mirror of
https://github.com/elisspace/autopsy.git
synced 2026-10-06 09:16:21 +00:00
Merge remote-tracking branch 'upstream/develop' into timeline_and_image_analyzer
This commit is contained in:
@@ -59,6 +59,7 @@ import org.sleuthkit.datamodel.SleuthkitJNI.CaseDbHandle.AddImageProcess;
|
||||
* open at a time. Use getCurrentCase() to retrieve the object for the current
|
||||
* case.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // TODO: Remove this when ErrorObserver is replaced.
|
||||
public class Case implements SleuthkitCase.ErrorObserver {
|
||||
|
||||
private static final String autopsyVer = Version.getVersion(); // current version of autopsy. Change it when the version is changed
|
||||
|
||||
@@ -44,13 +44,13 @@ import org.sleuthkit.datamodel.TskException;
|
||||
*/
|
||||
public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
|
||||
private BlackboardArtifact artifact;
|
||||
private Content associated;
|
||||
private final BlackboardArtifact artifact;
|
||||
private final Content associated;
|
||||
private List<NodeProperty<? extends Object>> customProperties;
|
||||
static final Logger logger = Logger.getLogger(BlackboardArtifactNode.class.getName());
|
||||
/**
|
||||
* Artifact types which should have the associated content's full unique path
|
||||
* as a property.
|
||||
/*
|
||||
* Artifact types which should have the full unique path of the associated
|
||||
* content as a property.
|
||||
*/
|
||||
private static final Integer[] SHOW_UNIQUE_PATH = new Integer[] {
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(),
|
||||
@@ -58,6 +58,13 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),
|
||||
};
|
||||
|
||||
// TODO (RC): This is an unattractive alternative to subclassing BlackboardArtifactNode,
|
||||
// cut from the same cloth as the equally unattractive SHOW_UNIQUE_PATH array
|
||||
// above. It should be removed when and if the subclassing is implemented.
|
||||
private static final Integer[] SHOW_FILE_METADATA = new Integer[] {
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct blackboard artifact node from an artifact and using provided
|
||||
* icon
|
||||
@@ -179,6 +186,30 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
NO_DESCR,
|
||||
sourcePath));
|
||||
}
|
||||
|
||||
if (Arrays.asList(SHOW_FILE_METADATA).contains(artifactTypeId)) {
|
||||
AbstractFile file = associated instanceof AbstractFile ? (AbstractFile)associated : null;
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileModifiedTime.name"),
|
||||
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileModifiedTime.displayName"),
|
||||
"",
|
||||
file != null ? ContentUtils.getStringTime(file.getMtime(), file) : ""));
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.name"),
|
||||
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.displayName"),
|
||||
"",
|
||||
file != null ? ContentUtils.getStringTime(file.getCtime(), file) : ""));
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.name"),
|
||||
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.displayName"),
|
||||
"",
|
||||
file != null ? ContentUtils.getStringTime(file.getAtime(), file) : ""));
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.name"),
|
||||
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.displayName"),
|
||||
"",
|
||||
file != null ? ContentUtils.getStringTime(file.getCrtime(), file) : ""));
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.name"),
|
||||
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.displayName"),
|
||||
"",
|
||||
associated.getSize()));
|
||||
}
|
||||
} else {
|
||||
String dataSourceStr = "";
|
||||
try {
|
||||
@@ -225,7 +256,7 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
* @param np NodeProperty to add
|
||||
*/
|
||||
public <T> void addNodeProperty(NodeProperty<T> np) {
|
||||
if (customProperties == null) {
|
||||
if (null == customProperties) {
|
||||
//lazy create the list
|
||||
customProperties = new ArrayList<>();
|
||||
}
|
||||
@@ -240,6 +271,7 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
* put
|
||||
* @param artifact to extract properties from
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // TODO: Remove this when TSK_TAGGED_ARTIFACT rows are removed in a database upgrade.
|
||||
private void fillPropertyMap(Map<String, Object> map, BlackboardArtifact artifact) {
|
||||
try {
|
||||
for (BlackboardAttribute attribute : artifact.getAttributes()) {
|
||||
@@ -247,8 +279,8 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
//skip some internal attributes that user shouldn't see
|
||||
if (attributeTypeID == ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID()
|
||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_TAGGED_ARTIFACT.getTypeID()
|
||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
|
||||
continue;
|
||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()
|
||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()) {
|
||||
} else {
|
||||
switch (attribute.getValueType()) {
|
||||
case STRING:
|
||||
@@ -337,7 +369,6 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
List<BlackboardAttribute> attributes = artifact.getAttributes();
|
||||
String keyword = null;
|
||||
String regexp = null;
|
||||
String origQuery = null;
|
||||
for (BlackboardAttribute att : attributes) {
|
||||
final int attributeTypeID = att.getAttributeTypeID();
|
||||
if (attributeTypeID == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) {
|
||||
@@ -348,6 +379,7 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
}
|
||||
if (keyword != null) {
|
||||
boolean isRegexp = (regexp != null && !regexp.equals(""));
|
||||
String origQuery;
|
||||
if (isRegexp) {
|
||||
origQuery = regexp;
|
||||
} else {
|
||||
@@ -410,9 +442,9 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
return "encrypted-file.png"; //NON-NLS
|
||||
case TSK_EXT_MISMATCH_DETECTED:
|
||||
return "mismatch-16.png"; //NON-NLS
|
||||
|
||||
default:
|
||||
return "artifact-icon.png"; //NON-NLS
|
||||
}
|
||||
return "artifact-icon.png"; //NON-NLS
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -108,7 +108,7 @@ public class InterestingHits implements AutopsyVisitableItem {
|
||||
String value = rs.getString("value_text"); //NON-NLS
|
||||
long artifactId = rs.getLong("artifact_id"); //NON-NLS
|
||||
if (!interestingItemsMap.containsKey(value)) {
|
||||
interestingItemsMap.put(value, new HashSet<Long>());
|
||||
interestingItemsMap.put(value, new HashSet<>());
|
||||
}
|
||||
interestingItemsMap.get(value).add(artifactId);
|
||||
}
|
||||
@@ -238,7 +238,7 @@ public class InterestingHits implements AutopsyVisitableItem {
|
||||
}
|
||||
|
||||
public class SetNameNode extends DisplayableItemNode implements Observer {
|
||||
private String setName;
|
||||
private final String setName;
|
||||
public SetNameNode(String setName) {//, Set<Long> children) {
|
||||
super(Children.create(new HitFactory(setName), true), Lookups.singleton(setName));
|
||||
this.setName = setName;
|
||||
@@ -286,7 +286,7 @@ public class InterestingHits implements AutopsyVisitableItem {
|
||||
}
|
||||
|
||||
private class HitFactory extends ChildFactory<Long> implements Observer {
|
||||
private String setName;
|
||||
private final String setName;
|
||||
|
||||
private HitFactory(String setName) {
|
||||
super();
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 686 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.ingest;
|
||||
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
|
||||
/**
|
||||
* An adapter that provides a no-op implementation of the startUp() method for
|
||||
* data source ingest modules.
|
||||
*/
|
||||
public abstract class DataSourceIngestModuleAdapter implements DataSourceIngestModule {
|
||||
|
||||
@Override
|
||||
public void startUp(IngestJobContext context) throws IngestModuleException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract ProcessResult process(Content dataSource, DataSourceIngestModuleProgress progressBar);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.ingest;
|
||||
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
/**
|
||||
* An adapter that provides no-op implementations of the startUp() and
|
||||
* shutDown() methods for file ingest modules.
|
||||
*/
|
||||
public abstract class FileIngestModuleAdapter implements FileIngestModule {
|
||||
|
||||
@Override
|
||||
public void startUp(IngestJobContext context) throws IngestModuleException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract ProcessResult process(AbstractFile file);
|
||||
|
||||
@Override
|
||||
public void shutDown() {
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ import org.sleuthkit.autopsy.modules.exif.ExifParserModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.fileextmismatch.FileExtMismatchDetectorModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeIdModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.interestingitems.InterestingItemsIngestModuleFactory;
|
||||
import org.sleuthkit.autopsy.modules.sevenzip.ArchiveFileExtractorModuleFactory;
|
||||
import org.sleuthkit.autopsy.python.JythonModuleLoader;
|
||||
|
||||
@@ -58,6 +59,7 @@ final class IngestModuleFactoryLoader {
|
||||
add(FileExtMismatchDetectorModuleFactory.class.getCanonicalName());
|
||||
add(E01VerifierModuleFactory.class.getCanonicalName());
|
||||
add(AndroidModuleFactory.class.getCanonicalName());
|
||||
add(InterestingItemsIngestModuleFactory.class.getCanonicalName());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
OpenIDE-Module-Display-Category=Ingest Module
|
||||
OpenIDE-Module-Long-Description=Interesting Files Identifier ingest module. \n\n Identifies interesting files as defined by interesting files rule sets.
|
||||
OpenIDE-Module-Short-Description=Interesting Files Identifier ingest module.
|
||||
OpenIDE-Module-Name=Interesting Files Identifier
|
||||
InterestingItemsIdentifierIngestModule.moduleName=Interesting Files Identifier
|
||||
InterestingItemsIdentifierIngestModule.moduleDescription=Identifies interesting items as defined by interesting item rule sets.
|
||||
InterestingFilesIdentifierJobSettingsPanel.filesSetTable.columnModel.title0=Title 1
|
||||
InterestingFilesIdentifierJobSettingsPanel.filesSetTable.columnModel.title3=Title 4
|
||||
InterestingFilesIdentifierJobSettingsPanel.filesSetTable.columnModel.title2=Title 3
|
||||
InterestingFilesIdentifierJobSettingsPanel.filesSetTable.columnModel.title1=Title 2
|
||||
InterestingItemDefsPanel.newSetButton.text=New Set...
|
||||
InterestingItemDefsPanel.editSetButton.text=Edit Set...
|
||||
InterestingItemDefsPanel.deleteSetButton.text=Delete Set
|
||||
InterestingItemDefsPanel.newRuleButton.text=New Rule...
|
||||
InterestingItemDefsPanel.editRuleButton.text=Edit Rule...
|
||||
InterestingItemDefsPanel.deleteRuleButton.text=Delete Rule
|
||||
InterestingItemDefsPanel.ruleNameTextField.text=
|
||||
InterestingItemDefsPanel.setsListLabel.text=Interesting Files Set Definitions:
|
||||
InterestingItemDefsPanel.selectedSetLabel.text=Selected Set:
|
||||
InterestingItemDefsPanel.rulesListLabel.text=Rules:
|
||||
InterestingItemDefsPanel.selectedRuleLabel.text=Selected Rule:
|
||||
InterestingItemDefsPanel.setDescPanel.border.title=Description
|
||||
FilesSetPanel.title=Interesting Files Set
|
||||
FilesSetPanel.messages.filesSetsMustBeNamed=Interesting files sets must be named.
|
||||
FilesSetPanel.ignoreKnownFilesCheckbox.text=Ignore Known Files
|
||||
FilesSetPanel.descriptionPanel.border.title=Description
|
||||
FilesSetPanel.nameLabel.text=Set Name:
|
||||
FilesSetPanel.descPanel.border.title=Description
|
||||
FilesSetRulePanel.title=Interesting Files Set Rule
|
||||
FilesSetRulePanel.extensionRadioButton.text=Extension Only
|
||||
FilesSetRulePanel.pathPanel.border.title=With parent path:
|
||||
FilesSetRulePanel.pathRegexCheckBox.text=Regex
|
||||
FilesSetRulePanel.pathTextField.text=
|
||||
FilesSetRulePanel.fullNameRadioButton.text=Full Name
|
||||
FilesSetRulePanel.nameRegexCheckbox.text=Regex
|
||||
FilesSetRulePanel.namePanel.AccessibleContext.accessibleName=Name
|
||||
FilesSetRulePanel.namePanel.border.title=Named:
|
||||
FilesSetRulePanel.ruleNameTextField.text=
|
||||
FilesSetRulePanel.nameTextField.text=
|
||||
FilesSetRulePanel.ruleNameLabel.text=Rule Name:
|
||||
FilesSetRulePanel.typePanel.border.title=Search for:
|
||||
FilesSetRulePanel.messages.filesSetRulesMustBeNamed=Interesting files set rules must be named.
|
||||
FilesSetRulePanel.messages.emptyNameFilter=Interesting files sets rules must have a name for which to search.
|
||||
FilesSetRulePanel.messages.invalidNameRegex=The name regular expression is not valid:\n\n{0}
|
||||
FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, \", <, or > unless it is a regular expression.
|
||||
FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, \", <, or > unless it is a regular expression.
|
||||
FilesSetRulePanel.messages.invalidPathRegex=The path regular expression is not valid:\n\n{0}
|
||||
FilesSetRulePanel.dirsRadioButton.text=Directories
|
||||
FilesSetRulePanel.filesRadioButton.text=Files
|
||||
InterestingItemDefsPanel.typePanel.border.title=Search for:
|
||||
InterestingItemDefsPanel.bothRadioButton.text=Files and Directories
|
||||
InterestingItemDefsPanel.dirsRadioButton.text=Directories
|
||||
InterestingItemDefsPanel.filesRadioButton.text=Files
|
||||
InterestingItemDefsPanel.fileNamePanel.border.title=Name
|
||||
InterestingItemDefsPanel.fileNameRegexCheckbox.text=Regex
|
||||
InterestingItemDefsPanel.fileNameExtensionRadioButton.text=Extension Only
|
||||
InterestingItemDefsPanel.fileNameTextField.text=
|
||||
InterestingItemDefsPanel.fileNameRadioButton.text=File Name
|
||||
FilesSetRulePanel.pathSeparatorInfoLabel.text=Use / as path separator
|
||||
FilesSetRulePanel.filesAndDirsRadioButton.text=Files and Directories
|
||||
InterestingItemDefsPanel.rulePathFilterTextField.text=
|
||||
InterestingItemDefsPanel.rulePathPanel.border.title=Path
|
||||
InterestingItemDefsPanel.rulePathFilterRegexCheckBox.text=Regex
|
||||
InterestingItemDefsPanel.ignoreKnownFilesCheckbox.text=Ignore Known Files
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.interestingitems;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||
|
||||
/**
|
||||
* Ingest job settings for interesting files identifier ingest modules.
|
||||
*/
|
||||
final class FilesIdentifierIngestJobSettings implements IngestModuleIngestJobSettings {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Set<String> enabledFilesSetNames = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Construct the ingest job settings for an interesting files identifier
|
||||
* ingest module.
|
||||
*
|
||||
* @param enabledFilesSetNames The names of the interesting files sets
|
||||
* that are enabled for the ingest job.
|
||||
*/
|
||||
FilesIdentifierIngestJobSettings(List<String> enabledFilesSetNames) {
|
||||
this.enabledFilesSetNames.addAll(enabledFilesSetNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public long getVersionNumber() {
|
||||
return FilesIdentifierIngestJobSettings.serialVersionUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not an interesting files set definition is enabled
|
||||
* for an ingest job.
|
||||
*
|
||||
* @param filesSetName The name of the files set definition to check.
|
||||
* @return True if the file set is enabled, false otherwise.
|
||||
*/
|
||||
boolean isInterestingFilesSetEnabled(String filesSetName) {
|
||||
return (this.enabledFilesSetNames.contains(filesSetName));
|
||||
}
|
||||
}
|
||||
Executable
+65
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="filesSetScrollPane" pref="254" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="filesSetScrollPane" pref="188" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="filesSetScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="filesSetTable">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="f0" green="f0" red="f0" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
|
||||
<Table columnCount="0" rowCount="0"/>
|
||||
</Property>
|
||||
<Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
|
||||
<TableColumnModel selectionModel="0"/>
|
||||
</Property>
|
||||
<Property name="showHorizontalLines" type="boolean" value="false"/>
|
||||
<Property name="showVerticalLines" type="boolean" value="false"/>
|
||||
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
|
||||
<TableHeader reorderingAllowed="true" resizingAllowed="true"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
Executable
+303
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.interestingitems;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.TreeMap;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.TableColumn;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
|
||||
|
||||
/**
|
||||
* Ingest job settings panel for interesting files identifier ingest modules.
|
||||
*/
|
||||
final class FilesIdentifierIngestJobSettingsPanel extends IngestModuleIngestJobSettingsPanel implements Observer {
|
||||
|
||||
private final FilesSetsTableModel tableModel;
|
||||
|
||||
// This map of interesting interesting files set names to files sets is used
|
||||
// both to sort interesting files sets by name and to detect when a new
|
||||
// files set is defined, so that the new set can be enabled by default.
|
||||
private TreeMap<String, FilesSet> filesSetSnapshot;
|
||||
|
||||
/**
|
||||
* A factory method that avoids publishing the "this" reference from the
|
||||
* constructor.
|
||||
*
|
||||
* @return An instance of the ingest job settings panel interesting files
|
||||
* identifier ingest modules.
|
||||
*/
|
||||
static FilesIdentifierIngestJobSettingsPanel makePanel(FilesIdentifierIngestJobSettings settings) {
|
||||
FilesIdentifierIngestJobSettingsPanel panel = new FilesIdentifierIngestJobSettingsPanel(settings);
|
||||
|
||||
// Observe the interesting item definitions manager for changes to the
|
||||
// interesting file set definitions. This is used to keep this panel in
|
||||
// synch with changes made using the global settings/option panel for
|
||||
// this module.
|
||||
InterestingItemDefsManager.getInstance().addObserver(panel);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an ingest job settings panel for interesting files identifier
|
||||
* ingest modules.
|
||||
*/
|
||||
private FilesIdentifierIngestJobSettingsPanel(FilesIdentifierIngestJobSettings settings) {
|
||||
initComponents();
|
||||
|
||||
/* Make a table row object for each interesting files set, bundling the
|
||||
* set with an enabled flag. The files sets are loaded into a tree map
|
||||
* so they are sorted by name. The keys set also serves as a cache of
|
||||
* set names so that new sets can be easily detected in the override of
|
||||
* Observer.update().
|
||||
*/
|
||||
List<FilesSetRow> filesSetRows = new ArrayList<>();
|
||||
this.filesSetSnapshot = new TreeMap<>(InterestingItemDefsManager.getInstance().getInterestingFilesSets());
|
||||
for (FilesSet set : this.filesSetSnapshot.values()) {
|
||||
filesSetRows.add(new FilesSetRow(set, settings.isInterestingFilesSetEnabled(set.getName())));
|
||||
}
|
||||
|
||||
// Make a table model to manage the row objects.
|
||||
this.tableModel = new FilesSetsTableModel(filesSetRows);
|
||||
|
||||
// Set up the table component that presents the table model that allows
|
||||
// users to enable and disable interesting files set definitions for an
|
||||
// ingest job.
|
||||
this.filesSetTable.setModel(tableModel);
|
||||
this.filesSetTable.setTableHeader(null);
|
||||
this.filesSetTable.setRowSelectionAllowed(false);
|
||||
final int width = this.filesSetScrollPane.getPreferredSize().width;
|
||||
this.filesSetTable.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
|
||||
TableColumn column;
|
||||
for (int i = 0; i < this.filesSetTable.getColumnCount(); i++) {
|
||||
column = this.filesSetTable.getColumnModel().getColumn(i);
|
||||
if (i == 0) {
|
||||
column.setPreferredWidth(((int) (width * 0.07)));
|
||||
} else {
|
||||
column.setPreferredWidth(((int) (width * 0.92)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public IngestModuleIngestJobSettings getSettings() {
|
||||
List<String> enabledInterestingFilesSets = new ArrayList<>();
|
||||
this.tableModel.filesSetRows.stream().filter((rowModel) -> (rowModel.isEnabled())).forEach((rowModel) -> {
|
||||
enabledInterestingFilesSets.add(rowModel.getFilesSet().getName());
|
||||
});
|
||||
return new FilesIdentifierIngestJobSettings(enabledInterestingFilesSets);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public void update(Observable o, Object arg
|
||||
) {
|
||||
// Get the user's current enabled/disabled settings.
|
||||
FilesIdentifierIngestJobSettings settings = (FilesIdentifierIngestJobSettings) this.getSettings();
|
||||
|
||||
// Refresh the view of the interesting files set definitions.
|
||||
List<FilesSetRow> rowModels = new ArrayList<>();
|
||||
TreeMap<String, FilesSet> newFilesSetSnapshot = new TreeMap<>(InterestingItemDefsManager.getInstance().getInterestingFilesSets());
|
||||
for (FilesSet set : newFilesSetSnapshot.values()) {
|
||||
if (this.filesSetSnapshot.keySet().contains(set.getName())) {
|
||||
// Preserve the current enabled/diabled state of the set.
|
||||
rowModels.add(new FilesSetRow(set, settings.isInterestingFilesSetEnabled(set.getName())));
|
||||
} else {
|
||||
// New sets are enabled by default.
|
||||
rowModels.add(new FilesSetRow(set, true));
|
||||
}
|
||||
}
|
||||
this.tableModel.resetTableData(rowModels);
|
||||
|
||||
// Cache the snapshot so it will be avaialble for the next update.
|
||||
this.filesSetSnapshot = newFilesSetSnapshot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Table model for a JTable component that allows users to enable and
|
||||
* disable interesting files set definitions for an ingest job.
|
||||
*/
|
||||
private final static class FilesSetsTableModel extends AbstractTableModel {
|
||||
|
||||
private List<FilesSetRow> filesSetRows;
|
||||
|
||||
/**
|
||||
* Constructs a table model for a JTable component that allows users to
|
||||
* enable and disable interesting files set definitions for an ingest
|
||||
* job.
|
||||
*
|
||||
* @param filesSetRows A collection of row objects that bundles an
|
||||
* interesting files set with an enabled flag
|
||||
*/
|
||||
FilesSetsTableModel(List<FilesSetRow> filesSetRows) {
|
||||
this.filesSetRows = filesSetRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the table with a new set of rows.
|
||||
*
|
||||
* @param filesSetRows A collection of row objects that bundles an
|
||||
* interesting files set with an enabled flag
|
||||
*/
|
||||
void resetTableData(List<FilesSetRow> filesSetRows) {
|
||||
this.filesSetRows = filesSetRows;
|
||||
this.fireTableDataChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return this.filesSetRows.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
if (columnIndex == 0) {
|
||||
return this.filesSetRows.get(rowIndex).isEnabled();
|
||||
} else {
|
||||
return this.filesSetRows.get(rowIndex).getFilesSet().getName();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return (columnIndex == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
if (columnIndex == 0) {
|
||||
this.filesSetRows.get(rowIndex).setEnabled((Boolean) aValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getColumnClass(int c) {
|
||||
return getValueAt(0, c).getClass();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bundles an interesting files set with an enabled flag.
|
||||
*/
|
||||
private final static class FilesSetRow {
|
||||
|
||||
private final FilesSet set;
|
||||
private boolean enabled;
|
||||
|
||||
FilesSetRow(FilesSet set, boolean enabled) {
|
||||
this.set = set;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
FilesSet getFilesSet() {
|
||||
return this.set;
|
||||
}
|
||||
|
||||
boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
filesSetScrollPane = new javax.swing.JScrollPane();
|
||||
filesSetTable = new javax.swing.JTable();
|
||||
|
||||
filesSetTable.setBackground(new java.awt.Color(240, 240, 240));
|
||||
filesSetTable.setModel(new javax.swing.table.DefaultTableModel(
|
||||
new Object [][] {
|
||||
|
||||
},
|
||||
new String [] {
|
||||
|
||||
}
|
||||
));
|
||||
filesSetTable.setShowHorizontalLines(false);
|
||||
filesSetTable.setShowVerticalLines(false);
|
||||
filesSetScrollPane.setViewportView(filesSetTable);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(filesSetScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 254, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(filesSetScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 188, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JScrollPane filesSetScrollPane;
|
||||
private javax.swing.JTable filesSetTable;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.interestingitems;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.FileIngestModule;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* A file ingest module that generates interesting files set hit artifacts for
|
||||
* files that match interesting files set definitions.
|
||||
*/
|
||||
final class FilesIdentifierIngestModule implements FileIngestModule {
|
||||
|
||||
private static final Object sharedResourcesLock = new Object();
|
||||
private static final Logger logger = Logger.getLogger(FilesIdentifierIngestModule.class.getName());
|
||||
private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
|
||||
private static final Map<Long, List<FilesSet>> interestingFileSetsByJob = new ConcurrentHashMap<>();
|
||||
private final FilesIdentifierIngestJobSettings settings;
|
||||
private IngestJobContext context;
|
||||
|
||||
/**
|
||||
* Construct an interesting files identifier ingest module for an ingest
|
||||
* job.
|
||||
*
|
||||
* @param settings An ingest job settings object for the module.
|
||||
*/
|
||||
FilesIdentifierIngestModule(FilesIdentifierIngestJobSettings settings) {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public void startUp(IngestJobContext context) throws IngestModuleException {
|
||||
this.context = context;
|
||||
synchronized (FilesIdentifierIngestModule.sharedResourcesLock) {
|
||||
if (FilesIdentifierIngestModule.refCounter.incrementAndGet(context.getJobId()) == 1) {
|
||||
// Starting up the first instance of this module for this ingest
|
||||
// job, so get the interesting file sets definitions snapshot
|
||||
// for the job. Note that getting this snapshot atomically via a
|
||||
// synchronized definitions manager method eliminates the need
|
||||
// to disable the interesting files set definition UI during ingest.
|
||||
List<FilesSet> filesSets = new ArrayList<>();
|
||||
for (FilesSet set : InterestingItemDefsManager.getInstance().getInterestingFilesSets().values()) {
|
||||
if (settings.isInterestingFilesSetEnabled(set.getName())) {
|
||||
filesSets.add(set);
|
||||
}
|
||||
}
|
||||
FilesIdentifierIngestModule.interestingFileSetsByJob.put(context.getJobId(), filesSets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public ProcessResult process(AbstractFile file) {
|
||||
// See if the file belongs to any defined interesting files set.
|
||||
List<FilesSet> filesSets = FilesIdentifierIngestModule.interestingFileSetsByJob.get(this.context.getJobId());
|
||||
for (FilesSet filesSet : filesSets) {
|
||||
String ruleSatisfied = filesSet.fileIsMemberOf(file);
|
||||
if (ruleSatisfied != null) {
|
||||
try {
|
||||
// Post an interesting files set hit artifact to the
|
||||
// blackboard.
|
||||
String moduleName = InterestingItemsIngestModuleFactory.getModuleName();
|
||||
BlackboardArtifact artifact = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT);
|
||||
|
||||
// Add a set name attribute to the artifact. This adds a
|
||||
// fair amount of redundant data to the attributes table
|
||||
// (i.e., rows that differ only in artifact id), but doing
|
||||
// otherwise would requires reworking the interesting files
|
||||
// set hit artifact.
|
||||
BlackboardAttribute setNameAttribute = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID(), moduleName, filesSet.getName());
|
||||
artifact.addAttribute(setNameAttribute);
|
||||
|
||||
// Add a category attribute to the artifact to record the
|
||||
// interesting files set membership rule that was satisfied.
|
||||
BlackboardAttribute ruleNameAttribute = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY.getTypeID(), moduleName, ruleSatisfied);
|
||||
artifact.addAttribute(ruleNameAttribute);
|
||||
|
||||
} catch (TskCoreException ex) {
|
||||
FilesIdentifierIngestModule.logger.log(Level.SEVERE, "Error posting to the blackboard", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public void shutDown() {
|
||||
if (refCounter.decrementAndGet(this.context.getJobId()) == 0) {
|
||||
// Shutting down the last instance of this module for this ingest
|
||||
// job, so discard the interesting file sets definitions snapshot
|
||||
// for the job.
|
||||
FilesIdentifierIngestModule.interestingFileSetsByJob.remove(this.context.getJobId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,635 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.interestingitems;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
/**
|
||||
* A collection of set membership rules that define an interesting files set.
|
||||
* The rules are independent, i.e., if any rule is satisfied by a file, the file
|
||||
* belongs to the set.
|
||||
*
|
||||
* Interesting files set definition objects are immutable, so they may be safely
|
||||
* published to multiple threads.
|
||||
*/
|
||||
final class FilesSet {
|
||||
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final boolean ignoreKnownFiles;
|
||||
private final Map<String, Rule> rules = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Constructs an interesting files set.
|
||||
*
|
||||
* @param name The name of the set.
|
||||
* @param description A description of the set, may be null.
|
||||
* @param ignoreKnownFiles Whether or not to exclude known files from the
|
||||
* set.
|
||||
* @param rules The rules that define the set. May be null, but a set with
|
||||
* no rules is the empty set.
|
||||
*/
|
||||
FilesSet(String name, String description, boolean ignoreKnownFiles, Map<String, Rule> rules) {
|
||||
if ((name == null) || (name.isEmpty())) {
|
||||
throw new IllegalArgumentException("Interesting files set name cannot be null or empty");
|
||||
}
|
||||
this.name = name;
|
||||
this.description = (description != null ? description : "");
|
||||
this.ignoreKnownFiles = ignoreKnownFiles;
|
||||
if (rules != null) {
|
||||
this.rules.putAll(rules);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this interesting files set.
|
||||
*
|
||||
* @return A name string.
|
||||
*/
|
||||
String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the description of this interesting files set.
|
||||
*
|
||||
* @return A description string, possibly the empty string.
|
||||
*/
|
||||
String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not this interesting files set ignores known files,
|
||||
* i.e., files marked as known by a look up in a known files hash set such
|
||||
* as the National Software Reference Library (NSRL). Note that the
|
||||
* interesting files set does not do hash set look ups; it simply queries
|
||||
* the known status of the files when testing them for set membership.
|
||||
*
|
||||
* @return True if known files are ignored, false otherwise.
|
||||
*/
|
||||
boolean ignoresKnownFiles() {
|
||||
return this.ignoreKnownFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a copy of the set membership rules of this interesting files set.
|
||||
*
|
||||
* @return A map of set membership rule names to rules, possibly empty.
|
||||
*/
|
||||
Map<String, Rule> getRules() {
|
||||
return new HashMap<>(this.rules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a file is a member of this interesting files set.
|
||||
*
|
||||
* @param file A file to test for set membership.
|
||||
* @return The name of the first set membership rule satisfied by the file,
|
||||
* will be null if the file does not belong to the set.
|
||||
*/
|
||||
String fileIsMemberOf(AbstractFile file) {
|
||||
if ((this.ignoreKnownFiles) && (file.getKnown() == TskData.FileKnown.KNOWN)) {
|
||||
return null;
|
||||
}
|
||||
for (Rule rule : rules.values()) {
|
||||
if (rule.isSatisfied(file)) {
|
||||
return rule.getName();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// This override is designed to provide a display name for use with
|
||||
// javax.swing.DefaultListModel<E>.
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* A set membership rule for an interesting files set. The immutability of a
|
||||
* rule object allows it to be safely published to multiple threads.
|
||||
*/
|
||||
static class Rule {
|
||||
|
||||
private final String ruleName;
|
||||
private final FileNameFilter fileNameFilter;
|
||||
private final MetaTypeFilter metaTypeFilter;
|
||||
private final ParentPathFilter pathFilter;
|
||||
private final List<FileAttributeFilter> filters = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Construct an interesting files set membership rule.
|
||||
*
|
||||
* @param ruleName The name of the rule.
|
||||
* @param fileNameFilter A file name filter.
|
||||
* @param metaTypeFilter A file meta-type filter.
|
||||
* @param pathFilter A file path filter, may be null.
|
||||
*/
|
||||
Rule(String ruleName, FileNameFilter fileNameFilter, MetaTypeFilter metaTypeFilter, ParentPathFilter pathFilter) {
|
||||
if ((ruleName == null) || (ruleName.isEmpty())) {
|
||||
throw new IllegalArgumentException("Interesting files set rule name cannot be null or empty");
|
||||
}
|
||||
if (fileNameFilter == null) {
|
||||
throw new IllegalArgumentException("Interesting files set rule file name filter cannot be null");
|
||||
}
|
||||
if (metaTypeFilter == null) {
|
||||
throw new IllegalArgumentException("Interesting files set rule meta-type filter cannot be null");
|
||||
}
|
||||
this.ruleName = ruleName;
|
||||
this.fileNameFilter = fileNameFilter;
|
||||
this.filters.add(fileNameFilter);
|
||||
this.metaTypeFilter = metaTypeFilter;
|
||||
this.filters.add(this.metaTypeFilter);
|
||||
this.pathFilter = pathFilter;
|
||||
if (this.pathFilter != null) {
|
||||
this.filters.add(this.pathFilter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the rule.
|
||||
*
|
||||
* @return A name string.
|
||||
*/
|
||||
String getName() {
|
||||
return ruleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file name filter for the rule.
|
||||
*
|
||||
* @return A file name filter.
|
||||
*/
|
||||
FileNameFilter getFileNameFilter() {
|
||||
return this.fileNameFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the meta-type filter for the rule.
|
||||
*
|
||||
* @return A meta-type filter.
|
||||
*/
|
||||
MetaTypeFilter getMetaTypeFilter() {
|
||||
return this.metaTypeFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path filter for the rule.
|
||||
*
|
||||
* @return A path filter, may be null.
|
||||
*/
|
||||
ParentPathFilter getPathFilter() {
|
||||
return this.pathFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not a file satisfies the rule.
|
||||
*
|
||||
* @param file The file to test.
|
||||
* @return True if the rule is satisfied, false otherwise.
|
||||
*/
|
||||
boolean isSatisfied(AbstractFile file) {
|
||||
for (FileAttributeFilter filter : filters) {
|
||||
if (!filter.passes(file)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
// This override is designed to provide a display name for use with
|
||||
// javax.swing.DefaultListModel<E>.
|
||||
return this.ruleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for the file attribute filters of which interesting
|
||||
* files set membership rules are composed.
|
||||
*/
|
||||
static interface FileAttributeFilter {
|
||||
|
||||
/**
|
||||
* Tests whether or not a file satisfies the conditions of a filter.
|
||||
*
|
||||
* @param file The file to test.
|
||||
* @return True if the file passes the test, false otherwise.
|
||||
*/
|
||||
boolean passes(AbstractFile file);
|
||||
}
|
||||
|
||||
/**
|
||||
* A file meta-type filter for an interesting files set membership rule.
|
||||
* The immutability of a meta-type filter object allows it to be safely
|
||||
* published to multiple threads.
|
||||
*/
|
||||
static final class MetaTypeFilter implements FileAttributeFilter {
|
||||
|
||||
enum Type {
|
||||
|
||||
FILES,
|
||||
DIRECTORIES,
|
||||
FILES_AND_DIRECTORIES
|
||||
}
|
||||
|
||||
private final Type type;
|
||||
|
||||
/**
|
||||
* Construct a meta-type filter.
|
||||
*
|
||||
* @param metaType The meta-type to match, must.
|
||||
*/
|
||||
MetaTypeFilter(Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public boolean passes(AbstractFile file) {
|
||||
switch (this.type) {
|
||||
case FILES:
|
||||
return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG;
|
||||
case DIRECTORIES:
|
||||
return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR;
|
||||
default:
|
||||
return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG
|
||||
|| file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the meta-type the filter matches.
|
||||
*
|
||||
* @return A member of the MetaTypeFilter.Type enumeration.
|
||||
*/
|
||||
Type getMetaType() {
|
||||
return this.type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for file attribute filters that do textual matching.
|
||||
*/
|
||||
static interface TextFilter extends FileAttributeFilter {
|
||||
|
||||
/**
|
||||
* Gets the text the filter matches.
|
||||
*
|
||||
* @return The text.
|
||||
*/
|
||||
String getTextToMatch();
|
||||
|
||||
/**
|
||||
* Queries whether or not the text the filter matches is a regular
|
||||
* expression.
|
||||
*
|
||||
* @return True if the text to be matched is a regular expression,
|
||||
* false otherwise.
|
||||
*/
|
||||
boolean isRegex();
|
||||
|
||||
/**
|
||||
* Determines whether a string of text matches the filter.
|
||||
*
|
||||
* @param textToMatch The text string.
|
||||
* @return True if the text matches, false otherwise.
|
||||
*/
|
||||
boolean textMatches(String textToMatch);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* An abstract base class for file attribute filters that do textual
|
||||
* matching.
|
||||
*/
|
||||
private static abstract class AbstractTextFilter implements TextFilter {
|
||||
|
||||
private final TextMatcher textMatcher;
|
||||
|
||||
/**
|
||||
* Construct a case-insensitive text filter.
|
||||
*
|
||||
* @param text The text to be matched.
|
||||
*/
|
||||
AbstractTextFilter(String text) {
|
||||
this.textMatcher = new FilesSet.Rule.CaseInsensitiveStringComparisionMatcher(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a regular expression text filter.
|
||||
*
|
||||
* @param regex The regular expression to be matched.
|
||||
*/
|
||||
AbstractTextFilter(Pattern regex) {
|
||||
this.textMatcher = new FilesSet.Rule.RegexMatcher(regex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text the filter matches.
|
||||
*
|
||||
* @return The text.
|
||||
*/
|
||||
@Override
|
||||
public String getTextToMatch() {
|
||||
return this.textMatcher.getTextToMatch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries whether or not the text the filter matches is a regular
|
||||
* expression.
|
||||
*
|
||||
* @return True if the text to be matched is a regular expression,
|
||||
* false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean isRegex() {
|
||||
return this.textMatcher.isRegex();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a string of text matches the filter.
|
||||
*
|
||||
* @param textToMatch The text string.
|
||||
* @return True if the text matches, false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean textMatches(String textToMatch) {
|
||||
return this.textMatcher.textMatches(textToMatch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public abstract boolean passes(AbstractFile file);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A file path filter for an interesting files set membership rule. The
|
||||
* immutability of a path filter object allows it to be safely published
|
||||
* to multiple threads.
|
||||
*/
|
||||
static final class ParentPathFilter extends AbstractTextFilter {
|
||||
|
||||
/**
|
||||
* Construct a case-insensitive file path filter.
|
||||
*
|
||||
* @param path The path to be matched.
|
||||
*/
|
||||
ParentPathFilter(String path) {
|
||||
super(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a file path regular expression filter.
|
||||
*
|
||||
* @param path The path regular expression to be matched.
|
||||
*/
|
||||
ParentPathFilter(Pattern path) {
|
||||
super(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public boolean passes(AbstractFile file) {
|
||||
return this.textMatches(file.getParentPath());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A "tagging" interface to group name and extension filters separately
|
||||
* from path filters for type safety when constructing rules.
|
||||
*/
|
||||
static interface FileNameFilter extends TextFilter {
|
||||
}
|
||||
|
||||
/**
|
||||
* A file name filter for an interesting files set membership rule. The
|
||||
* immutability of a file name filter object allows it to be safely
|
||||
* published to multiple threads.
|
||||
*/
|
||||
static final class FullNameFilter extends AbstractTextFilter implements FileNameFilter {
|
||||
|
||||
/**
|
||||
* Construct a case-insensitive full file name filter.
|
||||
*
|
||||
* @param name The file name to be matched.
|
||||
*/
|
||||
FullNameFilter(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a full file name regular expression filter.
|
||||
*
|
||||
* @param name The file name regular expression to be matched.
|
||||
*/
|
||||
FullNameFilter(Pattern name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public boolean passes(AbstractFile file) {
|
||||
return this.textMatches(file.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A file name extension filter for an interesting files set membership
|
||||
* rule. The immutability of a file name extension filter object allows
|
||||
* it to be safely published to multiple threads.
|
||||
*/
|
||||
static final class ExtensionFilter extends AbstractTextFilter implements FileNameFilter {
|
||||
|
||||
/**
|
||||
* Construct a case-insensitive file name extension filter.
|
||||
*
|
||||
* @param extension The file name extension to be matched.
|
||||
*/
|
||||
ExtensionFilter(String extension) {
|
||||
// If there is a leading ".", strip it since
|
||||
// AbstractFile.getFileNameExtension() returns just the
|
||||
// extension chars and not the dot.
|
||||
super(extension.startsWith(".") ? extension.substring(1) : extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a file name extension regular expression filter.
|
||||
*
|
||||
* @param extension The file name extension regular expression to be
|
||||
* matched.
|
||||
*/
|
||||
ExtensionFilter(Pattern extension) {
|
||||
super(extension.pattern());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public boolean passes(AbstractFile file) {
|
||||
return this.textMatches(file.getNameExtension());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for objects that do textual matches, used to compose a
|
||||
* text filter.
|
||||
*/
|
||||
private static interface TextMatcher {
|
||||
|
||||
/**
|
||||
* Get the text the matcher examines.
|
||||
*
|
||||
* @return The text.
|
||||
*/
|
||||
String getTextToMatch();
|
||||
|
||||
/**
|
||||
* Queries whether or not the text the matcher examines is a regular
|
||||
* expression.
|
||||
*
|
||||
* @return True if the text to be matched is a regular expression,
|
||||
* false otherwise.
|
||||
*/
|
||||
boolean isRegex();
|
||||
|
||||
/**
|
||||
* Determines whether a string of text is matched.
|
||||
*
|
||||
* @param textToMatch The text string.
|
||||
* @return True if the text matches, false otherwise.
|
||||
*/
|
||||
boolean textMatches(String subject);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A text matcher that does a case-insensitive string comparison.
|
||||
*/
|
||||
private static class CaseInsensitiveStringComparisionMatcher implements TextMatcher {
|
||||
|
||||
private final String textToMatch;
|
||||
|
||||
/**
|
||||
* Construct a text matcher that does a case-insensitive string
|
||||
* comparison.
|
||||
*
|
||||
* @param textToMatch The text to match.
|
||||
*/
|
||||
CaseInsensitiveStringComparisionMatcher(String textToMatch) {
|
||||
this.textToMatch = textToMatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public String getTextToMatch() {
|
||||
return this.textToMatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public boolean isRegex() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public boolean textMatches(String subject) {
|
||||
return subject.equalsIgnoreCase(textToMatch);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A text matcher that does regular expression matching.
|
||||
*/
|
||||
private static class RegexMatcher implements TextMatcher {
|
||||
|
||||
private final Pattern regex;
|
||||
|
||||
/**
|
||||
* Construct a text matcher that does a regular expression
|
||||
* comparison.
|
||||
*
|
||||
* @param regex The regular expression to match.
|
||||
*/
|
||||
RegexMatcher(Pattern regex) {
|
||||
this.regex = regex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public String getTextToMatch() {
|
||||
return this.regex.pattern();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public boolean isRegex() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public boolean textMatches(String subject) {
|
||||
// A single match is sufficient.
|
||||
return this.regex.matcher(subject).find();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="nameLabel" min="-2" pref="71" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="nameTextField" min="-2" pref="299" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="descPanel" max="32767" attributes="0"/>
|
||||
<Component id="ignoreKnownFilesCheckbox" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="nameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="nameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="descPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="ignoreKnownFilesCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="nameLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetPanel.nameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="nameTextField">
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="descPanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Description">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetPanel.descPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="descScrollPanel" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="descScrollPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="descScrollPanel">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextArea" name="descTextArea">
|
||||
<Properties>
|
||||
<Property name="columns" type="int" value="20"/>
|
||||
<Property name="rows" type="int" value="5"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JCheckBox" name="ignoreKnownFilesCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetPanel.ignoreKnownFilesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.interestingitems;
|
||||
|
||||
import org.openide.DialogDisplayer;
|
||||
import org.openide.NotifyDescriptor;
|
||||
import org.openide.util.NbBundle;
|
||||
|
||||
/**
|
||||
* A panel that allows a user to create and edit interesting files set
|
||||
* definitions.
|
||||
*/
|
||||
public class FilesSetPanel extends javax.swing.JPanel {
|
||||
|
||||
/**
|
||||
* Construct a files set panel in create mode.
|
||||
*/
|
||||
FilesSetPanel() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a files set panel in edit mode.
|
||||
*
|
||||
* @param filesSet The files set to be edited.
|
||||
*/
|
||||
FilesSetPanel(FilesSet filesSet) {
|
||||
initComponents();
|
||||
this.nameTextField.setText(filesSet.getName());
|
||||
this.descTextArea.setText(filesSet.getDescription());
|
||||
this.ignoreKnownFilesCheckbox.setSelected(filesSet.ignoresKnownFiles());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the data entered in the panel constitutes a valid
|
||||
* interesting files set definition, displaying a dialog explaining the
|
||||
* deficiency if the definition is invalid
|
||||
*
|
||||
* @return True if the definition is valid, false otherwise.
|
||||
*/
|
||||
boolean isValidDefinition() {
|
||||
if (this.nameTextField.getText().isEmpty()) {
|
||||
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
|
||||
NbBundle.getMessage(FilesSetPanel.class, "FilesSetPanel.messages.filesSetsMustBeNamed"),
|
||||
NotifyDescriptor.WARNING_MESSAGE);
|
||||
DialogDisplayer.getDefault().notify(notifyDesc);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name for the interesting files set defined using this panel.
|
||||
*
|
||||
* @return A name string.
|
||||
*/
|
||||
String getFilesSetName() {
|
||||
return this.nameTextField.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the description for the interesting files set defined using this
|
||||
* panel.
|
||||
*
|
||||
* @return A description string.
|
||||
*/
|
||||
String getFilesSetDescription() {
|
||||
return this.descTextArea.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether or not the interesting files set defined using this panel
|
||||
* ignores known files.
|
||||
*
|
||||
* @return True if the set ignores known files, false otherwise.
|
||||
*/
|
||||
boolean getFileSetIgnoresKnownFiles() {
|
||||
return this.ignoreKnownFilesCheckbox.isSelected();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
nameLabel = new javax.swing.JLabel();
|
||||
nameTextField = new javax.swing.JTextField();
|
||||
descPanel = new javax.swing.JPanel();
|
||||
descScrollPanel = new javax.swing.JScrollPane();
|
||||
descTextArea = new javax.swing.JTextArea();
|
||||
ignoreKnownFilesCheckbox = new javax.swing.JCheckBox();
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(nameLabel, org.openide.util.NbBundle.getMessage(FilesSetPanel.class, "FilesSetPanel.nameLabel.text")); // NOI18N
|
||||
|
||||
descPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(FilesSetPanel.class, "FilesSetPanel.descPanel.border.title"))); // NOI18N
|
||||
|
||||
descTextArea.setColumns(20);
|
||||
descTextArea.setRows(5);
|
||||
descScrollPanel.setViewportView(descTextArea);
|
||||
|
||||
javax.swing.GroupLayout descPanelLayout = new javax.swing.GroupLayout(descPanel);
|
||||
descPanel.setLayout(descPanelLayout);
|
||||
descPanelLayout.setHorizontalGroup(
|
||||
descPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(descPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(descScrollPanel)
|
||||
.addContainerGap())
|
||||
);
|
||||
descPanelLayout.setVerticalGroup(
|
||||
descPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, descPanelLayout.createSequentialGroup()
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(descScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(ignoreKnownFilesCheckbox, org.openide.util.NbBundle.getMessage(FilesSetPanel.class, "FilesSetPanel.ignoreKnownFilesCheckbox.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addComponent(nameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 299, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(descPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(ignoreKnownFilesCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(nameLabel)
|
||||
.addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(descPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(ignoreKnownFilesCheckbox)
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JPanel descPanel;
|
||||
private javax.swing.JScrollPane descScrollPanel;
|
||||
private javax.swing.JTextArea descTextArea;
|
||||
private javax.swing.JCheckBox ignoreKnownFilesCheckbox;
|
||||
private javax.swing.JLabel nameLabel;
|
||||
private javax.swing.JTextField nameTextField;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
+316
@@ -0,0 +1,316 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.ButtonGroup" name="nameButtonGroup">
|
||||
</Component>
|
||||
<Component class="javax.swing.ButtonGroup" name="typeButtonGroup">
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="typePanel" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="namePanel" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="ruleNameLabel" min="-2" pref="59" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="ruleNameTextField" min="-2" pref="256" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="pathPanel" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="ruleNameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="ruleNameLabel" alignment="3" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="typePanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="namePanel" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pathPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="ruleNameLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.ruleNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="ruleNameTextField">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.ruleNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="namePanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Named:">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.namePanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AccessibilityProperties>
|
||||
<Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.namePanel.AccessibleContext.accessibleName" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</AccessibilityProperties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="fullNameRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<Component id="extensionRadioButton" min="-2" pref="114" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="nameRegexCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="nameTextField" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="nameTextField" min="-2" pref="20" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="fullNameRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="extensionRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="nameRegexCheckbox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="nameRegexCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.nameRegexCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="extensionRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="nameButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.extensionRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="nameTextField">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.nameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="fullNameRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="nameButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.fullNameRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="typePanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Search for:">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.typePanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="filesRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="dirsRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="filesAndDirsRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="filesRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="dirsRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="filesAndDirsRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JRadioButton" name="filesRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="typeButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.filesRadioButton.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="filesRadioButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="dirsRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="typeButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.dirsRadioButton.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="dirsRadioButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="filesAndDirsRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="typeButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.filesAndDirsRadioButton.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="filesAndDirsRadioButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="pathPanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="With parent path:">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.pathPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="pathRegexCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="pathSeparatorInfoLabel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="pathTextField" min="-2" pref="283" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pathTextField" min="-2" pref="20" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="pathRegexCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="pathSeparatorInfoLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="pathRegexCheckBox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.pathRegexCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="pathTextField">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.pathTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="pathSeparatorInfoLabel">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/info-icon-16.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.pathSeparatorInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
+558
@@ -0,0 +1,558 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.interestingitems;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import org.openide.DialogDisplayer;
|
||||
import org.openide.NotifyDescriptor;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* A panel that allows a user to create and edit interesting files set
|
||||
* membership rules.
|
||||
*/
|
||||
final class FilesSetRulePanel extends javax.swing.JPanel {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(FilesSetRulePanel.class.getName());
|
||||
private static final String SLEUTHKIT_PATH_SEPARATOR = "/"; // NON-NLS
|
||||
private static final List<String> ILLEGAL_FILE_NAME_CHARS = InterestingItemDefsManager.getIllegalFileNameChars();
|
||||
private static final List<String> ILLEGAL_FILE_PATH_CHARS = InterestingItemDefsManager.getIllegalFilePathChars();
|
||||
|
||||
/**
|
||||
* Constructs a files set rule panel in create rule mode.
|
||||
*/
|
||||
FilesSetRulePanel() {
|
||||
initComponents();
|
||||
populateComponentsWithDefaultValues();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a files set rule panel in edit rule mode.
|
||||
*
|
||||
* @param rule The files set rule to be edited.
|
||||
*/
|
||||
FilesSetRulePanel(FilesSet.Rule rule) {
|
||||
initComponents();
|
||||
populateRuleNameComponent(rule);
|
||||
populateTypeFilterComponents(rule);
|
||||
populateNameFilterComponents(rule);
|
||||
populatePathFilterComponents(rule);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the UI components with default values.
|
||||
*/
|
||||
private void populateComponentsWithDefaultValues() {
|
||||
this.filesRadioButton.setSelected(true);
|
||||
this.fullNameRadioButton.setSelected(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the UI component that displays the rule name.
|
||||
*
|
||||
* @param rule The files set rule to be edited.
|
||||
*/
|
||||
private void populateRuleNameComponent(FilesSet.Rule rule) {
|
||||
this.ruleNameTextField.setText(rule.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the UI components that display the meta-type filter for a rule.
|
||||
*
|
||||
* @param rule The files set rule to be edited.
|
||||
*/
|
||||
private void populateTypeFilterComponents(FilesSet.Rule rule) {
|
||||
FilesSet.Rule.MetaTypeFilter typeFilter = rule.getMetaTypeFilter();
|
||||
switch (typeFilter.getMetaType()) {
|
||||
case FILES:
|
||||
this.filesRadioButton.setSelected(true);
|
||||
break;
|
||||
case DIRECTORIES:
|
||||
this.dirsRadioButton.setSelected(true);
|
||||
break;
|
||||
case FILES_AND_DIRECTORIES:
|
||||
this.filesAndDirsRadioButton.setSelected(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the UI components that display the name filter for a rule.
|
||||
*
|
||||
* @param rule The files set rule to be edited.
|
||||
*/
|
||||
private void populateNameFilterComponents(FilesSet.Rule rule) {
|
||||
FilesSet.Rule.FileNameFilter nameFilter = rule.getFileNameFilter();
|
||||
this.nameTextField.setText(nameFilter.getTextToMatch());
|
||||
this.nameRegexCheckbox.setSelected(nameFilter.isRegex());
|
||||
if (nameFilter instanceof FilesSet.Rule.FullNameFilter) {
|
||||
this.fullNameRadioButton.setSelected(true);
|
||||
} else {
|
||||
this.extensionRadioButton.setSelected(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the UI components that display the optional path filter for a
|
||||
* rule.
|
||||
*
|
||||
* @param rule The files set rule to be edited.
|
||||
*/
|
||||
private void populatePathFilterComponents(FilesSet.Rule rule) {
|
||||
FilesSet.Rule.ParentPathFilter pathFilter = rule.getPathFilter();
|
||||
if (pathFilter != null) {
|
||||
this.pathTextField.setText(pathFilter.getTextToMatch());
|
||||
this.pathRegexCheckBox.setSelected(pathFilter.isRegex());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the data entered in the panel constitutes a valid
|
||||
* interesting files set membership rule definition, displaying a dialog
|
||||
* explaining the deficiency if the definition is invalid.
|
||||
*
|
||||
* @return True if the definition is valid, false otherwise.
|
||||
*/
|
||||
boolean isValidRuleDefinition() {
|
||||
// The rule must have a name.
|
||||
if (this.ruleNameTextField.getText().isEmpty()) {
|
||||
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
|
||||
NbBundle.getMessage(FilesSetPanel.class, "FilesSetRulePanel.messages.filesSetRulesMustBeNamed"),
|
||||
NotifyDescriptor.WARNING_MESSAGE);
|
||||
DialogDisplayer.getDefault().notify(notifyDesc);
|
||||
return false;
|
||||
}
|
||||
|
||||
// The rule must have name filter text.
|
||||
if (this.nameTextField.getText().isEmpty()) {
|
||||
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
|
||||
NbBundle.getMessage(FilesSetPanel.class, "FilesSetRulePanel.messages.emptyNameFilter"),
|
||||
NotifyDescriptor.WARNING_MESSAGE);
|
||||
DialogDisplayer.getDefault().notify(notifyDesc);
|
||||
return false;
|
||||
}
|
||||
|
||||
// The name filter 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) {
|
||||
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 (!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 filter, if specified, must either be a regular expression
|
||||
// that compiles or a string without illegal file path chars.
|
||||
if (!this.pathTextField.getText().isEmpty()) {
|
||||
if (this.pathRegexCheckBox.isSelected()) {
|
||||
try {
|
||||
Pattern.compile(this.pathTextField.getText());
|
||||
} catch (PatternSyntaxException ex) {
|
||||
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
|
||||
NbBundle.getMessage(FilesSetPanel.class, "FilesSetRulePanel.messages.invalidPathRegex", ex.getLocalizedMessage()),
|
||||
NotifyDescriptor.WARNING_MESSAGE);
|
||||
DialogDisplayer.getDefault().notify(notifyDesc);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!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);
|
||||
DialogDisplayer.getDefault().notify(notifyDesc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the files set rule created or edited.
|
||||
*
|
||||
* @return A name string.
|
||||
*/
|
||||
String getRuleName() {
|
||||
return this.ruleNameTextField.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name filter for the rule that was created or edited. Should only
|
||||
* be called if isValidDefintion() returns true.
|
||||
*
|
||||
* @return A name filter.
|
||||
* @throws IllegalStateException if the specified name filter is not valid.
|
||||
*/
|
||||
FilesSet.Rule.FileNameFilter getFileNameFilter() throws IllegalStateException {
|
||||
FilesSet.Rule.FileNameFilter filter = null;
|
||||
if (!this.nameTextField.getText().isEmpty()) {
|
||||
if (this.nameRegexCheckbox.isSelected()) {
|
||||
try {
|
||||
Pattern pattern = Pattern.compile(this.nameTextField.getText());
|
||||
if (this.fullNameRadioButton.isSelected()) {
|
||||
filter = new FilesSet.Rule.FullNameFilter(pattern);
|
||||
} else {
|
||||
filter = new FilesSet.Rule.ExtensionFilter(pattern);
|
||||
}
|
||||
} catch (PatternSyntaxException ex) {
|
||||
logger.log(Level.SEVERE, "Attempt to get regex name filter that does not compile", ex); // NON-NLS
|
||||
throw new IllegalStateException("The files set rule panel name filter is not in a valid state"); // NON-NLS
|
||||
}
|
||||
} else {
|
||||
if (FilesSetRulePanel.containsOnlyLegalChars(this.nameTextField.getText(), FilesSetRulePanel.ILLEGAL_FILE_NAME_CHARS)) {
|
||||
if (this.fullNameRadioButton.isSelected()) {
|
||||
filter = new FilesSet.Rule.FullNameFilter(this.nameTextField.getText());
|
||||
} else {
|
||||
filter = new FilesSet.Rule.ExtensionFilter(this.nameTextField.getText());
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "Attempt to get name filter with illegal chars"); // NON-NLS
|
||||
throw new IllegalStateException("The files set rule panel name filter is not in a valid state"); // NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file meta-type filter for the rule that was created or edited.
|
||||
*
|
||||
* @return A type filter.
|
||||
*/
|
||||
FilesSet.Rule.MetaTypeFilter getMetaTypeFilter() {
|
||||
if (this.filesRadioButton.isSelected()) {
|
||||
return new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.FILES);
|
||||
} else if (this.dirsRadioButton.isSelected()) {
|
||||
return new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.DIRECTORIES);
|
||||
} else {
|
||||
return new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.FILES_AND_DIRECTORIES);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the optional path filter for the rule that was created or edited.
|
||||
* Should only be called if isValidDefintion() returns true.
|
||||
*
|
||||
* @return A path filter or null if no path filter was specified.
|
||||
* @throws IllegalStateException if the specified path filter is not valid.
|
||||
*/
|
||||
FilesSet.Rule.ParentPathFilter getPathFilter() throws IllegalStateException {
|
||||
FilesSet.Rule.ParentPathFilter filter = null;
|
||||
if (!this.pathTextField.getText().isEmpty()) {
|
||||
if (this.pathRegexCheckBox.isSelected()) {
|
||||
try {
|
||||
filter = new FilesSet.Rule.ParentPathFilter(Pattern.compile(this.pathTextField.getText()));
|
||||
} catch (PatternSyntaxException ex) {
|
||||
logger.log(Level.SEVERE, "Attempt to get malformed path filter", ex); // NON-NLS
|
||||
throw new IllegalStateException("The files set rule panel path filter is not in a valid state"); // NON-NLS
|
||||
}
|
||||
} else {
|
||||
String path = this.pathTextField.getText();
|
||||
if (FilesSetRulePanel.containsOnlyLegalChars(path, FilesSetRulePanel.ILLEGAL_FILE_PATH_CHARS)) {
|
||||
// Add a leading path separator if omitted.
|
||||
if (!path.startsWith(FilesSetRulePanel.SLEUTHKIT_PATH_SEPARATOR)) {
|
||||
path = FilesSetRulePanel.SLEUTHKIT_PATH_SEPARATOR + path;
|
||||
}
|
||||
// Add a trailing path separator if omitted.
|
||||
if (!path.endsWith(FilesSetRulePanel.SLEUTHKIT_PATH_SEPARATOR)) {
|
||||
path += FilesSetRulePanel.SLEUTHKIT_PATH_SEPARATOR;
|
||||
}
|
||||
filter = new FilesSet.Rule.ParentPathFilter(path);
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "Attempt to get path filter with illegal chars"); // NON-NLS
|
||||
throw new IllegalStateException("The files set rule panel path filter is not in a valid state"); // NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks an input string for the use of illegal characters.
|
||||
*
|
||||
* @param toBeChecked The input string.
|
||||
* @param illegalChars The characters deemed to be illegal.
|
||||
* @return True if the string does not contain illegal characters, false
|
||||
* otherwise.
|
||||
*/
|
||||
private static boolean containsOnlyLegalChars(String toBeChecked, List<String> illegalChars) {
|
||||
for (String illegalChar : illegalChars) {
|
||||
if (toBeChecked.contains(illegalChar)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the state of the name filter UI components consistent with the state
|
||||
* of the UI components in the type button group.
|
||||
*/
|
||||
private void setComponentsForSearchType() {
|
||||
if (!this.filesRadioButton.isSelected()) {
|
||||
this.fullNameRadioButton.setSelected(true);
|
||||
this.extensionRadioButton.setEnabled(false);
|
||||
} else {
|
||||
this.extensionRadioButton.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
nameButtonGroup = new javax.swing.ButtonGroup();
|
||||
typeButtonGroup = new javax.swing.ButtonGroup();
|
||||
ruleNameLabel = new javax.swing.JLabel();
|
||||
ruleNameTextField = new javax.swing.JTextField();
|
||||
namePanel = new javax.swing.JPanel();
|
||||
nameRegexCheckbox = new javax.swing.JCheckBox();
|
||||
extensionRadioButton = new javax.swing.JRadioButton();
|
||||
nameTextField = new javax.swing.JTextField();
|
||||
fullNameRadioButton = new javax.swing.JRadioButton();
|
||||
typePanel = new javax.swing.JPanel();
|
||||
filesRadioButton = new javax.swing.JRadioButton();
|
||||
dirsRadioButton = new javax.swing.JRadioButton();
|
||||
filesAndDirsRadioButton = new javax.swing.JRadioButton();
|
||||
pathPanel = new javax.swing.JPanel();
|
||||
pathRegexCheckBox = new javax.swing.JCheckBox();
|
||||
pathTextField = new javax.swing.JTextField();
|
||||
pathSeparatorInfoLabel = new javax.swing.JLabel();
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(ruleNameLabel, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.ruleNameLabel.text")); // NOI18N
|
||||
|
||||
ruleNameTextField.setText(org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.ruleNameTextField.text")); // NOI18N
|
||||
|
||||
namePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.namePanel.border.title"))); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(nameRegexCheckbox, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.nameRegexCheckbox.text")); // NOI18N
|
||||
|
||||
nameButtonGroup.add(extensionRadioButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(extensionRadioButton, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.extensionRadioButton.text")); // NOI18N
|
||||
|
||||
nameTextField.setText(org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.nameTextField.text")); // NOI18N
|
||||
|
||||
nameButtonGroup.add(fullNameRadioButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(fullNameRadioButton, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.fullNameRadioButton.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout namePanelLayout = new javax.swing.GroupLayout(namePanel);
|
||||
namePanel.setLayout(namePanelLayout);
|
||||
namePanelLayout.setHorizontalGroup(
|
||||
namePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(namePanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(namePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(namePanelLayout.createSequentialGroup()
|
||||
.addComponent(fullNameRadioButton)
|
||||
.addGap(10, 10, 10)
|
||||
.addComponent(extensionRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(nameRegexCheckbox)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addComponent(nameTextField))
|
||||
.addContainerGap())
|
||||
);
|
||||
namePanelLayout.setVerticalGroup(
|
||||
namePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(namePanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(namePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(fullNameRadioButton)
|
||||
.addComponent(extensionRadioButton)
|
||||
.addComponent(nameRegexCheckbox))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
typePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.typePanel.border.title"))); // NOI18N
|
||||
|
||||
typeButtonGroup.add(filesRadioButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(filesRadioButton, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.filesRadioButton.text")); // NOI18N
|
||||
filesRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
filesRadioButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
typeButtonGroup.add(dirsRadioButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(dirsRadioButton, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.dirsRadioButton.text")); // NOI18N
|
||||
dirsRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
dirsRadioButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
typeButtonGroup.add(filesAndDirsRadioButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(filesAndDirsRadioButton, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.filesAndDirsRadioButton.text")); // NOI18N
|
||||
filesAndDirsRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
filesAndDirsRadioButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout typePanelLayout = new javax.swing.GroupLayout(typePanel);
|
||||
typePanel.setLayout(typePanelLayout);
|
||||
typePanelLayout.setHorizontalGroup(
|
||||
typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(typePanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(filesRadioButton)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(dirsRadioButton)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(filesAndDirsRadioButton)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
typePanelLayout.setVerticalGroup(
|
||||
typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(typePanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(filesRadioButton)
|
||||
.addComponent(dirsRadioButton)
|
||||
.addComponent(filesAndDirsRadioButton))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
pathPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.pathPanel.border.title"))); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(pathRegexCheckBox, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.pathRegexCheckBox.text")); // NOI18N
|
||||
|
||||
pathTextField.setText(org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.pathTextField.text")); // NOI18N
|
||||
|
||||
pathSeparatorInfoLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/info-icon-16.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(pathSeparatorInfoLabel, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.pathSeparatorInfoLabel.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout pathPanelLayout = new javax.swing.GroupLayout(pathPanel);
|
||||
pathPanel.setLayout(pathPanelLayout);
|
||||
pathPanelLayout.setHorizontalGroup(
|
||||
pathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pathPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(pathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addGroup(pathPanelLayout.createSequentialGroup()
|
||||
.addComponent(pathRegexCheckBox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(pathSeparatorInfoLabel))
|
||||
.addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 283, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
pathPanelLayout.setVerticalGroup(
|
||||
pathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pathPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(pathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(pathRegexCheckBox)
|
||||
.addComponent(pathSeparatorInfoLabel))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(typePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(namePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(ruleNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 59, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(ruleNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 256, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(pathPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(ruleNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(ruleNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(typePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(namePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pathPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
namePanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.namePanel.AccessibleContext.accessibleName")); // NOI18N
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void filesAndDirsRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_filesAndDirsRadioButtonActionPerformed
|
||||
setComponentsForSearchType();
|
||||
}//GEN-LAST:event_filesAndDirsRadioButtonActionPerformed
|
||||
|
||||
private void dirsRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dirsRadioButtonActionPerformed
|
||||
setComponentsForSearchType();
|
||||
}//GEN-LAST:event_dirsRadioButtonActionPerformed
|
||||
|
||||
private void filesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_filesRadioButtonActionPerformed
|
||||
setComponentsForSearchType();
|
||||
}//GEN-LAST:event_filesRadioButtonActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JRadioButton dirsRadioButton;
|
||||
private javax.swing.JRadioButton extensionRadioButton;
|
||||
private javax.swing.JRadioButton filesAndDirsRadioButton;
|
||||
private javax.swing.JRadioButton filesRadioButton;
|
||||
private javax.swing.JRadioButton fullNameRadioButton;
|
||||
private javax.swing.ButtonGroup nameButtonGroup;
|
||||
private javax.swing.JPanel namePanel;
|
||||
private javax.swing.JCheckBox nameRegexCheckbox;
|
||||
private javax.swing.JTextField nameTextField;
|
||||
private javax.swing.JPanel pathPanel;
|
||||
private javax.swing.JCheckBox pathRegexCheckBox;
|
||||
private javax.swing.JLabel pathSeparatorInfoLabel;
|
||||
private javax.swing.JTextField pathTextField;
|
||||
private javax.swing.JLabel ruleNameLabel;
|
||||
private javax.swing.JTextField ruleNameTextField;
|
||||
private javax.swing.ButtonGroup typeButtonGroup;
|
||||
private javax.swing.JPanel typePanel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
+577
@@ -0,0 +1,577 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.interestingitems;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Observable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.XMLUtil;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* Provides access to interesting item definitions persisted to disk. Clients
|
||||
* receive copies of the most recent interesting item definitions via
|
||||
* synchronized methods, allowing the definitions to be safely published to
|
||||
* multiple threads.
|
||||
*/
|
||||
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 DEFAULT_FILE_SET_DEFS_PATH = PlatformUtil.getUserConfigDirectory() + File.separator + INTERESTING_FILES_SET_DEFS_FILE_NAME;
|
||||
private static InterestingItemDefsManager instance;
|
||||
|
||||
/**
|
||||
* Gets the interesting item definitions manager singleton.
|
||||
*/
|
||||
synchronized static InterestingItemDefsManager getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new InterestingItemDefsManager();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the set of chars deemed to be illegal in file names (Windows).
|
||||
*
|
||||
* @return A list of characters.
|
||||
*/
|
||||
static List<String> getIllegalFileNameChars() {
|
||||
return InterestingItemDefsManager.ILLEGAL_FILE_NAME_CHARS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the set of chars deemed to be illegal in file path (SleuthKit/Windows).
|
||||
*
|
||||
* @return A list of characters.
|
||||
*/
|
||||
static List<String> getIllegalFilePathChars() {
|
||||
return InterestingItemDefsManager.ILLEGAL_FILE_PATH_CHARS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a copy of the current interesting files set definitions.
|
||||
*
|
||||
* @return A map of interesting files set names to interesting file sets,
|
||||
* possibly empty.
|
||||
*/
|
||||
synchronized Map<String, FilesSet> getInterestingFilesSets() {
|
||||
return FilesSetXML.readDefinitionsFile(DEFAULT_FILE_SET_DEFS_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current interesting file sets definitions, replacing any
|
||||
* previous definitions.
|
||||
*
|
||||
* @param filesSets A mapping of interesting files set names to files sets,
|
||||
* used to enforce unique files set names.
|
||||
*/
|
||||
synchronized void setInterestingFilesSets(Map<String, FilesSet> filesSets) {
|
||||
FilesSetXML.writeDefinitionsFile(DEFAULT_FILE_SET_DEFS_PATH, filesSets);
|
||||
this.setChanged();
|
||||
this.notifyObservers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and writes interesting files set definitions to and from disk in
|
||||
* XML format.
|
||||
*/
|
||||
private final static class FilesSetXML {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(FilesSetXML.class.getName());
|
||||
private static final String XML_ENCODING = "UTF-8"; //NON-NLS
|
||||
private static final List<String> illegalFileNameChars = InterestingItemDefsManager.getIllegalFileNameChars();
|
||||
|
||||
// The following tags and attributes are identical to those used in the
|
||||
// TSK Framework interesting files set definitions file schema.
|
||||
private static final String FILE_SETS_ROOT_TAG = "INTERESTING_FILE_SETS"; //NON-NLS
|
||||
private static final String FILE_SET_TAG = "INTERESTING_FILE_SET"; //NON-NLS
|
||||
private static final String NAME_RULE_TAG = "NAME"; //NON-NLS
|
||||
private static final String EXTENSION_RULE_TAG = "EXTENSION"; //NON-NLS
|
||||
private static final String NAME_ATTR = "name"; //NON-NLS
|
||||
private static final String DESC_ATTR = "description"; //NON-NLS
|
||||
private static final String IGNORE_KNOWN_FILES_ATTR = "ignoreKnown"; //NON-NLS
|
||||
private static final String TYPE_FILTER_ATTR = "typeFilter"; //NON-NLS
|
||||
private static final String PATH_FILTER_ATTR = "pathFilter"; //NON-NLS
|
||||
private static final String TYPE_FILTER_VALUE_FILES = "file"; //NON-NLS
|
||||
private static final String TYPE_FILTER_VALUE_DIRS = "dir"; //NON-NLS
|
||||
|
||||
// The following tags and attributes are currently specific to the
|
||||
// Autopsy implementation of interesting files set definitions. Autopsy
|
||||
// definitions that use these will not be able to be used by TSK
|
||||
// Framework. However, Autopsy can accept TSK Framework definitions:
|
||||
//
|
||||
// 1. Rules do not have names in the TSK Framework schema, but rules do
|
||||
// have names in the Autopsy schema. Names will be synthesized as needed
|
||||
// to allow Autopsy to use TSK Framework interesting files set
|
||||
// definitions.
|
||||
// 2. The TSK Framework has an interesting files module that supports
|
||||
// simple globbing with "*" characters. Name rules and path filters with
|
||||
// "*" characters will be converted to regexes to allow Autopsy to use
|
||||
// TSK Framework interesting files set definitions.
|
||||
// 3. Type filters are required by Autopsy, but not by TSK Frmaework.
|
||||
// Missing type filters will defualt to "files" filters.
|
||||
private static final String REGEX_ATTR = "regex"; //NON-NLS
|
||||
private static final String PATH_REGEX_ATTR = "pathRegex"; //NON-NLS
|
||||
private static final String TYPE_FILTER_VALUE_FILES_AND_DIRS = "files_and_dirs"; //NON-NLS
|
||||
private static final String UNNAMED_LEGACY_RULE_PREFIX = "Unnamed Rule "; // NON-NLS
|
||||
private static int unnamedLegacyRuleCounter;
|
||||
|
||||
/**
|
||||
* Reads interesting file set definitions from an XML file.
|
||||
*
|
||||
* @param filePath Path of the set definitions file as a string.
|
||||
* @return The set definitions in a map of set names to sets.
|
||||
*/
|
||||
// Note: This method takes a file path to support the possibility of
|
||||
// multiple intersting files set definition files, e.g., one for
|
||||
// definitions that ship with Autopsy and one for user definitions.
|
||||
static Map<String, FilesSet> readDefinitionsFile(String filePath) {
|
||||
Map<String, FilesSet> filesSets = new HashMap<>();
|
||||
|
||||
// Check if the file exists.
|
||||
File defsFile = new File(filePath);
|
||||
if (!defsFile.exists()) {
|
||||
return filesSets;
|
||||
}
|
||||
|
||||
// Check if the file can be read.
|
||||
if (!defsFile.canRead()) {
|
||||
logger.log(Level.SEVERE, "Interesting file sets definition file at {0} exists, but cannot be read", filePath); // NON-NLS
|
||||
return filesSets;
|
||||
}
|
||||
|
||||
// Parse the XML in the file.
|
||||
Document doc = XMLUtil.loadDoc(FilesSetXML.class, filePath);
|
||||
if (doc == null) {
|
||||
logger.log(Level.SEVERE, "Failed to parse interesting file sets definition file at {0}", filePath); // NON-NLS
|
||||
return filesSets;
|
||||
}
|
||||
|
||||
// Get the root element.
|
||||
Element root = doc.getDocumentElement();
|
||||
if (root == null) {
|
||||
logger.log(Level.SEVERE, "Failed to get root {0} element tag of interesting file sets definition file at {1}", new Object[]{FilesSetXML.FILE_SETS_ROOT_TAG, filePath}); // NON-NLS
|
||||
return filesSets;
|
||||
}
|
||||
|
||||
// Read in the files set definitions.
|
||||
NodeList setElems = root.getElementsByTagName(FILE_SET_TAG);
|
||||
for (int i = 0; i < setElems.getLength(); ++i) {
|
||||
readFilesSet((Element) setElems.item(i), filesSets, filePath);
|
||||
}
|
||||
|
||||
return filesSets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in an interesting files set.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
private static void readFilesSet(Element setElem, Map<String, FilesSet> filesSets, String filePath) {
|
||||
// The file set must have a unique name.
|
||||
String setName = setElem.getAttribute(FilesSetXML.NAME_ATTR);
|
||||
if (setName.isEmpty()) {
|
||||
logger.log(Level.SEVERE, "Found {0} element without required {1} attribute, ignoring malformed file set definition in interesting file sets definition file at {2}", new Object[]{FilesSetXML.FILE_SET_TAG, FilesSetXML.NAME_ATTR, filePath}); // NON-NLS
|
||||
return;
|
||||
}
|
||||
if (filesSets.containsKey(setName)) {
|
||||
logger.log(Level.SEVERE, "Found duplicate definition of set named {0} in interesting file sets definition file at {1}, discarding duplicate set", new Object[]{setName, filePath}); // NON-NLS
|
||||
return;
|
||||
}
|
||||
|
||||
// The file set may have a description. The empty string is o.k.
|
||||
String description = setElem.getAttribute(FilesSetXML.DESC_ATTR);
|
||||
|
||||
// The file set may or may not ignore known files. The default behavior
|
||||
// is to not ignore them.
|
||||
String ignoreKnown = setElem.getAttribute(FilesSetXML.IGNORE_KNOWN_FILES_ATTR);
|
||||
boolean ignoreKnownFiles = false;
|
||||
if (!ignoreKnown.isEmpty()) {
|
||||
ignoreKnownFiles = Boolean.parseBoolean(ignoreKnown);
|
||||
}
|
||||
|
||||
// Read file name set membership rules, if any.
|
||||
FilesSetXML.unnamedLegacyRuleCounter = 1;
|
||||
Map<String, FilesSet.Rule> rules = new HashMap<>();
|
||||
NodeList nameRuleElems = setElem.getElementsByTagName(FilesSetXML.NAME_RULE_TAG);
|
||||
for (int j = 0; j < nameRuleElems.getLength(); ++j) {
|
||||
Element elem = (Element) nameRuleElems.item(j);
|
||||
FilesSet.Rule rule = FilesSetXML.readFileNameRule(elem);
|
||||
if (rule != null) {
|
||||
if (!rules.containsKey(rule.getName())) {
|
||||
rules.put(rule.getName(), rule);
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "Found duplicate rule {0} for set named {1} in interesting file sets definition file at {2}, discarding malformed set", new Object[]{rule.getName(), setName, filePath}); // NON-NLS
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "Found malformed rule for set named {0} in interesting file sets definition file at {1}, discarding malformed set", new Object[]{setName, filePath}); // NON-NLS
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Read file extension set membership rules, if any.
|
||||
NodeList extRuleElems = setElem.getElementsByTagName(FilesSetXML.EXTENSION_RULE_TAG);
|
||||
for (int j = 0; j < extRuleElems.getLength(); ++j) {
|
||||
Element elem = (Element) extRuleElems.item(j);
|
||||
FilesSet.Rule rule = FilesSetXML.readFileExtensionRule(elem);
|
||||
if (rule != null) {
|
||||
if (!rules.containsKey(rule.getName())) {
|
||||
rules.put(rule.getName(), rule);
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "Found duplicate rule {0} for set named {1} in interesting file sets definition file at {2}, discarding malformed set", new Object[]{rule.getName(), setName, filePath});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "Found malformed rule for set named {0} in interesting file sets definition file at {1}, discarding malformed set", new Object[]{setName, filePath});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Make the files set. Note that degenerate sets with no rules are
|
||||
// allowed to facilitate the separation of set definition and rule
|
||||
// definitions. A set without rules is simply the empty set.
|
||||
FilesSet set = new FilesSet(setName, description, ignoreKnownFiles, rules);
|
||||
filesSets.put(set.getName(), set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an interesting files set file name rule from the data in an
|
||||
* 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.
|
||||
* @return A file name rule, or null if there is an error (the error is
|
||||
* logged).
|
||||
*/
|
||||
private static FilesSet.Rule readFileNameRule(Element elem) {
|
||||
String ruleName = FilesSetXML.readRuleName(elem);
|
||||
|
||||
// The content of the rule tag is a file name filter. It may be a
|
||||
// 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.FullNameFilter nameFilter;
|
||||
String regex = elem.getAttribute(FilesSetXML.REGEX_ATTR);
|
||||
if ((!regex.isEmpty() && regex.equalsIgnoreCase("true")) || content.contains("*")) { // NON_NLS
|
||||
Pattern pattern = compileRegex(content);
|
||||
if (pattern != null) {
|
||||
nameFilter = new FilesSet.Rule.FullNameFilter(pattern);
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "Error compiling " + FilesSetXML.NAME_RULE_TAG + " regex, ignoring malformed '{0}' rule definition", ruleName); // NON-NLS
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
for (String illegalChar : illegalFileNameChars) {
|
||||
if (content.contains(illegalChar)) {
|
||||
logger.log(Level.SEVERE, FilesSetXML.NAME_RULE_TAG + " content has illegal chars, ignoring malformed '{0}' rule definition", new Object[]{FilesSetXML.NAME_RULE_TAG, ruleName}); // NON-NLS
|
||||
return null;
|
||||
}
|
||||
}
|
||||
nameFilter = new FilesSet.Rule.FullNameFilter(content);
|
||||
}
|
||||
|
||||
// Read in the type filter.
|
||||
FilesSet.Rule.MetaTypeFilter metaTypeFilter = FilesSetXML.readMetaTypeFilter(elem);
|
||||
if (metaTypeFilter == null) {
|
||||
// Malformed attribute.
|
||||
return null;
|
||||
}
|
||||
|
||||
// Read in the optional path filter. Null is o.k., but if the attribute
|
||||
// is there, be sure it is not malformed.
|
||||
FilesSet.Rule.ParentPathFilter pathFilter = null;
|
||||
if (!elem.getAttribute(FilesSetXML.PATH_FILTER_ATTR).isEmpty()
|
||||
|| !elem.getAttribute(FilesSetXML.PATH_REGEX_ATTR).isEmpty()) {
|
||||
pathFilter = FilesSetXML.readPathFilter(elem);
|
||||
if (pathFilter == null) {
|
||||
// Malformed attribute.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new FilesSet.Rule(ruleName, nameFilter, metaTypeFilter, pathFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an interesting files set file name extension rule from the
|
||||
* data in an XML element.
|
||||
*
|
||||
* @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).
|
||||
*/
|
||||
private static FilesSet.Rule readFileExtensionRule(Element elem) {
|
||||
String ruleName = FilesSetXML.readRuleName(elem);
|
||||
|
||||
// The content of the rule tag is a file name extension filter. It may
|
||||
// be a regex, or it may be from a TSK Framework rule definition
|
||||
// with a "*" globbing char.
|
||||
String content = elem.getTextContent();
|
||||
FilesSet.Rule.ExtensionFilter extFilter;
|
||||
String regex = elem.getAttribute(FilesSetXML.REGEX_ATTR);
|
||||
if ((!regex.isEmpty() && regex.equalsIgnoreCase("true")) || content.contains("*")) { // NON_NLS
|
||||
Pattern pattern = compileRegex(content);
|
||||
if (pattern != null) {
|
||||
extFilter = new FilesSet.Rule.ExtensionFilter(pattern);
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "Error compiling " + FilesSetXML.EXTENSION_RULE_TAG + " regex, ignoring malformed {0} rule definition", ruleName); // NON-NLS
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
for (String illegalChar : illegalFileNameChars) {
|
||||
if (content.contains(illegalChar)) {
|
||||
logger.log(Level.SEVERE, "{0} content has illegal chars, ignoring malformed {1} rule definition", ruleName); // NON-NLS
|
||||
return null;
|
||||
}
|
||||
}
|
||||
extFilter = new FilesSet.Rule.ExtensionFilter(content);
|
||||
}
|
||||
|
||||
// The rule must have a meta-type filter, unless a TSK Framework
|
||||
// definitions file is being read.
|
||||
FilesSet.Rule.MetaTypeFilter metaTypeFilter = null;
|
||||
if (!elem.getAttribute(FilesSetXML.TYPE_FILTER_ATTR).isEmpty()) {
|
||||
metaTypeFilter = FilesSetXML.readMetaTypeFilter(elem);
|
||||
if (metaTypeFilter == null) {
|
||||
// Malformed attribute.
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
metaTypeFilter = new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.FILES);
|
||||
}
|
||||
|
||||
// The rule may have a path filter. Null is o.k., but if the attribute
|
||||
// is there, it must not be malformed.
|
||||
FilesSet.Rule.ParentPathFilter pathFilter = null;
|
||||
if (!elem.getAttribute(FilesSetXML.PATH_FILTER_ATTR).isEmpty()
|
||||
|| !elem.getAttribute(FilesSetXML.PATH_REGEX_ATTR).isEmpty()) {
|
||||
pathFilter = FilesSetXML.readPathFilter(elem);
|
||||
if (pathFilter == null) {
|
||||
// Malformed attribute.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new FilesSet.Rule(ruleName, extFilter, metaTypeFilter, pathFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a rule name attribute from a rule element.
|
||||
*
|
||||
* @param elem A rule element.
|
||||
* @return A rule name.
|
||||
*/
|
||||
private static String readRuleName(Element elem) {
|
||||
// The rule must have a name.
|
||||
String ruleName = elem.getAttribute(FilesSetXML.NAME_ATTR);
|
||||
if (ruleName.isEmpty()) {
|
||||
// Assume a TSK Framework definitions file is being read and
|
||||
// synthesize a rule name.
|
||||
ruleName = UNNAMED_LEGACY_RULE_PREFIX + Integer.toString(FilesSetXML.unnamedLegacyRuleCounter++);
|
||||
}
|
||||
return ruleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to compile a regular expression.
|
||||
*
|
||||
* @param regex The regular expression.
|
||||
* @return A pattern object, or null if the compilation fails.
|
||||
*/
|
||||
private static Pattern compileRegex(String regex) {
|
||||
try {
|
||||
return Pattern.compile(regex);
|
||||
} catch (PatternSyntaxException ex) {
|
||||
logger.log(Level.SEVERE, "Error compiling rule regex: " + ex.getMessage(), ex); // NON-NLS
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a meta-type filter for an interesting files set membership
|
||||
* rule from data in an XML element.
|
||||
*
|
||||
* @param ruleElement The XML element.
|
||||
* @return The meta-type filter, or null if there is an error (logged).
|
||||
*/
|
||||
private static FilesSet.Rule.MetaTypeFilter readMetaTypeFilter(Element ruleElement) {
|
||||
FilesSet.Rule.MetaTypeFilter filter = null;
|
||||
String filterAttribute = ruleElement.getAttribute(FilesSetXML.TYPE_FILTER_ATTR);
|
||||
if (!filterAttribute.isEmpty()) {
|
||||
switch (filterAttribute) {
|
||||
case FilesSetXML.TYPE_FILTER_VALUE_FILES:
|
||||
filter = new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.FILES);
|
||||
break;
|
||||
case FilesSetXML.TYPE_FILTER_VALUE_DIRS:
|
||||
filter = new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.DIRECTORIES);
|
||||
break;
|
||||
case FilesSetXML.TYPE_FILTER_VALUE_FILES_AND_DIRS:
|
||||
filter = new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.FILES_AND_DIRECTORIES);
|
||||
break;
|
||||
default:
|
||||
logger.log(Level.SEVERE, "Found {0} " + FilesSetXML.TYPE_FILTER_ATTR + " attribute with unrecognized value ''{0}'', ignoring malformed rule definition", filterAttribute); // NON-NLS
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Accept TSK Framework interesting files set definitions,
|
||||
// default to files.
|
||||
filter = new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.FILES);
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a path filter for an interesting files set membership rule
|
||||
* from data in an XML element.
|
||||
*
|
||||
* @param ruleElement The XML element.
|
||||
* @return The path filter, or null if there is an error (logged).
|
||||
*/
|
||||
private static FilesSet.Rule.ParentPathFilter readPathFilter(Element ruleElement) {
|
||||
FilesSet.Rule.ParentPathFilter filter = null;
|
||||
String path = ruleElement.getAttribute(FilesSetXML.PATH_FILTER_ATTR);
|
||||
String pathRegex = ruleElement.getAttribute(FilesSetXML.PATH_REGEX_ATTR);
|
||||
if (!pathRegex.isEmpty() && path.isEmpty()) {
|
||||
try {
|
||||
Pattern pattern = Pattern.compile(pathRegex);
|
||||
filter = new FilesSet.Rule.ParentPathFilter(pattern);
|
||||
} catch (PatternSyntaxException ex) {
|
||||
logger.log(Level.SEVERE, "Error compiling " + FilesSetXML.PATH_REGEX_ATTR + " regex, ignoring malformed path filter definition", ex); // NON-NLS
|
||||
}
|
||||
} else if (!path.isEmpty() && pathRegex.isEmpty()) {
|
||||
filter = new FilesSet.Rule.ParentPathFilter(path);
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes interesting files set definitions to disk as an XML file,
|
||||
* logging any errors.
|
||||
*
|
||||
* @param filePath Path of the set definitions file as a string.
|
||||
* @returns True if the definitions are written to disk, false
|
||||
* otherwise.
|
||||
*/
|
||||
// Note: This method takes a file path to support the possibility of
|
||||
// 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 filter
|
||||
// type tag.
|
||||
FilesSet.Rule.FileNameFilter nameFilter = rule.getFileNameFilter();
|
||||
Element ruleElement;
|
||||
if (nameFilter instanceof FilesSet.Rule.FullNameFilter) {
|
||||
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 filter regex attribute
|
||||
ruleElement.setAttribute(FilesSetXML.REGEX_ATTR, Boolean.toString(nameFilter.isRegex()));
|
||||
|
||||
// Add the type filter attribute.
|
||||
FilesSet.Rule.MetaTypeFilter typeFilter = rule.getMetaTypeFilter();
|
||||
switch (typeFilter.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 filter.
|
||||
FilesSet.Rule.ParentPathFilter pathFilter = rule.getPathFilter();
|
||||
if (pathFilter != null) {
|
||||
if (pathFilter.isRegex()) {
|
||||
ruleElement.setAttribute(FilesSetXML.PATH_REGEX_ATTR, pathFilter.getTextToMatch());
|
||||
} else {
|
||||
ruleElement.setAttribute(FilesSetXML.PATH_FILTER_ATTR, pathFilter.getTextToMatch());
|
||||
}
|
||||
}
|
||||
|
||||
// Add the name filter text as the rule element content.
|
||||
ruleElement.setTextContent(nameFilter.getTextToMatch());
|
||||
|
||||
setElement.appendChild(ruleElement);
|
||||
}
|
||||
|
||||
rootElement.appendChild(setElement);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.interestingitems;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.netbeans.spi.options.OptionsPanelController;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.Lookup;
|
||||
|
||||
@OptionsPanelController.TopLevelRegistration(
|
||||
categoryName = "#OptionsCategory_Name_InterestingItemDefinitions",
|
||||
iconBase = "org/sleuthkit/autopsy/images/interesting_item_32x32.png",
|
||||
keywords = "#OptionsCategory_Keywords_InterestingItemDefinitions",
|
||||
keywordsCategory = "InterestingItemDefinitions",
|
||||
position = 5
|
||||
)
|
||||
@org.openide.util.NbBundle.Messages({"OptionsCategory_Name_InterestingItemDefinitions=Interesting Item Definitions", "OptionsCategory_Keywords_InterestingItemDefinitions=InterestingItemDefinitions"})
|
||||
public final class InterestingItemDefsOptionsPanelController extends OptionsPanelController {
|
||||
|
||||
private InterestingItemDefsPanel panel;
|
||||
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
||||
private boolean changed;
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
getPanel().load();
|
||||
changed = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyChanges() {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getPanel().store();
|
||||
changed = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
// need not do anything special, if no changes have been persisted yet
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChanged() {
|
||||
return changed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HelpCtx getHelpCtx() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getComponent(Lookup masterLookup) {
|
||||
return getPanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
pcs.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
pcs.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
private InterestingItemDefsPanel getPanel() {
|
||||
if (panel == null) {
|
||||
panel = new InterestingItemDefsPanel();
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
|
||||
void changed() {
|
||||
if (!changed) {
|
||||
changed = true;
|
||||
pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);
|
||||
}
|
||||
pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
+558
@@ -0,0 +1,558 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.ButtonGroup" name="fileNameButtonGroup">
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="newSetButton" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="editSetButton" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="deleteSetButton" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="setsListLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="setsListScrollPane" max="32767" attributes="0"/>
|
||||
<Component id="ignoreKnownFilesCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="selectedSetLabel" min="-2" pref="71" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="setNameTextField" min="-2" pref="208" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="setDescPanel" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="separator" min="-2" pref="2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="selectedRuleLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="ruleNameTextField" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="rulesListLabel" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="fileNamePanel" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="rulePathPanel" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="10" pref="10" max="-2" attributes="0"/>
|
||||
<Component id="newRuleButton" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="editRuleButton" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="deleteRuleButton" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="rulesListScrollPane" max="32767" attributes="0"/>
|
||||
<Component id="typePanel" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="setsListLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="rulesListLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="setsListScrollPane" min="-2" pref="199" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="selectedSetLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="setNameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="setDescPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="ignoreKnownFilesCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="rulesListScrollPane" min="-2" pref="122" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="selectedRuleLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="ruleNameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="16" max="-2" attributes="0"/>
|
||||
<Component id="typePanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="fileNamePanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="rulePathPanel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="deleteRuleButton" linkSize="2" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="editRuleButton" linkSize="2" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="newRuleButton" linkSize="2" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="deleteSetButton" linkSize="2" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="editSetButton" linkSize="2" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="newSetButton" linkSize="2" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Component id="separator" alignment="0" min="-2" pref="474" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="setsListLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.setsListLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="rulesListLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.rulesListLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="setsListScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JList" name="setsList">
|
||||
<Properties>
|
||||
<Property name="selectionMode" type="int" value="0"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<FilesSet>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JScrollPane" name="rulesListScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JList" name="rulesList">
|
||||
<Properties>
|
||||
<Property name="selectionMode" type="int" value="0"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<FilesSet.Rule>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="selectedSetLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.selectedSetLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="ignoreKnownFilesCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.ignoreKnownFilesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="selectedRuleLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.selectedRuleLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="newSetButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/add16.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.newSetButton.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="newSetButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="editSetButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/edit16.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.editSetButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="editSetButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="deleteSetButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/delete16.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.deleteSetButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteSetButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="newRuleButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/add16.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.newRuleButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="newRuleButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="editRuleButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/edit16.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.editRuleButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="editRuleButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="deleteRuleButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/delete16.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.deleteRuleButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteRuleButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSeparator" name="separator">
|
||||
<Properties>
|
||||
<Property name="orientation" type="int" value="1"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="setNameTextField">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="ruleNameTextField">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.ruleNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="fileNamePanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Name">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.fileNamePanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="fileNameTextField" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="fileNameRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<Component id="fileNameExtensionRadioButton" min="-2" pref="114" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="fileNameRegexCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="fileNameTextField" min="-2" pref="20" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="fileNameRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="fileNameExtensionRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="fileNameRegexCheckbox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="fileNameRegexCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.fileNameRegexCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="fileNameExtensionRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="fileNameButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.fileNameExtensionRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="fileNameTextField">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.fileNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="fileNameRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="fileNameButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.fileNameRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="rulePathPanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Path">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.rulePathPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="rulePathFilterRegexCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="rulePathFilterTextField" alignment="0" min="-2" pref="283" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="rulePathFilterTextField" min="-2" pref="20" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="rulePathFilterRegexCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="rulePathFilterRegexCheckBox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.rulePathFilterRegexCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="rulePathFilterTextField">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.rulePathFilterTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="setDescPanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Description">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.setDescPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="setDescScrollPanel" min="-2" pref="296" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="setDescScrollPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="setDescScrollPanel">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextArea" name="setDescriptionTextArea">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="columns" type="int" value="20"/>
|
||||
<Property name="rows" type="int" value="5"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="typePanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Search for:">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.typePanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="filesRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="dirsRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="bothRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="filesRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="dirsRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="bothRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JRadioButton" name="filesRadioButton">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.filesRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="dirsRadioButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.dirsRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="bothRadioButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.bothRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
+793
@@ -0,0 +1,793 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.interestingitems;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
|
||||
|
||||
/**
|
||||
* A panel that allows a user to make interesting item definitions.
|
||||
*/
|
||||
final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel implements OptionsPanel {
|
||||
|
||||
private final DefaultListModel<FilesSet> setsListModel = new DefaultListModel<>();
|
||||
private final DefaultListModel<FilesSet.Rule> rulesListModel = new DefaultListModel<>();
|
||||
|
||||
// The following is a map of interesting files set names to interesting
|
||||
// files set definitions. It is a snapshot of the files set definitions
|
||||
// obtained from the interesting item definitions manager at the time the
|
||||
// the panel is loaded. When the panel saves or stores its settings, these
|
||||
// definitions, possibly changed, are submitted back to the interesting item
|
||||
// definitions manager. Note that it is a tree map to aid in displaying
|
||||
// files sets in sorted order by name.
|
||||
private TreeMap<String, FilesSet> filesSets;
|
||||
|
||||
/**
|
||||
* Constructs an interesting item definitions panel.
|
||||
*/
|
||||
InterestingItemDefsPanel() {
|
||||
this.initComponents();
|
||||
this.setsList.setModel(setsListModel);
|
||||
this.setsList.addListSelectionListener(new InterestingItemDefsPanel.SetsListSelectionListener());
|
||||
this.rulesList.setModel(rulesListModel);
|
||||
this.rulesList.addListSelectionListener(new InterestingItemDefsPanel.RulesListSelectionListener());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public void saveSettings() {
|
||||
InterestingItemDefsManager.getInstance().setInterestingFilesSets(this.filesSets);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public void store() {
|
||||
this.saveSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public void load() {
|
||||
this.resetComponents();
|
||||
|
||||
// Get a working copy of the interesting files set definitions and sort
|
||||
// by set name.
|
||||
this.filesSets = new TreeMap<>(InterestingItemDefsManager.getInstance().getInterestingFilesSets());
|
||||
|
||||
// Populate the list model for the interesting files sets list
|
||||
// component.
|
||||
for (FilesSet set : this.filesSets.values()) {
|
||||
this.setsListModel.addElement(set);
|
||||
}
|
||||
|
||||
if (!this.filesSets.isEmpty()) {
|
||||
// Select the first files set by default. The list selections
|
||||
// listeners will then populate the other components.
|
||||
EventQueue.invokeLater(() -> {
|
||||
InterestingItemDefsPanel.this.setsList.setSelectedIndex(0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the list models and resets all of the components.
|
||||
*/
|
||||
private void resetComponents() {
|
||||
this.resetRuleComponents();
|
||||
this.setsListModel.clear();
|
||||
this.setNameTextField.setText("");
|
||||
this.setDescriptionTextArea.setText("");
|
||||
this.ignoreKnownFilesCheckbox.setSelected(true);
|
||||
this.newSetButton.setEnabled(true);
|
||||
this.editSetButton.setEnabled(false);
|
||||
this.deleteSetButton.setEnabled(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the rules list model and resets all of the rule-related
|
||||
* components.
|
||||
*/
|
||||
private void resetRuleComponents() {
|
||||
this.ruleNameTextField.setText("");
|
||||
this.fileNameTextField.setText("");
|
||||
this.fileNameRadioButton.setSelected(true);
|
||||
this.fileNameRegexCheckbox.setSelected(false);
|
||||
this.filesRadioButton.setSelected(true);
|
||||
this.rulePathFilterTextField.setText("");
|
||||
this.rulePathFilterRegexCheckBox.setSelected(false);
|
||||
this.newRuleButton.setEnabled(!this.setsListModel.isEmpty());
|
||||
this.editRuleButton.setEnabled(false);
|
||||
this.deleteRuleButton.setEnabled(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* A list events listener for the interesting files sets list component.
|
||||
*/
|
||||
private final class SetsListSelectionListener implements ListSelectionListener {
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if (e.getValueIsAdjusting()) {
|
||||
return;
|
||||
}
|
||||
|
||||
InterestingItemDefsPanel.this.rulesListModel.clear();
|
||||
InterestingItemDefsPanel.this.resetRuleComponents();
|
||||
|
||||
// Get the selected interesting files set and populate the set
|
||||
// components.
|
||||
FilesSet selectedSet = InterestingItemDefsPanel.this.setsList.getSelectedValue();
|
||||
if (selectedSet != null) {
|
||||
// Populate the components that display the properties of the
|
||||
// selected files set.
|
||||
InterestingItemDefsPanel.this.setNameTextField.setText(selectedSet.getName());
|
||||
InterestingItemDefsPanel.this.setDescriptionTextArea.setText(selectedSet.getDescription());
|
||||
InterestingItemDefsPanel.this.ignoreKnownFilesCheckbox.setSelected(selectedSet.ignoresKnownFiles());
|
||||
|
||||
// Enable the new, edit and delete set buttons.
|
||||
InterestingItemDefsPanel.this.newSetButton.setEnabled(true);
|
||||
InterestingItemDefsPanel.this.editSetButton.setEnabled(true);
|
||||
InterestingItemDefsPanel.this.deleteSetButton.setEnabled(true);
|
||||
|
||||
// Populate the rule definitions list, sorted by name.
|
||||
TreeMap<String, FilesSet.Rule> rules = new TreeMap<>(selectedSet.getRules());
|
||||
for (FilesSet.Rule rule : rules.values()) {
|
||||
InterestingItemDefsPanel.this.rulesListModel.addElement(rule);
|
||||
}
|
||||
|
||||
// Select the first rule by default.
|
||||
if (!InterestingItemDefsPanel.this.rulesListModel.isEmpty()) {
|
||||
InterestingItemDefsPanel.this.rulesList.setSelectedIndex(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A list events listener for the interesting files set rules list
|
||||
* component.
|
||||
*/
|
||||
private final class RulesListSelectionListener implements ListSelectionListener {
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if (e.getValueIsAdjusting()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the selected rule and populate the rule components.
|
||||
FilesSet.Rule rule = InterestingItemDefsPanel.this.rulesList.getSelectedValue();
|
||||
if (rule != null) {
|
||||
// Get the filters that make up the rule.
|
||||
FilesSet.Rule.FileNameFilter nameFilter = rule.getFileNameFilter();
|
||||
FilesSet.Rule.MetaTypeFilter typeFilter = rule.getMetaTypeFilter();
|
||||
FilesSet.Rule.ParentPathFilter pathFilter = rule.getPathFilter();
|
||||
|
||||
// Populate the components that display the properties of the
|
||||
// selected rule.
|
||||
InterestingItemDefsPanel.this.ruleNameTextField.setText(rule.getName());
|
||||
InterestingItemDefsPanel.this.fileNameTextField.setText(nameFilter.getTextToMatch());
|
||||
InterestingItemDefsPanel.this.fileNameRadioButton.setSelected(nameFilter instanceof FilesSet.Rule.FullNameFilter);
|
||||
InterestingItemDefsPanel.this.fileNameExtensionRadioButton.setSelected(nameFilter instanceof FilesSet.Rule.ExtensionFilter);
|
||||
InterestingItemDefsPanel.this.fileNameRegexCheckbox.setSelected(nameFilter.isRegex());
|
||||
switch (typeFilter.getMetaType()) {
|
||||
case FILES:
|
||||
InterestingItemDefsPanel.this.filesRadioButton.setSelected(true);
|
||||
break;
|
||||
case DIRECTORIES:
|
||||
InterestingItemDefsPanel.this.dirsRadioButton.setSelected(true);
|
||||
break;
|
||||
case FILES_AND_DIRECTORIES:
|
||||
InterestingItemDefsPanel.this.bothRadioButton.setSelected(true);
|
||||
break;
|
||||
}
|
||||
if (pathFilter != null) {
|
||||
InterestingItemDefsPanel.this.rulePathFilterTextField.setText(pathFilter.getTextToMatch());
|
||||
InterestingItemDefsPanel.this.rulePathFilterRegexCheckBox.setSelected(pathFilter.isRegex());
|
||||
} else {
|
||||
InterestingItemDefsPanel.this.rulePathFilterTextField.setText("");
|
||||
InterestingItemDefsPanel.this.rulePathFilterRegexCheckBox.setSelected(false);
|
||||
}
|
||||
|
||||
// Enable the new, edit and delete rule buttons.
|
||||
InterestingItemDefsPanel.this.newRuleButton.setEnabled(true);
|
||||
InterestingItemDefsPanel.this.editRuleButton.setEnabled(true);
|
||||
InterestingItemDefsPanel.this.deleteRuleButton.setEnabled(true);
|
||||
} else {
|
||||
InterestingItemDefsPanel.this.resetRuleComponents();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display an interesting files set definition panel in a dialog box and
|
||||
* respond to user interactions with the dialog.
|
||||
*
|
||||
* @param selectedSet The currently selected files set, may be null to
|
||||
* indicate a new interesting files set definition is to be created.
|
||||
*/
|
||||
private void doFileSetsDialog(FilesSet selectedSet) {
|
||||
// Create a files set defintion panle.
|
||||
FilesSetPanel panel;
|
||||
if (selectedSet != null) {
|
||||
// Editing an existing set definition.
|
||||
panel = new FilesSetPanel(selectedSet);
|
||||
} else {
|
||||
// Creating a new set definition.
|
||||
panel = new FilesSetPanel();
|
||||
}
|
||||
|
||||
// Do a dialog box with the files set panel until the user either enters
|
||||
// a valid definition or cancels. Note that the panel gives the user
|
||||
// feedback when isValidDefinition() is called.
|
||||
int option = JOptionPane.OK_OPTION;
|
||||
do {
|
||||
option = JOptionPane.showConfirmDialog(null, panel, NbBundle.getMessage(FilesSetPanel.class, "FilesSetPanel.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
|
||||
} while (option == JOptionPane.OK_OPTION && !panel.isValidDefinition());
|
||||
|
||||
if (option == JOptionPane.OK_OPTION) {
|
||||
Map<String, FilesSet.Rule> rules = new HashMap<>();
|
||||
if (selectedSet != null) {
|
||||
// Interesting file sets are immutable for thread safety,
|
||||
// so editing a files set definition is a replacement operation.
|
||||
// Preserve the existing rules from the set being edited.
|
||||
rules.putAll(selectedSet.getRules());
|
||||
}
|
||||
this.replaceFilesSet(selectedSet, panel.getFilesSetName(), panel.getFilesSetDescription(), panel.getFileSetIgnoresKnownFiles(), rules);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display an interesting files set membership rule definition panel in a
|
||||
* dialog box and respond to user interactions with the dialog.
|
||||
*
|
||||
* @param selectedRule The currently selected rule, may be null to indicate
|
||||
* a new rule definition is to be created.
|
||||
*/
|
||||
private void doFilesSetRuleDialog(FilesSet.Rule selectedRule) {
|
||||
// Create a files set rule panel.
|
||||
FilesSetRulePanel panel;
|
||||
if (selectedRule != null) {
|
||||
// Editing an existing rule definition.
|
||||
panel = new FilesSetRulePanel(selectedRule);
|
||||
} else {
|
||||
// Creating a new rule definition.
|
||||
panel = new FilesSetRulePanel();
|
||||
}
|
||||
|
||||
// Do a dialog box with the files set panel until the user either enters
|
||||
// a valid definition or cancels. Note that the panel gives the user
|
||||
// feedback when isValidDefinition() is called.
|
||||
int option = JOptionPane.OK_OPTION;
|
||||
do {
|
||||
option = JOptionPane.showConfirmDialog(null, panel, NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
|
||||
} while (option == JOptionPane.OK_OPTION && !panel.isValidRuleDefinition());
|
||||
|
||||
if (option == JOptionPane.OK_OPTION) {
|
||||
// Interesting file sets are immutable for thread safety,
|
||||
// so editing a files set rule definition is a replacement
|
||||
// operation. Preserve the existing rules from the set being edited.
|
||||
FilesSet selectedSet = this.setsList.getSelectedValue();
|
||||
Map<String, FilesSet.Rule> rules = new HashMap<>(selectedSet.getRules());
|
||||
|
||||
// Remove the "old" rule definition and add the new/edited
|
||||
// definition.
|
||||
if (selectedRule != null) {
|
||||
rules.remove(selectedRule.getName());
|
||||
}
|
||||
FilesSet.Rule newRule = new FilesSet.Rule(panel.getRuleName(), panel.getFileNameFilter(), panel.getMetaTypeFilter(), panel.getPathFilter());
|
||||
rules.put(newRule.getName(), newRule);
|
||||
|
||||
// Add the new/edited files set definition, replacing any previous
|
||||
// definition with the same name and refreshing the display.
|
||||
this.replaceFilesSet(selectedSet, selectedSet.getName(), selectedSet.getDescription(), selectedSet.ignoresKnownFiles(), rules);
|
||||
|
||||
// Select the new/edited rule. Queue it up so it happens after the
|
||||
// selection listeners react to the selection of the "new" files
|
||||
// set.
|
||||
EventQueue.invokeLater(() -> {
|
||||
this.rulesList.setSelectedValue(newRule, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an interesting files set definition to the collection of definitions
|
||||
* owned by this panel. If there is a definition with the same name, it will
|
||||
* be replaced, so this is an add/edit operation.
|
||||
*
|
||||
* @param oldSet A set to replace, null if the new set is not a replacement.
|
||||
* @param name The name of the files set.
|
||||
* @param description The description of the files set.
|
||||
* @param ignoresKnownFiles Whether or not the files set ignores known
|
||||
* files.
|
||||
* @param rules The set membership rules for the set.
|
||||
*/
|
||||
void replaceFilesSet(FilesSet oldSet, String name, String description, boolean ignoresKnownFiles, Map<String, FilesSet.Rule> rules) {
|
||||
if (oldSet != null) {
|
||||
// Remove the set to be replaced from the working copy if the files
|
||||
// set definitions.
|
||||
this.filesSets.remove(oldSet.getName());
|
||||
}
|
||||
|
||||
// Make the new/edited set definition and add it to the working copy of
|
||||
// the files set definitions.
|
||||
FilesSet newSet = new FilesSet(name, description, ignoresKnownFiles, rules);
|
||||
this.filesSets.put(newSet.getName(), newSet);
|
||||
|
||||
// Redo the list model for the files set list component, which will make
|
||||
// everything stays sorted as in the working copy tree set.
|
||||
InterestingItemDefsPanel.this.setsListModel.clear();
|
||||
for (FilesSet set : this.filesSets.values()) {
|
||||
this.setsListModel.addElement(set);
|
||||
}
|
||||
|
||||
// Select the new/edited files set definition in the set definitions
|
||||
// list. This will cause the selection listeners to repopulate the
|
||||
// subordinate components.
|
||||
this.setsList.setSelectedValue(newSet, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
fileNameButtonGroup = new javax.swing.ButtonGroup();
|
||||
setsListLabel = new javax.swing.JLabel();
|
||||
rulesListLabel = new javax.swing.JLabel();
|
||||
setsListScrollPane = new javax.swing.JScrollPane();
|
||||
setsList = new javax.swing.JList<FilesSet>();
|
||||
rulesListScrollPane = new javax.swing.JScrollPane();
|
||||
rulesList = new javax.swing.JList<FilesSet.Rule>();
|
||||
selectedSetLabel = new javax.swing.JLabel();
|
||||
ignoreKnownFilesCheckbox = new javax.swing.JCheckBox();
|
||||
selectedRuleLabel = new javax.swing.JLabel();
|
||||
newSetButton = new javax.swing.JButton();
|
||||
editSetButton = new javax.swing.JButton();
|
||||
deleteSetButton = new javax.swing.JButton();
|
||||
newRuleButton = new javax.swing.JButton();
|
||||
editRuleButton = new javax.swing.JButton();
|
||||
deleteRuleButton = new javax.swing.JButton();
|
||||
separator = new javax.swing.JSeparator();
|
||||
setNameTextField = new javax.swing.JTextField();
|
||||
ruleNameTextField = new javax.swing.JTextField();
|
||||
fileNamePanel = new javax.swing.JPanel();
|
||||
fileNameRegexCheckbox = new javax.swing.JCheckBox();
|
||||
fileNameExtensionRadioButton = new javax.swing.JRadioButton();
|
||||
fileNameTextField = new javax.swing.JTextField();
|
||||
fileNameRadioButton = new javax.swing.JRadioButton();
|
||||
rulePathPanel = new javax.swing.JPanel();
|
||||
rulePathFilterRegexCheckBox = new javax.swing.JCheckBox();
|
||||
rulePathFilterTextField = new javax.swing.JTextField();
|
||||
setDescPanel = new javax.swing.JPanel();
|
||||
setDescScrollPanel = new javax.swing.JScrollPane();
|
||||
setDescriptionTextArea = new javax.swing.JTextArea();
|
||||
typePanel = new javax.swing.JPanel();
|
||||
filesRadioButton = new javax.swing.JRadioButton();
|
||||
dirsRadioButton = new javax.swing.JRadioButton();
|
||||
bothRadioButton = new javax.swing.JRadioButton();
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(setsListLabel, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.setsListLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(rulesListLabel, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.rulesListLabel.text")); // NOI18N
|
||||
|
||||
setsList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
setsListScrollPane.setViewportView(setsList);
|
||||
|
||||
rulesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
rulesListScrollPane.setViewportView(rulesList);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(selectedSetLabel, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.selectedSetLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(ignoreKnownFilesCheckbox, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.ignoreKnownFilesCheckbox.text")); // NOI18N
|
||||
ignoreKnownFilesCheckbox.setEnabled(false);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(selectedRuleLabel, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.selectedRuleLabel.text")); // NOI18N
|
||||
|
||||
newSetButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add16.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(newSetButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.newSetButton.text")); // NOI18N
|
||||
newSetButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
newSetButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
editSetButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/edit16.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(editSetButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.editSetButton.text")); // NOI18N
|
||||
editSetButton.setEnabled(false);
|
||||
editSetButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
editSetButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
deleteSetButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/delete16.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(deleteSetButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.deleteSetButton.text")); // NOI18N
|
||||
deleteSetButton.setEnabled(false);
|
||||
deleteSetButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
deleteSetButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
newRuleButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add16.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(newRuleButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.newRuleButton.text")); // NOI18N
|
||||
newRuleButton.setEnabled(false);
|
||||
newRuleButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
newRuleButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
editRuleButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/edit16.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(editRuleButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.editRuleButton.text")); // NOI18N
|
||||
editRuleButton.setEnabled(false);
|
||||
editRuleButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
editRuleButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
deleteRuleButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/delete16.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(deleteRuleButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.deleteRuleButton.text")); // NOI18N
|
||||
deleteRuleButton.setEnabled(false);
|
||||
deleteRuleButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
deleteRuleButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
separator.setOrientation(javax.swing.SwingConstants.VERTICAL);
|
||||
|
||||
setNameTextField.setEditable(false);
|
||||
|
||||
ruleNameTextField.setEditable(false);
|
||||
ruleNameTextField.setText(org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.ruleNameTextField.text")); // NOI18N
|
||||
|
||||
fileNamePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.fileNamePanel.border.title"))); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(fileNameRegexCheckbox, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.fileNameRegexCheckbox.text")); // NOI18N
|
||||
fileNameRegexCheckbox.setEnabled(false);
|
||||
|
||||
fileNameButtonGroup.add(fileNameExtensionRadioButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(fileNameExtensionRadioButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.fileNameExtensionRadioButton.text")); // NOI18N
|
||||
fileNameExtensionRadioButton.setEnabled(false);
|
||||
|
||||
fileNameTextField.setEditable(false);
|
||||
fileNameTextField.setText(org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.fileNameTextField.text")); // NOI18N
|
||||
|
||||
fileNameButtonGroup.add(fileNameRadioButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(fileNameRadioButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.fileNameRadioButton.text")); // NOI18N
|
||||
fileNameRadioButton.setEnabled(false);
|
||||
|
||||
javax.swing.GroupLayout fileNamePanelLayout = new javax.swing.GroupLayout(fileNamePanel);
|
||||
fileNamePanel.setLayout(fileNamePanelLayout);
|
||||
fileNamePanelLayout.setHorizontalGroup(
|
||||
fileNamePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(fileNamePanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(fileNamePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(fileNameTextField)
|
||||
.addGroup(fileNamePanelLayout.createSequentialGroup()
|
||||
.addComponent(fileNameRadioButton)
|
||||
.addGap(10, 10, 10)
|
||||
.addComponent(fileNameExtensionRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(fileNameRegexCheckbox)))
|
||||
.addContainerGap())
|
||||
);
|
||||
fileNamePanelLayout.setVerticalGroup(
|
||||
fileNamePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(fileNamePanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(fileNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(fileNamePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(fileNameRadioButton)
|
||||
.addComponent(fileNameExtensionRadioButton)
|
||||
.addComponent(fileNameRegexCheckbox))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
rulePathPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.rulePathPanel.border.title"))); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(rulePathFilterRegexCheckBox, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.rulePathFilterRegexCheckBox.text")); // NOI18N
|
||||
rulePathFilterRegexCheckBox.setEnabled(false);
|
||||
|
||||
rulePathFilterTextField.setEditable(false);
|
||||
rulePathFilterTextField.setText(org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.rulePathFilterTextField.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout rulePathPanelLayout = new javax.swing.GroupLayout(rulePathPanel);
|
||||
rulePathPanel.setLayout(rulePathPanelLayout);
|
||||
rulePathPanelLayout.setHorizontalGroup(
|
||||
rulePathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(rulePathPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(rulePathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(rulePathFilterRegexCheckBox)
|
||||
.addComponent(rulePathFilterTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 283, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
rulePathPanelLayout.setVerticalGroup(
|
||||
rulePathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(rulePathPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(rulePathFilterTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(rulePathFilterRegexCheckBox)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
setDescPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.setDescPanel.border.title"))); // NOI18N
|
||||
|
||||
setDescriptionTextArea.setEditable(false);
|
||||
setDescriptionTextArea.setColumns(20);
|
||||
setDescriptionTextArea.setRows(5);
|
||||
setDescScrollPanel.setViewportView(setDescriptionTextArea);
|
||||
|
||||
javax.swing.GroupLayout setDescPanelLayout = new javax.swing.GroupLayout(setDescPanel);
|
||||
setDescPanel.setLayout(setDescPanelLayout);
|
||||
setDescPanelLayout.setHorizontalGroup(
|
||||
setDescPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(setDescPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(setDescScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 296, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
setDescPanelLayout.setVerticalGroup(
|
||||
setDescPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, setDescPanelLayout.createSequentialGroup()
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(setDescScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
typePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.typePanel.border.title"))); // NOI18N
|
||||
|
||||
filesRadioButton.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(filesRadioButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.filesRadioButton.text")); // NOI18N
|
||||
filesRadioButton.setEnabled(false);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(dirsRadioButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.dirsRadioButton.text")); // NOI18N
|
||||
dirsRadioButton.setEnabled(false);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(bothRadioButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.bothRadioButton.text")); // NOI18N
|
||||
bothRadioButton.setEnabled(false);
|
||||
|
||||
javax.swing.GroupLayout typePanelLayout = new javax.swing.GroupLayout(typePanel);
|
||||
typePanel.setLayout(typePanelLayout);
|
||||
typePanelLayout.setHorizontalGroup(
|
||||
typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(typePanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(filesRadioButton)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(dirsRadioButton)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(bothRadioButton)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
typePanelLayout.setVerticalGroup(
|
||||
typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(typePanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(filesRadioButton)
|
||||
.addComponent(dirsRadioButton)
|
||||
.addComponent(bothRadioButton))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(newSetButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(editSetButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(deleteSetButton))
|
||||
.addComponent(setsListLabel)
|
||||
.addComponent(setsListScrollPane)
|
||||
.addComponent(ignoreKnownFilesCheckbox)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(selectedSetLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(setNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 208, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(setDescPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(separator, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(selectedRuleLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(ruleNameTextField))
|
||||
.addComponent(rulesListLabel)
|
||||
.addComponent(fileNamePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(rulePathPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(10, 10, 10)
|
||||
.addComponent(newRuleButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(editRuleButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(deleteRuleButton))
|
||||
.addComponent(rulesListScrollPane)
|
||||
.addComponent(typePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {deleteRuleButton, deleteSetButton, editRuleButton, editSetButton, newRuleButton, newSetButton});
|
||||
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(setsListLabel)
|
||||
.addComponent(rulesListLabel))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(setsListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 199, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(selectedSetLabel)
|
||||
.addComponent(setNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(setDescPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(ignoreKnownFilesCheckbox))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(rulesListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 122, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(selectedRuleLabel)
|
||||
.addComponent(ruleNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(16, 16, 16)
|
||||
.addComponent(typePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(fileNamePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(rulePathPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(deleteRuleButton)
|
||||
.addComponent(editRuleButton)
|
||||
.addComponent(newRuleButton)
|
||||
.addComponent(deleteSetButton)
|
||||
.addComponent(editSetButton)
|
||||
.addComponent(newSetButton)))
|
||||
.addComponent(separator, javax.swing.GroupLayout.PREFERRED_SIZE, 474, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {deleteRuleButton, deleteSetButton, editRuleButton, editSetButton, newRuleButton, newSetButton});
|
||||
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void newSetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newSetButtonActionPerformed
|
||||
this.doFileSetsDialog(null);
|
||||
}//GEN-LAST:event_newSetButtonActionPerformed
|
||||
|
||||
private void editSetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editSetButtonActionPerformed
|
||||
this.doFileSetsDialog(this.setsList.getSelectedValue());
|
||||
}//GEN-LAST:event_editSetButtonActionPerformed
|
||||
|
||||
private void newRuleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newRuleButtonActionPerformed
|
||||
this.doFilesSetRuleDialog(null);
|
||||
}//GEN-LAST:event_newRuleButtonActionPerformed
|
||||
|
||||
private void editRuleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editRuleButtonActionPerformed
|
||||
this.doFilesSetRuleDialog(this.rulesList.getSelectedValue());
|
||||
}//GEN-LAST:event_editRuleButtonActionPerformed
|
||||
|
||||
private void deleteSetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteSetButtonActionPerformed
|
||||
FilesSet selectedSet = this.setsList.getSelectedValue();
|
||||
this.filesSets.remove(selectedSet.getName());
|
||||
this.setsListModel.removeElement(selectedSet);
|
||||
|
||||
// Select the first of the remaining set definitions. This will cause
|
||||
// the selection listeners to repopulate the subordinate components.
|
||||
if (!this.filesSets.isEmpty()) {
|
||||
this.setsList.setSelectedIndex(0);
|
||||
} else {
|
||||
this.resetComponents();
|
||||
}
|
||||
}//GEN-LAST:event_deleteSetButtonActionPerformed
|
||||
|
||||
private void deleteRuleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteRuleButtonActionPerformed
|
||||
// Interesting file sets are immutable for thread safety,
|
||||
// so editing a files set rule definition is a replacement
|
||||
// operation. Preserve the existing rules from the set being
|
||||
// edited, except for the deleted rule.
|
||||
FilesSet oldSet = this.setsList.getSelectedValue();
|
||||
Map<String, FilesSet.Rule> rules = new HashMap<>(oldSet.getRules());
|
||||
FilesSet.Rule selectedRule = this.rulesList.getSelectedValue();
|
||||
rules.remove(selectedRule.getName());
|
||||
this.replaceFilesSet(oldSet, oldSet.getName(), oldSet.getDescription(), oldSet.ignoresKnownFiles(), rules);
|
||||
}//GEN-LAST:event_deleteRuleButtonActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JRadioButton bothRadioButton;
|
||||
private javax.swing.JButton deleteRuleButton;
|
||||
private javax.swing.JButton deleteSetButton;
|
||||
private javax.swing.JRadioButton dirsRadioButton;
|
||||
private javax.swing.JButton editRuleButton;
|
||||
private javax.swing.JButton editSetButton;
|
||||
private javax.swing.ButtonGroup fileNameButtonGroup;
|
||||
private javax.swing.JRadioButton fileNameExtensionRadioButton;
|
||||
private javax.swing.JPanel fileNamePanel;
|
||||
private javax.swing.JRadioButton fileNameRadioButton;
|
||||
private javax.swing.JCheckBox fileNameRegexCheckbox;
|
||||
private javax.swing.JTextField fileNameTextField;
|
||||
private javax.swing.JRadioButton filesRadioButton;
|
||||
private javax.swing.JCheckBox ignoreKnownFilesCheckbox;
|
||||
private javax.swing.JButton newRuleButton;
|
||||
private javax.swing.JButton newSetButton;
|
||||
private javax.swing.JTextField ruleNameTextField;
|
||||
private javax.swing.JCheckBox rulePathFilterRegexCheckBox;
|
||||
private javax.swing.JTextField rulePathFilterTextField;
|
||||
private javax.swing.JPanel rulePathPanel;
|
||||
private javax.swing.JList<FilesSet.Rule> rulesList;
|
||||
private javax.swing.JLabel rulesListLabel;
|
||||
private javax.swing.JScrollPane rulesListScrollPane;
|
||||
private javax.swing.JLabel selectedRuleLabel;
|
||||
private javax.swing.JLabel selectedSetLabel;
|
||||
private javax.swing.JSeparator separator;
|
||||
private javax.swing.JPanel setDescPanel;
|
||||
private javax.swing.JScrollPane setDescScrollPanel;
|
||||
private javax.swing.JTextArea setDescriptionTextArea;
|
||||
private javax.swing.JTextField setNameTextField;
|
||||
private javax.swing.JList<FilesSet> setsList;
|
||||
private javax.swing.JLabel setsListLabel;
|
||||
private javax.swing.JScrollPane setsListScrollPane;
|
||||
private javax.swing.JPanel typePanel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
}
|
||||
Executable
+110
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.modules.interestingitems;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.coreutils.Version;
|
||||
import org.sleuthkit.autopsy.ingest.FileIngestModule;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleFactory;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
|
||||
|
||||
/**
|
||||
* A factory that creates ingest modules that use interesting files set
|
||||
* definitions to identify files that may be of interest to the user.
|
||||
*/
|
||||
@ServiceProvider(service = IngestModuleFactory.class)
|
||||
final public class InterestingItemsIngestModuleFactory extends IngestModuleFactoryAdapter {
|
||||
|
||||
@Override
|
||||
public String getModuleDisplayName() {
|
||||
return getModuleName();
|
||||
}
|
||||
|
||||
static String getModuleName() {
|
||||
return NbBundle.getMessage(InterestingItemsIngestModuleFactory.class, "InterestingItemsIdentifierIngestModule.moduleName");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModuleDescription() {
|
||||
return NbBundle.getMessage(InterestingItemsIngestModuleFactory.class, "InterestingItemsIdentifierIngestModule.moduleDescription");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModuleVersionNumber() {
|
||||
return Version.getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasGlobalSettingsPanel() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IngestModuleGlobalSettingsPanel getGlobalSettingsPanel() {
|
||||
InterestingItemDefsPanel panel = new InterestingItemDefsPanel();
|
||||
panel.load();
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IngestModuleIngestJobSettings getDefaultIngestJobSettings() {
|
||||
// All interesting files set definitions are enabled by default. The
|
||||
// names of the set definitions are stored instead of the set
|
||||
// definitions to make per ingest job enabling and disabling of the
|
||||
// definitions independent of the rules that make up the defintions.
|
||||
// Doing so also keeps the serialization simple.
|
||||
List<String> enabledFilesSetNames = new ArrayList<>();
|
||||
for (String name : InterestingItemDefsManager.getInstance().getInterestingFilesSets().keySet()) {
|
||||
enabledFilesSetNames.add(name);
|
||||
}
|
||||
return new FilesIdentifierIngestJobSettings(enabledFilesSetNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasIngestJobSettingsPanel() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IngestModuleIngestJobSettingsPanel getIngestJobSettingsPanel(IngestModuleIngestJobSettings settings) {
|
||||
if (!(settings instanceof FilesIdentifierIngestJobSettings)) {
|
||||
throw new IllegalArgumentException("Settings not instanceof org.sleuthkit.autopsy.modules.interestingitems.InterestingItemsIngestJobSettings");
|
||||
}
|
||||
return FilesIdentifierIngestJobSettingsPanel.makePanel((FilesIdentifierIngestJobSettings) settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFileIngestModuleFactory() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) {
|
||||
if (!(settings instanceof FilesIdentifierIngestJobSettings)) {
|
||||
throw new IllegalArgumentException("Settings not instanceof org.sleuthkit.autopsy.modules.interestingitems.InterestingItemsIngestJobSettings");
|
||||
}
|
||||
return new FilesIdentifierIngestModule((FilesIdentifierIngestJobSettings) settings);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user