mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 07:56:16 +00:00
4114 resolve merge conflicts with develop
This commit is contained in:
commit
5f1ff9573a
@ -103,6 +103,11 @@
|
|||||||
<get src="https://drive.google.com/uc?id=1xv3Lz9m2QLq35ofDfHQNe9aHVtVzHUsj" dest="${test-input}/c2ds2_v1.vhd" skipexisting="true"/>
|
<get src="https://drive.google.com/uc?id=1xv3Lz9m2QLq35ofDfHQNe9aHVtVzHUsj" dest="${test-input}/c2ds2_v1.vhd" skipexisting="true"/>
|
||||||
<get src="https://drive.google.com/uc?id=1sg-znklB9yJAWq8i1cF2W-QLOM4FjZyv" dest="${test-input}/c3ds1_v1.vhd" skipexisting="true"/>
|
<get src="https://drive.google.com/uc?id=1sg-znklB9yJAWq8i1cF2W-QLOM4FjZyv" dest="${test-input}/c3ds1_v1.vhd" skipexisting="true"/>
|
||||||
<get src="https://drive.google.com/uc?id=1qXyaSlm3hMhv0jl6JkZEficknKjYNOlt" dest="${test-input}/c3ds2_v1.vhd" skipexisting="true"/>
|
<get src="https://drive.google.com/uc?id=1qXyaSlm3hMhv0jl6JkZEficknKjYNOlt" dest="${test-input}/c3ds2_v1.vhd" skipexisting="true"/>
|
||||||
|
<get src="https://drive.google.com/uc?id=1gW-SvduRwwoHmOheQypaRZ3ig-bezRre" dest="${test-input}/CommonFilesAttrs_img4_v1.vhd" skipexisting="true"/>
|
||||||
|
<get src="https://drive.google.com/uc?id=14vx83MZcd5PJadOesQz7tja-4a-Hz7eD" dest="${test-input}/CommonFilesAttrs_img3_v1.vhd" skipexisting="true"/>
|
||||||
|
<get src="https://drive.google.com/uc?id=1ZIYca4CWxyDcfF5Vf2uWkXeI83mR8L9B" dest="${test-input}/CommonFilesAttrs_img2_v1.vhd" skipexisting="true"/>
|
||||||
|
<get src="https://drive.google.com/uc?id=1RvLNhuKzqHURqeVml_o4lpv6jPCJJ9sv" dest="${test-input}/CommonFilesAttrs_img1_v1.vhd" skipexisting="true"/>
|
||||||
|
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="get-deps" depends="init-ivy,getTSKJars,get-thirdparty-dependencies,get-InternalPythonModules, download-binlist,getTestDataFiles">
|
<target name="get-deps" depends="init-ivy,getTSKJars,get-thirdparty-dependencies,get-InternalPythonModules, download-binlist,getTestDataFiles">
|
||||||
|
@ -7,12 +7,8 @@
|
|||||||
</configurations>
|
</configurations>
|
||||||
<dependencies >
|
<dependencies >
|
||||||
|
|
||||||
|
|
||||||
<dependency conf="core->default" org="com.github.jgraph" name="jgraphx" rev="v3.8.0"/>
|
<dependency conf="core->default" org="com.github.jgraph" name="jgraphx" rev="v3.8.0"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<dependency conf="core->default" org="org.apache.activemq" name="activemq-all" rev="5.11.1"/>
|
<dependency conf="core->default" org="org.apache.activemq" name="activemq-all" rev="5.11.1"/>
|
||||||
<dependency conf="core->default" org="org.apache.curator" name="curator-client" rev="2.8.0"/>
|
<dependency conf="core->default" org="org.apache.curator" name="curator-client" rev="2.8.0"/>
|
||||||
<dependency conf="core->default" org="org.apache.curator" name="curator-framework" rev="2.8.0"/>
|
<dependency conf="core->default" org="org.apache.curator" name="curator-framework" rev="2.8.0"/>
|
||||||
@ -27,6 +23,7 @@
|
|||||||
<dependency conf="core->default" org="com.adobe.xmp" name="xmpcore" rev="5.1.2"/>
|
<dependency conf="core->default" org="com.adobe.xmp" name="xmpcore" rev="5.1.2"/>
|
||||||
<dependency conf="core->default" org="org.apache.zookeeper" name="zookeeper" rev="3.4.6"/>
|
<dependency conf="core->default" org="org.apache.zookeeper" name="zookeeper" rev="3.4.6"/>
|
||||||
|
|
||||||
|
|
||||||
<dependency conf="core->default" org="org.apache.commons" name="commons-dbcp2" rev="2.1.1"/>
|
<dependency conf="core->default" org="org.apache.commons" name="commons-dbcp2" rev="2.1.1"/>
|
||||||
<dependency conf="core->default" org="org.apache.commons" name="commons-pool2" rev="2.4.2"/>
|
<dependency conf="core->default" org="org.apache.commons" name="commons-pool2" rev="2.4.2"/>
|
||||||
<dependency org="com.monitorjbl" name="xlsx-streamer" rev="1.2.1"/>
|
<dependency org="com.monitorjbl" name="xlsx-streamer" rev="1.2.1"/>
|
||||||
@ -34,5 +31,7 @@
|
|||||||
<dependency conf="core->default" org="org.jsoup" name="jsoup" rev="1.10.3"/>
|
<dependency conf="core->default" org="org.jsoup" name="jsoup" rev="1.10.3"/>
|
||||||
<dependency conf="core->default" org="com.googlecode.plist" name="dd-plist" rev="1.20"/>
|
<dependency conf="core->default" org="com.googlecode.plist" name="dd-plist" rev="1.20"/>
|
||||||
|
|
||||||
|
<dependency conf="core->default" org="commons-validator" name="commons-validator" rev="1.6"/>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</ivy-module>
|
</ivy-module>
|
||||||
|
@ -40,6 +40,7 @@ file.reference.xmpcore-5.1.3.jar=release/modules/ext/xmpcore-5.1.3.jar
|
|||||||
file.reference.xz-1.6.jar=release/modules/ext/xz-1.6.jar
|
file.reference.xz-1.6.jar=release/modules/ext/xz-1.6.jar
|
||||||
file.reference.zookeeper-3.4.6.jar=release/modules/ext/zookeeper-3.4.6.jar
|
file.reference.zookeeper-3.4.6.jar=release/modules/ext/zookeeper-3.4.6.jar
|
||||||
file.reference.SparseBitSet-1.1.jar=release/modules/ext/SparseBitSet-1.1.jar
|
file.reference.SparseBitSet-1.1.jar=release/modules/ext/SparseBitSet-1.1.jar
|
||||||
|
file.reference.commons-validator-1.6.jar=release/modules/ext/commons-validator-1.6.jar
|
||||||
javac.source=1.8
|
javac.source=1.8
|
||||||
javac.compilerargs=-Xlint -Xlint:-serial
|
javac.compilerargs=-Xlint -Xlint:-serial
|
||||||
license.file=../LICENSE-2.0.txt
|
license.file=../LICENSE-2.0.txt
|
||||||
|
@ -356,6 +356,10 @@
|
|||||||
<runtime-relative-path>ext/cxf-rt-transports-http-3.0.16.jar</runtime-relative-path>
|
<runtime-relative-path>ext/cxf-rt-transports-http-3.0.16.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/cxf-rt-transports-http-3.0.16.jar</binary-origin>
|
<binary-origin>release/modules/ext/cxf-rt-transports-http-3.0.16.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
|
<class-path-extension>
|
||||||
|
<runtime-relative-path>ext/commons-validator-1.6.jar</runtime-relative-path>
|
||||||
|
<binary-origin>release/modules/ext/commons-validator-1.6.jar</binary-origin>
|
||||||
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/curator-framework-2.8.0.jar</runtime-relative-path>
|
<runtime-relative-path>ext/curator-framework-2.8.0.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/curator-framework-2.8.0.jar</binary-origin>
|
<binary-origin>release/modules/ext/curator-framework-2.8.0.jar</binary-origin>
|
||||||
|
@ -77,7 +77,7 @@ import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
|||||||
import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.ReportAddedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.ReportAddedEvent;
|
||||||
import org.sleuthkit.autopsy.casemodule.services.Services;
|
import org.sleuthkit.autopsy.casemodule.services.Services;
|
||||||
import org.sleuthkit.autopsy.commonfilesearch.CommonFilesSearchAction;
|
import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchAction;
|
||||||
import org.sleuthkit.autopsy.communications.OpenCommVisualizationToolAction;
|
import org.sleuthkit.autopsy.communications.OpenCommVisualizationToolAction;
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CategoryNode;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CategoryNode;
|
||||||
@ -1093,7 +1093,7 @@ public class Case {
|
|||||||
CallableSystemAction.get(CaseDeleteAction.class).setEnabled(true);
|
CallableSystemAction.get(CaseDeleteAction.class).setEnabled(true);
|
||||||
CallableSystemAction.get(OpenTimelineAction.class).setEnabled(true);
|
CallableSystemAction.get(OpenTimelineAction.class).setEnabled(true);
|
||||||
CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(true);
|
CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(true);
|
||||||
CallableSystemAction.get(CommonFilesSearchAction.class).setEnabled(true);
|
CallableSystemAction.get(CommonAttributeSearchAction.class).setEnabled(true);
|
||||||
CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false);
|
CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1147,7 +1147,7 @@ public class Case {
|
|||||||
CallableSystemAction.get(OpenTimelineAction.class).setEnabled(false);
|
CallableSystemAction.get(OpenTimelineAction.class).setEnabled(false);
|
||||||
CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(false);
|
CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(false);
|
||||||
CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false);
|
CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false);
|
||||||
CallableSystemAction.get(CommonFilesSearchAction.class).setEnabled(false);
|
CallableSystemAction.get(CommonAttributeSearchAction.class).setEnabled(false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear the notifications in the notfier component in the lower
|
* Clear the notifications in the notfier component in the lower
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
<DimensionLayout dim="1">
|
<DimensionLayout dim="1">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="otherCasesPanel" pref="59" max="32767" attributes="0"/>
|
<Component id="otherCasesPanel" pref="58" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
</Layout>
|
</Layout>
|
||||||
@ -99,7 +99,7 @@
|
|||||||
<EmptySpace min="0" pref="483" max="32767" attributes="0"/>
|
<EmptySpace min="0" pref="483" max="32767" attributes="0"/>
|
||||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Component id="tableContainerPanel" pref="59" max="32767" attributes="0"/>
|
<Component id="tableContainerPanel" pref="58" max="32767" attributes="0"/>
|
||||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
|
@ -56,6 +56,7 @@ import org.openide.util.NbBundle.Messages;
|
|||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil;
|
||||||
@ -78,14 +79,14 @@ import org.sleuthkit.datamodel.TskData;
|
|||||||
* View correlation results from other cases
|
* View correlation results from other cases
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
||||||
@ServiceProvider(service = DataContentViewer.class, position = 8)
|
@ServiceProvider(service = DataContentViewer.class, position = 9)
|
||||||
@Messages({"DataContentViewerOtherCases.title=Other Occurrences",
|
@Messages({"DataContentViewerOtherCases.title=Other Occurrences",
|
||||||
"DataContentViewerOtherCases.toolTip=Displays instances of the selected file/artifact from other occurrences.",})
|
"DataContentViewerOtherCases.toolTip=Displays instances of the selected file/artifact from other occurrences.",})
|
||||||
public class DataContentViewerOtherCases extends JPanel implements DataContentViewer {
|
public class DataContentViewerOtherCases extends JPanel implements DataContentViewer {
|
||||||
|
|
||||||
private static final long serialVersionUID = -1L;
|
private static final long serialVersionUID = -1L;
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(DataContentViewerOtherCases.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(DataContentViewerOtherCases.class.getName());
|
||||||
|
|
||||||
private static final int DEFAULT_MIN_CELL_WIDTH = 15;
|
private static final int DEFAULT_MIN_CELL_WIDTH = 15;
|
||||||
private static final int CELL_TEXT_WIDTH_PADDING = 5;
|
private static final int CELL_TEXT_WIDTH_PADDING = 5;
|
||||||
@ -122,12 +123,11 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
try {
|
try {
|
||||||
saveToCSV();
|
saveToCSV();
|
||||||
} catch (NoCurrentCaseException ex) {
|
} catch (NoCurrentCaseException ex) {
|
||||||
logger.log(Level.SEVERE, "Exception while getting open case.", ex); // NON-NLS
|
LOGGER.log(Level.SEVERE, "Exception while getting open case.", ex); // NON-NLS
|
||||||
}
|
}
|
||||||
} else if (jmi.equals(showCommonalityMenuItem)) {
|
} else if (jmi.equals(showCommonalityMenuItem)) {
|
||||||
showCommonalityDetails();
|
showCommonalityDetails();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -165,17 +165,21 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
try {
|
try {
|
||||||
EamDb dbManager = EamDb.getInstance();
|
EamDb dbManager = EamDb.getInstance();
|
||||||
for (CorrelationAttributeInstance eamArtifact : correlationAttributes) {
|
for (CorrelationAttributeInstance eamArtifact : correlationAttributes) {
|
||||||
percentage = dbManager.getFrequencyPercentage(eamArtifact);
|
try {
|
||||||
msg.append(Bundle.DataContentViewerOtherCases_correlatedArtifacts_byType(percentage,
|
percentage = dbManager.getFrequencyPercentage(eamArtifact);
|
||||||
eamArtifact.getCorrelationType().getDisplayName(),
|
msg.append(Bundle.DataContentViewerOtherCases_correlatedArtifacts_byType(percentage,
|
||||||
eamArtifact.getCorrelationValue()));
|
eamArtifact.getCorrelationType().getDisplayName(),
|
||||||
|
eamArtifact.getCorrelationValue()));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
LOGGER.log(Level.WARNING, String.format("Error getting commonality details for artifact with ID: %s.", eamArtifact.getID()), ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
JOptionPane.showConfirmDialog(showCommonalityMenuItem,
|
JOptionPane.showConfirmDialog(showCommonalityMenuItem,
|
||||||
msg.toString(),
|
msg.toString(),
|
||||||
Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
|
Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
|
||||||
DEFAULT_OPTION, PLAIN_MESSAGE);
|
DEFAULT_OPTION, PLAIN_MESSAGE);
|
||||||
} catch (EamDbException ex) {
|
} catch (EamDbException ex) {
|
||||||
logger.log(Level.SEVERE, "Error getting commonality details.", ex);
|
LOGGER.log(Level.SEVERE, "Error getting commonality details.", ex);
|
||||||
JOptionPane.showConfirmDialog(showCommonalityMenuItem,
|
JOptionPane.showConfirmDialog(showCommonalityMenuItem,
|
||||||
Bundle.DataContentViewerOtherCases_correlatedArtifacts_failed(),
|
Bundle.DataContentViewerOtherCases_correlatedArtifacts_failed(),
|
||||||
Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
|
Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
|
||||||
@ -228,7 +232,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
DEFAULT_OPTION, PLAIN_MESSAGE);
|
DEFAULT_OPTION, PLAIN_MESSAGE);
|
||||||
}
|
}
|
||||||
} catch (EamDbException ex) {
|
} catch (EamDbException ex) {
|
||||||
logger.log(Level.SEVERE, "Error loading case details", ex);
|
LOGGER.log(Level.SEVERE, "Error loading case details", ex);
|
||||||
JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
|
JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
|
||||||
Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails(),
|
Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails(),
|
||||||
caseDisplayName,
|
caseDisplayName,
|
||||||
@ -291,7 +295,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.log(Level.SEVERE, "Error writing selected rows to CSV.", ex);
|
LOGGER.log(Level.SEVERE, "Error writing selected rows to CSV.", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,7 +387,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
try {
|
try {
|
||||||
content = nodeBbArtifact.getSleuthkitCase().getContentById(nodeBbArtifact.getObjectID());
|
content = nodeBbArtifact.getSleuthkitCase().getContentById(nodeBbArtifact.getObjectID());
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Error retrieving blackboard artifact", ex); // NON-NLS
|
LOGGER.log(Level.SEVERE, "Error retrieving blackboard artifact", ex); // NON-NLS
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,9 +417,9 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
if (bbArtifact != null && EamDb.isEnabled()) {
|
if (bbArtifact != null && EamDb.isEnabled()) {
|
||||||
ret.addAll(EamArtifactUtil.makeInstancesFromBlackboardArtifact(bbArtifact, false));
|
ret.addAll(EamArtifactUtil.makeInstancesFromBlackboardArtifact(bbArtifact, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
// we can correlate based on the MD5 if it is enabled
|
// we can correlate based on the MD5 if it is enabled
|
||||||
if (this.file != null && EamDb.isEnabled()) {
|
if (this.file != null && EamDb.isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
List<CorrelationAttributeInstance.Type> artifactTypes = EamDb.getInstance().getDefinedCorrelationTypes();
|
List<CorrelationAttributeInstance.Type> artifactTypes = EamDb.getInstance().getDefinedCorrelationTypes();
|
||||||
@ -424,33 +428,47 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
for (CorrelationAttributeInstance.Type aType : artifactTypes) {
|
for (CorrelationAttributeInstance.Type aType : artifactTypes) {
|
||||||
if (aType.getId() == CorrelationAttributeInstance.FILES_TYPE_ID) {
|
if (aType.getId() == CorrelationAttributeInstance.FILES_TYPE_ID) {
|
||||||
CorrelationCase corCase = EamDb.getInstance().getCase(Case.getCurrentCase());
|
CorrelationCase corCase = EamDb.getInstance().getCase(Case.getCurrentCase());
|
||||||
ret.add(new CorrelationAttributeInstance(
|
try {
|
||||||
md5,
|
ret.add(new CorrelationAttributeInstance(
|
||||||
aType,
|
md5,
|
||||||
corCase,
|
aType,
|
||||||
CorrelationDataSource.fromTSKDataSource(corCase, file.getDataSource()),
|
corCase,
|
||||||
file.getParentPath() + file.getName(),
|
CorrelationDataSource.fromTSKDataSource(corCase, file.getDataSource()),
|
||||||
"",
|
file.getParentPath() + file.getName(),
|
||||||
file.getKnown()));
|
"",
|
||||||
|
file.getKnown()));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
LOGGER.log(Level.INFO, String.format("Unable to check create CorrelationAttribtueInstance for value %s and type %s.", md5, aType.toString()), ex);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (EamDbException | TskCoreException ex) {
|
} catch (EamDbException | TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Error connecting to DB", ex); // NON-NLS
|
LOGGER.log(Level.SEVERE, "Error connecting to DB", ex); // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
try {
|
|
||||||
// If EamDb not enabled, get the Files default correlation type to allow Other Occurances to be enabled.
|
// If EamDb not enabled, get the Files default correlation type to allow Other Occurances to be enabled.
|
||||||
if (this.file != null) {
|
if (this.file != null) {
|
||||||
String md5 = this.file.getMd5Hash();
|
String md5 = this.file.getMd5Hash();
|
||||||
if (md5 != null && !md5.isEmpty()) {
|
if (md5 != null && !md5.isEmpty()) {
|
||||||
ret.add(new CorrelationAttributeInstance(CorrelationAttributeInstance.getDefaultCorrelationTypes().get(0), md5));
|
try {
|
||||||
|
final CorrelationAttributeInstance.Type fileAttributeType
|
||||||
|
= CorrelationAttributeInstance.getDefaultCorrelationTypes()
|
||||||
|
.stream()
|
||||||
|
.filter(attrType -> attrType.getId() == CorrelationAttributeInstance.FILES_TYPE_ID)
|
||||||
|
.findAny()
|
||||||
|
.get();
|
||||||
|
|
||||||
|
ret.add(new CorrelationAttributeInstance(fileAttributeType, md5));
|
||||||
|
} catch (EamDbException ex) {
|
||||||
|
LOGGER.log(Level.SEVERE, "Error connecting to DB", ex); // NON-NLS
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
LOGGER.log(Level.INFO, String.format("Unable to create CorrelationAttributeInstance for value %s", md5), ex); // NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (EamDbException ex) {
|
|
||||||
logger.log(Level.SEVERE, "Error connecting to DB", ex); // NON-NLS
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,9 +500,9 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (EamDbException ex) {
|
} catch (EamDbException ex) {
|
||||||
logger.log(Level.SEVERE, "Error getting list of cases from database.", ex); // NON-NLS
|
LOGGER.log(Level.SEVERE, "Error getting list of cases from database.", ex); // NON-NLS
|
||||||
} catch (ParseException ex) {
|
} catch (ParseException ex) {
|
||||||
logger.log(Level.SEVERE, "Error parsing date of cases from database.", ex); // NON-NLS
|
LOGGER.log(Level.SEVERE, "Error parsing date of cases from database.", ex); // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -497,9 +515,9 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
* artifact. If the central repo is not enabled, this will only return files
|
* artifact. If the central repo is not enabled, this will only return files
|
||||||
* from the current case with matching MD5 hashes.
|
* from the current case with matching MD5 hashes.
|
||||||
*
|
*
|
||||||
* @param corAttr CorrelationAttribute to query for
|
* @param corAttr CorrelationAttribute to query for
|
||||||
* @param dataSourceName Data source to filter results
|
* @param dataSourceName Data source to filter results
|
||||||
* @param deviceId Device Id to filter results
|
* @param deviceId Device Id to filter results
|
||||||
*
|
*
|
||||||
* @return A collection of correlated artifact instances
|
* @return A collection of correlated artifact instances
|
||||||
*/
|
*/
|
||||||
@ -544,13 +562,15 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
|
|
||||||
return nodeDataMap;
|
return nodeDataMap;
|
||||||
} catch (EamDbException ex) {
|
} catch (EamDbException ex) {
|
||||||
logger.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS
|
LOGGER.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
LOGGER.log(Level.INFO, "Error getting artifact instances from database.", ex); // NON-NLS
|
||||||
} catch (NoCurrentCaseException ex) {
|
} catch (NoCurrentCaseException ex) {
|
||||||
logger.log(Level.SEVERE, "Exception while getting open case.", ex); // NON-NLS
|
LOGGER.log(Level.SEVERE, "Exception while getting open case.", ex); // NON-NLS
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
// do nothing.
|
// do nothing.
|
||||||
// @@@ Review this behavior
|
// @@@ Review this behavior
|
||||||
logger.log(Level.SEVERE, "Exception while querying open case.", ex); // NON-NLS
|
LOGGER.log(Level.SEVERE, "Exception while querying open case.", ex); // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HashMap<>(0);
|
return new HashMap<>(0);
|
||||||
@ -560,7 +580,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
* Get all other abstract files in the current case with the same MD5 as the
|
* Get all other abstract files in the current case with the same MD5 as the
|
||||||
* selected node.
|
* selected node.
|
||||||
*
|
*
|
||||||
* @param corAttr The CorrelationAttribute containing the MD5 to search for
|
* @param corAttr The CorrelationAttribute containing the MD5 to search for
|
||||||
* @param openCase The current case
|
* @param openCase The current case
|
||||||
*
|
*
|
||||||
* @return List of matching AbstractFile objects
|
* @return List of matching AbstractFile objects
|
||||||
@ -694,7 +714,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
|
|
||||||
correlatedNodeDataMap.values().forEach((nodeData) -> {
|
correlatedNodeDataMap.values().forEach((nodeData) -> {
|
||||||
tableModel.addNodeData(nodeData);
|
tableModel.addNodeData(nodeData);
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -714,8 +733,8 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
* Adjust a given column for the text provided.
|
* Adjust a given column for the text provided.
|
||||||
*
|
*
|
||||||
* @param columnIndex The index of the column to adjust.
|
* @param columnIndex The index of the column to adjust.
|
||||||
* @param text The text whose length will be used to adjust the
|
* @param text The text whose length will be used to adjust the column
|
||||||
* column width.
|
* width.
|
||||||
*/
|
*/
|
||||||
private void setColumnWidthToText(int columnIndex, String text) {
|
private void setColumnWidthToText(int columnIndex, String text) {
|
||||||
TableColumn column = otherCasesTable.getColumnModel().getColumn(columnIndex);
|
TableColumn column = otherCasesTable.getColumnModel().getColumn(columnIndex);
|
||||||
@ -972,5 +991,4 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
return dataSourceID;
|
return dataSourceID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -652,7 +652,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
preparedStatement.setString(1, eamArtifact.getCorrelationCase().getCaseUUID());
|
preparedStatement.setString(1, eamArtifact.getCorrelationCase().getCaseUUID());
|
||||||
preparedStatement.setString(2, eamArtifact.getCorrelationDataSource().getDeviceID());
|
preparedStatement.setString(2, eamArtifact.getCorrelationDataSource().getDeviceID());
|
||||||
preparedStatement.setInt(3, eamArtifact.getCorrelationDataSource().getCaseID());
|
preparedStatement.setInt(3, eamArtifact.getCorrelationDataSource().getCaseID());
|
||||||
preparedStatement.setString(4, eamArtifact.getCorrelationValue().toLowerCase());
|
preparedStatement.setString(4, eamArtifact.getCorrelationValue());
|
||||||
preparedStatement.setString(5, eamArtifact.getFilePath().toLowerCase());
|
preparedStatement.setString(5, eamArtifact.getFilePath().toLowerCase());
|
||||||
preparedStatement.setByte(6, eamArtifact.getKnownStatus().getFileKnownValue());
|
preparedStatement.setByte(6, eamArtifact.getKnownStatus().getFileKnownValue());
|
||||||
if ("".equals(eamArtifact.getComment())) {
|
if ("".equals(eamArtifact.getComment())) {
|
||||||
@ -712,10 +712,10 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException {
|
public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
if (aType == null) {
|
|
||||||
throw new EamDbException("Correlation type is null");
|
String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
|
||||||
}
|
|
||||||
Connection conn = connect();
|
Connection conn = connect();
|
||||||
|
|
||||||
List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
|
List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
|
||||||
@ -743,7 +743,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
preparedStatement = conn.prepareStatement(sql);
|
preparedStatement = conn.prepareStatement(sql);
|
||||||
preparedStatement.setString(1, value);
|
preparedStatement.setString(1, normalizedValue);
|
||||||
resultSet = preparedStatement.executeQuery();
|
resultSet = preparedStatement.executeQuery();
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
|
artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
|
||||||
@ -809,8 +809,12 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
preparedStatement.setString(1, filePath.toLowerCase());
|
preparedStatement.setString(1, filePath.toLowerCase());
|
||||||
resultSet = preparedStatement.executeQuery();
|
resultSet = preparedStatement.executeQuery();
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
|
try {
|
||||||
artifactInstances.add(artifactInstance);
|
artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
|
||||||
|
artifactInstances.add(artifactInstance);
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
logger.log(Level.INFO, "Unable to get artifact instance from resultset.", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS
|
throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS
|
||||||
@ -834,13 +838,8 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
* ArtifactValue.
|
* ArtifactValue.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Long getCountArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException {
|
public Long getCountArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
if (aType == null) {
|
String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
|
||||||
throw new EamDbException("Correlation type is null");
|
|
||||||
}
|
|
||||||
if (value == null) {
|
|
||||||
throw new EamDbException("Correlation value is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
Connection conn = connect();
|
Connection conn = connect();
|
||||||
|
|
||||||
@ -856,7 +855,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
preparedStatement = conn.prepareStatement(sql);
|
preparedStatement = conn.prepareStatement(sql);
|
||||||
preparedStatement.setString(1, value.toLowerCase());
|
preparedStatement.setString(1, normalizedValue);
|
||||||
resultSet = preparedStatement.executeQuery();
|
resultSet = preparedStatement.executeQuery();
|
||||||
resultSet.next();
|
resultSet.next();
|
||||||
instanceCount = resultSet.getLong(1);
|
instanceCount = resultSet.getLong(1);
|
||||||
@ -872,7 +871,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getFrequencyPercentage(CorrelationAttributeInstance corAttr) throws EamDbException {
|
public int getFrequencyPercentage(CorrelationAttributeInstance corAttr) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
if (corAttr == null) {
|
if (corAttr == null) {
|
||||||
throw new EamDbException("CorrelationAttribute is null");
|
throw new EamDbException("CorrelationAttribute is null");
|
||||||
}
|
}
|
||||||
@ -893,10 +892,8 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
* @return Number of unique tuples
|
* @return Number of unique tuples
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException {
|
public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
if (aType == null) {
|
String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
|
||||||
throw new EamDbException("Correlation type is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
Connection conn = connect();
|
Connection conn = connect();
|
||||||
|
|
||||||
@ -914,7 +911,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
preparedStatement = conn.prepareStatement(sql);
|
preparedStatement = conn.prepareStatement(sql);
|
||||||
preparedStatement.setString(1, value);
|
preparedStatement.setString(1, normalizedValue);
|
||||||
resultSet = preparedStatement.executeQuery();
|
resultSet = preparedStatement.executeQuery();
|
||||||
resultSet.next();
|
resultSet.next();
|
||||||
instanceCount = resultSet.getLong(1);
|
instanceCount = resultSet.getLong(1);
|
||||||
@ -1262,7 +1259,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
preparedQuery.setString(1, eamArtifact.getComment());
|
preparedQuery.setString(1, eamArtifact.getComment());
|
||||||
preparedQuery.setString(2, eamArtifact.getCorrelationCase().getCaseUUID());
|
preparedQuery.setString(2, eamArtifact.getCorrelationCase().getCaseUUID());
|
||||||
preparedQuery.setString(3, eamArtifact.getCorrelationDataSource().getDeviceID());
|
preparedQuery.setString(3, eamArtifact.getCorrelationDataSource().getDeviceID());
|
||||||
preparedQuery.setString(4, eamArtifact.getCorrelationValue().toLowerCase());
|
preparedQuery.setString(4, eamArtifact.getCorrelationValue());
|
||||||
preparedQuery.setString(5, eamArtifact.getFilePath().toLowerCase());
|
preparedQuery.setString(5, eamArtifact.getFilePath().toLowerCase());
|
||||||
preparedQuery.executeUpdate();
|
preparedQuery.executeUpdate();
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
@ -1289,20 +1286,14 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase,
|
public CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase,
|
||||||
CorrelationDataSource correlationDataSource, String value, String filePath) throws EamDbException {
|
CorrelationDataSource correlationDataSource, String value, String filePath) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
|
|
||||||
if (type == null) {
|
|
||||||
throw new EamDbException("Correlation type is null");
|
|
||||||
}
|
|
||||||
if (correlationCase == null) {
|
if (correlationCase == null) {
|
||||||
throw new EamDbException("Correlation case is null");
|
throw new EamDbException("Correlation case is null");
|
||||||
}
|
}
|
||||||
if (correlationDataSource == null) {
|
if (correlationDataSource == null) {
|
||||||
throw new EamDbException("Correlation data source is null");
|
throw new EamDbException("Correlation data source is null");
|
||||||
}
|
}
|
||||||
if (value == null) {
|
|
||||||
throw new EamDbException("Correlation value is null");
|
|
||||||
}
|
|
||||||
if (filePath == null) {
|
if (filePath == null) {
|
||||||
throw new EamDbException("Correlation file path is null");
|
throw new EamDbException("Correlation file path is null");
|
||||||
}
|
}
|
||||||
@ -1314,6 +1305,8 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
CorrelationAttributeInstance correlationAttributeInstance = null;
|
CorrelationAttributeInstance correlationAttributeInstance = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
String normalizedValue = CorrelationAttributeNormalizer.normalize(type, value);
|
||||||
|
|
||||||
String tableName = EamDbUtil.correlationTypeToInstanceTableName(type);
|
String tableName = EamDbUtil.correlationTypeToInstanceTableName(type);
|
||||||
String sql
|
String sql
|
||||||
= "SELECT id, known_status, comment FROM "
|
= "SELECT id, known_status, comment FROM "
|
||||||
@ -1326,7 +1319,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
preparedStatement = conn.prepareStatement(sql);
|
preparedStatement = conn.prepareStatement(sql);
|
||||||
preparedStatement.setInt(1, correlationCase.getID());
|
preparedStatement.setInt(1, correlationCase.getID());
|
||||||
preparedStatement.setInt(2, correlationDataSource.getID());
|
preparedStatement.setInt(2, correlationDataSource.getID());
|
||||||
preparedStatement.setString(3, value.toLowerCase());
|
preparedStatement.setString(3, normalizedValue);
|
||||||
preparedStatement.setString(4, filePath.toLowerCase());
|
preparedStatement.setString(4, filePath.toLowerCase());
|
||||||
resultSet = preparedStatement.executeQuery();
|
resultSet = preparedStatement.executeQuery();
|
||||||
if (resultSet.next()) {
|
if (resultSet.next()) {
|
||||||
@ -1457,10 +1450,8 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
* @return List with 0 or more matching eamArtifact instances.
|
* @return List with 0 or more matching eamArtifact instances.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException {
|
public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
if (aType == null) {
|
String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
|
||||||
throw new EamDbException("Correlation type is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
Connection conn = connect();
|
Connection conn = connect();
|
||||||
|
|
||||||
@ -1489,7 +1480,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
preparedStatement = conn.prepareStatement(sql);
|
preparedStatement = conn.prepareStatement(sql);
|
||||||
preparedStatement.setString(1, value);
|
preparedStatement.setString(1, normalizedValue);
|
||||||
preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
|
preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
|
||||||
resultSet = preparedStatement.executeQuery();
|
resultSet = preparedStatement.executeQuery();
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
@ -1552,8 +1543,12 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
preparedStatement.setByte(1, TskData.FileKnown.BAD.getFileKnownValue());
|
preparedStatement.setByte(1, TskData.FileKnown.BAD.getFileKnownValue());
|
||||||
resultSet = preparedStatement.executeQuery();
|
resultSet = preparedStatement.executeQuery();
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
|
try {
|
||||||
artifactInstances.add(artifactInstance);
|
artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
|
||||||
|
artifactInstances.add(artifactInstance);
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
logger.log(Level.INFO, "Unable to get artifact instance from resultset.", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
throw new EamDbException("Error getting notable artifact instances.", ex); // NON-NLS
|
throw new EamDbException("Error getting notable artifact instances.", ex); // NON-NLS
|
||||||
@ -1575,10 +1570,9 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
* @return Number of matching eamArtifacts
|
* @return Number of matching eamArtifacts
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Long getCountArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException {
|
public Long getCountArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
if (aType == null) {
|
|
||||||
throw new EamDbException("Correlation type is null");
|
String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
|
||||||
}
|
|
||||||
|
|
||||||
Connection conn = connect();
|
Connection conn = connect();
|
||||||
|
|
||||||
@ -1594,7 +1588,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
preparedStatement = conn.prepareStatement(sql);
|
preparedStatement = conn.prepareStatement(sql);
|
||||||
preparedStatement.setString(1, value);
|
preparedStatement.setString(1, normalizedValue);
|
||||||
preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
|
preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
|
||||||
resultSet = preparedStatement.executeQuery();
|
resultSet = preparedStatement.executeQuery();
|
||||||
resultSet.next();
|
resultSet.next();
|
||||||
@ -1623,10 +1617,9 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException {
|
public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
if (aType == null) {
|
|
||||||
throw new EamDbException("Correlation type is null");
|
String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
|
||||||
}
|
|
||||||
|
|
||||||
Connection conn = connect();
|
Connection conn = connect();
|
||||||
|
|
||||||
@ -1649,7 +1642,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
preparedStatement = conn.prepareStatement(sql);
|
preparedStatement = conn.prepareStatement(sql);
|
||||||
preparedStatement.setString(1, value);
|
preparedStatement.setString(1, normalizedValue);
|
||||||
preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
|
preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
|
||||||
resultSet = preparedStatement.executeQuery();
|
resultSet = preparedStatement.executeQuery();
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
@ -1768,7 +1761,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isFileHashInReferenceSet(String hash, int referenceSetID) throws EamDbException {
|
public boolean isFileHashInReferenceSet(String hash, int referenceSetID) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
return isValueInReferenceSet(hash, referenceSetID, CorrelationAttributeInstance.FILES_TYPE_ID);
|
return isValueInReferenceSet(hash, referenceSetID, CorrelationAttributeInstance.FILES_TYPE_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1782,8 +1775,10 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
* @return true if the value is found in the reference set
|
* @return true if the value is found in the reference set
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException {
|
public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
|
|
||||||
|
String normalizeValued = CorrelationAttributeNormalizer.normalize(this.getCorrelationTypeById(correlationTypeID), value);
|
||||||
|
|
||||||
Connection conn = connect();
|
Connection conn = connect();
|
||||||
|
|
||||||
Long matchingInstances = 0L;
|
Long matchingInstances = 0L;
|
||||||
@ -1795,13 +1790,13 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
|
preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
|
||||||
preparedStatement.setString(1, value);
|
preparedStatement.setString(1, normalizeValued);
|
||||||
preparedStatement.setInt(2, referenceSetID);
|
preparedStatement.setInt(2, referenceSetID);
|
||||||
resultSet = preparedStatement.executeQuery();
|
resultSet = preparedStatement.executeQuery();
|
||||||
resultSet.next();
|
resultSet.next();
|
||||||
matchingInstances = resultSet.getLong(1);
|
matchingInstances = resultSet.getLong(1);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
throw new EamDbException("Error determining if value (" + value + ") is in reference set " + referenceSetID, ex); // NON-NLS
|
throw new EamDbException("Error determining if value (" + normalizeValued + ") is in reference set " + referenceSetID, ex); // NON-NLS
|
||||||
} finally {
|
} finally {
|
||||||
EamDbUtil.closeStatement(preparedStatement);
|
EamDbUtil.closeStatement(preparedStatement);
|
||||||
EamDbUtil.closeResultSet(resultSet);
|
EamDbUtil.closeResultSet(resultSet);
|
||||||
@ -1820,11 +1815,11 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
* @return Global known status of the artifact
|
* @return Global known status of the artifact
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isArtifactKnownBadByReference(CorrelationAttributeInstance.Type aType, String value) throws EamDbException {
|
public boolean isArtifactKnownBadByReference(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
if (aType == null) {
|
|
||||||
throw new EamDbException("Correlation type is null");
|
//this should be done here so that we can be certain that aType and value are valid before we proceed
|
||||||
}
|
String normalizeValued = CorrelationAttributeNormalizer.normalize(aType, value);
|
||||||
|
|
||||||
// TEMP: Only support file correlation type
|
// TEMP: Only support file correlation type
|
||||||
if (aType.getId() != CorrelationAttributeInstance.FILES_TYPE_ID) {
|
if (aType.getId() != CorrelationAttributeInstance.FILES_TYPE_ID) {
|
||||||
return false;
|
return false;
|
||||||
@ -1837,9 +1832,9 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
ResultSet resultSet = null;
|
ResultSet resultSet = null;
|
||||||
String sql = "SELECT count(*) FROM %s WHERE value=? AND known_status=?";
|
String sql = "SELECT count(*) FROM %s WHERE value=? AND known_status=?";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
preparedStatement = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(aType)));
|
preparedStatement = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(aType)));
|
||||||
preparedStatement.setString(1, value);
|
preparedStatement.setString(1, normalizeValued);
|
||||||
preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
|
preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
|
||||||
resultSet = preparedStatement.executeQuery();
|
resultSet = preparedStatement.executeQuery();
|
||||||
resultSet.next();
|
resultSet.next();
|
||||||
@ -2420,10 +2415,8 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String aValue) throws EamDbException {
|
public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String aValue) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
if (aType == null) {
|
String normalizeValued = CorrelationAttributeNormalizer.normalize(aType, aValue);
|
||||||
throw new EamDbException("Correlation type is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
Connection conn = connect();
|
Connection conn = connect();
|
||||||
|
|
||||||
@ -2434,12 +2427,11 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
preparedStatement1 = conn.prepareStatement(String.format(sql1, EamDbUtil.correlationTypeToReferenceTableName(aType)));
|
preparedStatement1 = conn.prepareStatement(String.format(sql1, EamDbUtil.correlationTypeToReferenceTableName(aType)));
|
||||||
preparedStatement1.setString(1, aValue);
|
preparedStatement1.setString(1, normalizeValued);
|
||||||
resultSet = preparedStatement1.executeQuery();
|
resultSet = preparedStatement1.executeQuery();
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
globalFileInstances.add(getEamGlobalFileInstanceFromResultSet(resultSet));
|
globalFileInstances.add(getEamGlobalFileInstanceFromResultSet(resultSet));
|
||||||
}
|
}
|
||||||
return globalFileInstances;
|
|
||||||
|
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
throw new EamDbException("Error getting reference instances by type and value.", ex); // NON-NLS
|
throw new EamDbException("Error getting reference instances by type and value.", ex); // NON-NLS
|
||||||
@ -2448,6 +2440,8 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
EamDbUtil.closeResultSet(resultSet);
|
EamDbUtil.closeResultSet(resultSet);
|
||||||
EamDbUtil.closeConnection(conn);
|
EamDbUtil.closeConnection(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return globalFileInstances;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2828,7 +2822,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
*
|
*
|
||||||
* @throws SQLException when an expected column name is not in the resultSet
|
* @throws SQLException when an expected column name is not in the resultSet
|
||||||
*/
|
*/
|
||||||
private CorrelationAttributeInstance getEamArtifactInstanceFromResultSet(ResultSet resultSet, CorrelationAttributeInstance.Type aType) throws SQLException, EamDbException {
|
private CorrelationAttributeInstance getEamArtifactInstanceFromResultSet(ResultSet resultSet, CorrelationAttributeInstance.Type aType) throws SQLException, EamDbException, CorrelationAttributeNormalizationException {
|
||||||
if (null == resultSet) {
|
if (null == resultSet) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -2876,7 +2870,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private EamGlobalFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet) throws SQLException, EamDbException {
|
private EamGlobalFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet) throws SQLException, EamDbException, CorrelationAttributeNormalizationException {
|
||||||
if (null == resultSet) {
|
if (null == resultSet) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ public class CorrelationAttributeInstance implements Serializable {
|
|||||||
CorrelationCase eamCase,
|
CorrelationCase eamCase,
|
||||||
CorrelationDataSource eamDataSource,
|
CorrelationDataSource eamDataSource,
|
||||||
String filePath
|
String filePath
|
||||||
) throws EamDbException {
|
) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
this(correlationType, correlationValue, -1, eamCase, eamDataSource, filePath, null, TskData.FileKnown.UNKNOWN);
|
this(correlationType, correlationValue, -1, eamCase, eamDataSource, filePath, null, TskData.FileKnown.UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ public class CorrelationAttributeInstance implements Serializable {
|
|||||||
String filePath,
|
String filePath,
|
||||||
String comment,
|
String comment,
|
||||||
TskData.FileKnown knownStatus
|
TskData.FileKnown knownStatus
|
||||||
) throws EamDbException {
|
) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
this(correlationType, correlationValue, -1, eamCase, eamDataSource, filePath, comment, knownStatus);
|
this(correlationType, correlationValue, -1, eamCase, eamDataSource, filePath, comment, knownStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ public class CorrelationAttributeInstance implements Serializable {
|
|||||||
String correlationValue,
|
String correlationValue,
|
||||||
CorrelationCase correlationCase,
|
CorrelationCase correlationCase,
|
||||||
CorrelationDataSource fromTSKDataSource,
|
CorrelationDataSource fromTSKDataSource,
|
||||||
String string) throws EamDbException {
|
String string) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
this(correlationType, correlationValue, -1, correlationCase, fromTSKDataSource, string, "", TskData.FileKnown.UNKNOWN);
|
this(correlationType, correlationValue, -1, correlationCase, fromTSKDataSource, string, "", TskData.FileKnown.UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ public class CorrelationAttributeInstance implements Serializable {
|
|||||||
* @param aType CorrelationAttributeInstance.Type
|
* @param aType CorrelationAttributeInstance.Type
|
||||||
* @param value correlation value
|
* @param value correlation value
|
||||||
*/
|
*/
|
||||||
public CorrelationAttributeInstance(Type aType, String value) throws EamDbException {
|
public CorrelationAttributeInstance(Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
this(aType, value, -1, null, null, "", "", TskData.FileKnown.UNKNOWN);
|
this(aType, value, -1, null, null, "", "", TskData.FileKnown.UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,17 +99,13 @@ public class CorrelationAttributeInstance implements Serializable {
|
|||||||
String filePath,
|
String filePath,
|
||||||
String comment,
|
String comment,
|
||||||
TskData.FileKnown knownStatus
|
TskData.FileKnown knownStatus
|
||||||
) throws EamDbException {
|
) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
if (filePath == null) {
|
if (filePath == null) {
|
||||||
throw new EamDbException("file path is null");
|
throw new EamDbException("file path is null");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value == null) {
|
|
||||||
throw new EamDbException("correlation value is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.correlationType = type;
|
this.correlationType = type;
|
||||||
this.correlationValue = value;
|
this.correlationValue = CorrelationAttributeNormalizer.normalize(type, value);
|
||||||
this.ID = instanceId;
|
this.ID = instanceId;
|
||||||
this.correlationCase = eamCase;
|
this.correlationCase = eamCase;
|
||||||
this.correlationDataSource = eamDataSource;
|
this.correlationDataSource = eamDataSource;
|
||||||
@ -121,6 +117,8 @@ public class CorrelationAttributeInstance implements Serializable {
|
|||||||
|
|
||||||
public Boolean equals(CorrelationAttributeInstance otherInstance) {
|
public Boolean equals(CorrelationAttributeInstance otherInstance) {
|
||||||
return ((this.getID() == otherInstance.getID())
|
return ((this.getID() == otherInstance.getID())
|
||||||
|
&& (this.getCorrelationValue().equals(otherInstance.getCorrelationValue()))
|
||||||
|
&& (this.getCorrelationType().equals(otherInstance.getCorrelationType()))
|
||||||
&& (this.getCorrelationCase().equals(otherInstance.getCorrelationCase()))
|
&& (this.getCorrelationCase().equals(otherInstance.getCorrelationCase()))
|
||||||
&& (this.getCorrelationDataSource().equals(otherInstance.getCorrelationDataSource()))
|
&& (this.getCorrelationDataSource().equals(otherInstance.getCorrelationDataSource()))
|
||||||
&& (this.getFilePath().equals(otherInstance.getFilePath()))
|
&& (this.getFilePath().equals(otherInstance.getFilePath()))
|
||||||
@ -134,6 +132,8 @@ public class CorrelationAttributeInstance implements Serializable {
|
|||||||
+ this.getCorrelationCase().getCaseUUID()
|
+ this.getCorrelationCase().getCaseUUID()
|
||||||
+ this.getCorrelationDataSource().getDeviceID()
|
+ this.getCorrelationDataSource().getDeviceID()
|
||||||
+ this.getFilePath()
|
+ this.getFilePath()
|
||||||
|
+ this.getCorrelationType().toString()
|
||||||
|
+ this.getCorrelationValue()
|
||||||
+ this.getKnownStatus()
|
+ this.getKnownStatus()
|
||||||
+ this.getComment();
|
+ this.getComment();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2018 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.centralrepository.datamodel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when a given value is not in the expected format.
|
||||||
|
*/
|
||||||
|
public class CorrelationAttributeNormalizationException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct an exception with the given message.
|
||||||
|
* @param message error message
|
||||||
|
*/
|
||||||
|
public CorrelationAttributeNormalizationException(String message){
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct an exception with the given message and inner exception.
|
||||||
|
* @param message error message
|
||||||
|
* @param cause inner exception
|
||||||
|
*/
|
||||||
|
public CorrelationAttributeNormalizationException(String message, Throwable cause){
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct an exception with the given inner exception.
|
||||||
|
* @param cause inner exception
|
||||||
|
*/
|
||||||
|
public CorrelationAttributeNormalizationException(Throwable cause){
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2018 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.centralrepository.datamodel;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.apache.commons.validator.routines.DomainValidator;
|
||||||
|
import org.apache.commons.validator.routines.EmailValidator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides functions for normalizing data by attribute type before insertion or querying.
|
||||||
|
*/
|
||||||
|
final public class CorrelationAttributeNormalizer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a utility class - no need for constructing or subclassing, etc...
|
||||||
|
*/
|
||||||
|
private CorrelationAttributeNormalizer() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize the data. Converts text to lower case, and ensures that the
|
||||||
|
* data is a valid string of the format expected given the attributeType.
|
||||||
|
*
|
||||||
|
* @param attributeType correlation type of data
|
||||||
|
* @param data data to normalize
|
||||||
|
*
|
||||||
|
* @return normalized data
|
||||||
|
*/
|
||||||
|
public static String normalize(CorrelationAttributeInstance.Type attributeType, String data) throws CorrelationAttributeNormalizationException {
|
||||||
|
|
||||||
|
if(attributeType == null){
|
||||||
|
throw new CorrelationAttributeNormalizationException("Attribute type was null.");
|
||||||
|
}
|
||||||
|
if(data == null){
|
||||||
|
throw new CorrelationAttributeNormalizationException("Data was null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(attributeType.getId()){
|
||||||
|
case CorrelationAttributeInstance.FILES_TYPE_ID:
|
||||||
|
return normalizeMd5(data);
|
||||||
|
case CorrelationAttributeInstance.DOMAIN_TYPE_ID:
|
||||||
|
return normalizeDomain(data);
|
||||||
|
case CorrelationAttributeInstance.EMAIL_TYPE_ID:
|
||||||
|
return normalizeEmail(data);
|
||||||
|
case CorrelationAttributeInstance.PHONE_TYPE_ID:
|
||||||
|
return normalizePhone(data);
|
||||||
|
case CorrelationAttributeInstance.USBID_TYPE_ID:
|
||||||
|
return normalizeUsbId(data);
|
||||||
|
default:
|
||||||
|
final String errorMessage = String.format(
|
||||||
|
"Validator function not found for attribute type: %s",
|
||||||
|
attributeType.getDisplayName());
|
||||||
|
throw new CorrelationAttributeNormalizationException(errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the data. Converts text to lower case, and ensures that the
|
||||||
|
* data is a valid string of the format expected given the attributeType.
|
||||||
|
*
|
||||||
|
* @param attributeTypeId correlation type of data
|
||||||
|
* @param data data to normalize
|
||||||
|
*
|
||||||
|
* @return normalized data
|
||||||
|
*/
|
||||||
|
public static String normalize(int attributeTypeId, String data) throws CorrelationAttributeNormalizationException {
|
||||||
|
try {
|
||||||
|
List<CorrelationAttributeInstance.Type> defaultTypes = CorrelationAttributeInstance.getDefaultCorrelationTypes();
|
||||||
|
Optional<CorrelationAttributeInstance.Type> typeOption = defaultTypes.stream().filter(attributeType -> attributeType.getId() == attributeTypeId).findAny();
|
||||||
|
|
||||||
|
if(typeOption.isPresent()){
|
||||||
|
CorrelationAttributeInstance.Type type = typeOption.get();
|
||||||
|
return CorrelationAttributeNormalizer.normalize(type, data);
|
||||||
|
} else {
|
||||||
|
throw new CorrelationAttributeNormalizationException(String.format("Given attributeTypeId did not correspond to any known Attribute: %s", attributeTypeId));
|
||||||
|
}
|
||||||
|
} catch (EamDbException ex) {
|
||||||
|
throw new CorrelationAttributeNormalizationException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify MD5 is the correct length and values. Make lower case.
|
||||||
|
*/
|
||||||
|
private static String normalizeMd5(String data) throws CorrelationAttributeNormalizationException {
|
||||||
|
final String validMd5Regex = "^[a-f0-9]{32}$";
|
||||||
|
final String dataLowered = data.toLowerCase();
|
||||||
|
if(dataLowered.matches(validMd5Regex)){
|
||||||
|
return dataLowered;
|
||||||
|
} else {
|
||||||
|
throw new CorrelationAttributeNormalizationException(String.format("Data purporting to be an MD5 was found not to comform to expected format: %s", data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify there are no slashes or invalid domain name characters (such as '?' or \: ). Normalize to lower case.
|
||||||
|
*/
|
||||||
|
private static String normalizeDomain(String data) throws CorrelationAttributeNormalizationException {
|
||||||
|
DomainValidator validator = DomainValidator.getInstance(true);
|
||||||
|
if(validator.isValid(data)){
|
||||||
|
return data.toLowerCase();
|
||||||
|
} else {
|
||||||
|
final String validIpAddressRegex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$";
|
||||||
|
if(data.matches(validIpAddressRegex)){
|
||||||
|
return data;
|
||||||
|
} else {
|
||||||
|
throw new CorrelationAttributeNormalizationException(String.format("Data was expected to be a valid domain: %s", data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that there is an '@' and no invalid characters. Should normalize to lower case.
|
||||||
|
*/
|
||||||
|
private static String normalizeEmail(String data) throws CorrelationAttributeNormalizationException {
|
||||||
|
EmailValidator validator = EmailValidator.getInstance(true, true);
|
||||||
|
if(validator.isValid(data)){
|
||||||
|
return data.toLowerCase();
|
||||||
|
} else {
|
||||||
|
throw new CorrelationAttributeNormalizationException(String.format("Data was expected to be a valid email address: %s", data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify it is only numbers and '+'. Strip spaces, dashes, and parentheses.
|
||||||
|
*/
|
||||||
|
private static String normalizePhone(String data) throws CorrelationAttributeNormalizationException {
|
||||||
|
if(data.matches("\\+?[0-9()\\-\\s]+")){
|
||||||
|
String phoneNumber = data.replaceAll("[^0-9\\+]", "");
|
||||||
|
return phoneNumber;
|
||||||
|
} else {
|
||||||
|
throw new CorrelationAttributeNormalizationException(String.format("Data was expected to be a valid phone number: %s", data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vacuous - will be replaced with something reasonable later.
|
||||||
|
*/
|
||||||
|
private static String normalizeUsbId(String data) throws CorrelationAttributeNormalizationException {
|
||||||
|
//TODO replace with correct usb id validation at a later date
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
@ -213,7 +213,7 @@ public class EamArtifactUtil {
|
|||||||
TskData.FileKnown.UNKNOWN
|
TskData.FileKnown.UNKNOWN
|
||||||
);
|
);
|
||||||
|
|
||||||
} catch (TskCoreException | EamDbException ex) {
|
} catch (TskCoreException | EamDbException | CorrelationAttributeNormalizationException ex) {
|
||||||
logger.log(Level.SEVERE, "Error creating artifact instance.", ex); // NON-NLS
|
logger.log(Level.SEVERE, "Error creating artifact instance.", ex); // NON-NLS
|
||||||
return null;
|
return null;
|
||||||
} catch (NoCurrentCaseException ex) {
|
} catch (NoCurrentCaseException ex) {
|
||||||
@ -268,7 +268,7 @@ public class EamArtifactUtil {
|
|||||||
CorrelationAttributeInstance correlationAttributeInstance;
|
CorrelationAttributeInstance correlationAttributeInstance;
|
||||||
try {
|
try {
|
||||||
correlationAttributeInstance = EamDb.getInstance().getCorrelationAttributeInstance(type, correlationCase, correlationDataSource, value, filePath);
|
correlationAttributeInstance = EamDb.getInstance().getCorrelationAttributeInstance(type, correlationCase, correlationDataSource, value, filePath);
|
||||||
} catch (EamDbException ex) {
|
} catch (EamDbException | CorrelationAttributeNormalizationException ex) {
|
||||||
logger.log(Level.WARNING, String.format(
|
logger.log(Level.WARNING, String.format(
|
||||||
"Correlation attribute could not be retrieved for '%s' (id=%d): %s",
|
"Correlation attribute could not be retrieved for '%s' (id=%d): %s",
|
||||||
content.getName(), content.getId(), ex.getMessage()));
|
content.getName(), content.getId(), ex.getMessage()));
|
||||||
@ -323,7 +323,7 @@ public class EamArtifactUtil {
|
|||||||
CorrelationDataSource.fromTSKDataSource(correlationCase, af.getDataSource()),
|
CorrelationDataSource.fromTSKDataSource(correlationCase, af.getDataSource()),
|
||||||
af.getParentPath() + af.getName());
|
af.getParentPath() + af.getName());
|
||||||
|
|
||||||
} catch (TskCoreException | EamDbException ex) {
|
} catch (TskCoreException | EamDbException | CorrelationAttributeNormalizationException ex) {
|
||||||
logger.log(Level.SEVERE, "Error making correlation attribute.", ex);
|
logger.log(Level.SEVERE, "Error making correlation attribute.", ex);
|
||||||
return null;
|
return null;
|
||||||
} catch (NoCurrentCaseException ex) {
|
} catch (NoCurrentCaseException ex) {
|
||||||
|
@ -244,7 +244,7 @@ public interface EamDb {
|
|||||||
*
|
*
|
||||||
* @return List of artifact instances for a given type/value
|
* @return List of artifact instances for a given type/value
|
||||||
*/
|
*/
|
||||||
List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException;
|
List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves eamArtifact instances from the database that are associated
|
* Retrieves eamArtifact instances from the database that are associated
|
||||||
@ -269,7 +269,7 @@ public interface EamDb {
|
|||||||
* @return Number of artifact instances having ArtifactType and
|
* @return Number of artifact instances having ArtifactType and
|
||||||
* ArtifactValue.
|
* ArtifactValue.
|
||||||
*/
|
*/
|
||||||
Long getCountArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException;
|
Long getCountArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the percentage of data sources that have this attribute value.
|
* Calculate the percentage of data sources that have this attribute value.
|
||||||
@ -278,7 +278,7 @@ public interface EamDb {
|
|||||||
*
|
*
|
||||||
* @return Int between 0 and 100
|
* @return Int between 0 and 100
|
||||||
*/
|
*/
|
||||||
int getFrequencyPercentage(CorrelationAttributeInstance corAttr) throws EamDbException;
|
int getFrequencyPercentage(CorrelationAttributeInstance corAttr) throws EamDbException, CorrelationAttributeNormalizationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves number of unique caseDisplayName / dataSource tuples in the
|
* Retrieves number of unique caseDisplayName / dataSource tuples in the
|
||||||
@ -290,7 +290,7 @@ public interface EamDb {
|
|||||||
*
|
*
|
||||||
* @return Number of unique tuples
|
* @return Number of unique tuples
|
||||||
*/
|
*/
|
||||||
Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException;
|
Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves number of data sources in the database.
|
* Retrieves number of data sources in the database.
|
||||||
@ -358,7 +358,7 @@ public interface EamDb {
|
|||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase,
|
CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase,
|
||||||
CorrelationDataSource correlationDataSource, String value, String filePath) throws EamDbException;
|
CorrelationDataSource correlationDataSource, String value, String filePath) throws EamDbException, CorrelationAttributeNormalizationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets an eamArtifact instance to the given known status. If eamArtifact
|
* Sets an eamArtifact instance to the given known status. If eamArtifact
|
||||||
@ -378,7 +378,7 @@ public interface EamDb {
|
|||||||
*
|
*
|
||||||
* @return List with 0 or more matching eamArtifact instances.
|
* @return List with 0 or more matching eamArtifact instances.
|
||||||
*/
|
*/
|
||||||
List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException;
|
List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets list of matching eamArtifact instances that have knownStatus =
|
* Gets list of matching eamArtifact instances that have knownStatus =
|
||||||
@ -397,7 +397,7 @@ public interface EamDb {
|
|||||||
*
|
*
|
||||||
* @return Number of matching eamArtifacts
|
* @return Number of matching eamArtifacts
|
||||||
*/
|
*/
|
||||||
Long getCountArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException;
|
Long getCountArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets list of distinct case display names, where each case has 1+ Artifact
|
* Gets list of distinct case display names, where each case has 1+ Artifact
|
||||||
@ -411,7 +411,7 @@ public interface EamDb {
|
|||||||
*
|
*
|
||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException;
|
List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a reference set and all values contained in it.
|
* Remove a reference set and all values contained in it.
|
||||||
@ -462,7 +462,7 @@ public interface EamDb {
|
|||||||
*
|
*
|
||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
public boolean isFileHashInReferenceSet(String hash, int referenceSetID) throws EamDbException;
|
public boolean isFileHashInReferenceSet(String hash, int referenceSetID) throws EamDbException, CorrelationAttributeNormalizationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the given value is in a specific reference set
|
* Check if the given value is in a specific reference set
|
||||||
@ -473,7 +473,7 @@ public interface EamDb {
|
|||||||
*
|
*
|
||||||
* @return true if the hash is found in the reference set
|
* @return true if the hash is found in the reference set
|
||||||
*/
|
*/
|
||||||
public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException;
|
public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException, CorrelationAttributeNormalizationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the artifact known as bad according to the reference entries?
|
* Is the artifact known as bad according to the reference entries?
|
||||||
@ -483,7 +483,7 @@ public interface EamDb {
|
|||||||
*
|
*
|
||||||
* @return Global known status of the artifact
|
* @return Global known status of the artifact
|
||||||
*/
|
*/
|
||||||
boolean isArtifactKnownBadByReference(CorrelationAttributeInstance.Type aType, String value) throws EamDbException;
|
boolean isArtifactKnownBadByReference(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new organization
|
* Add a new organization
|
||||||
@ -611,7 +611,7 @@ public interface EamDb {
|
|||||||
*
|
*
|
||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String aValue) throws EamDbException;
|
List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String aValue) throws EamDbException, CorrelationAttributeNormalizationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new EamArtifact.Type to the db.
|
* Add a new EamArtifact.Type to the db.
|
||||||
|
@ -36,7 +36,7 @@ public class EamGlobalFileInstance {
|
|||||||
int globalSetID,
|
int globalSetID,
|
||||||
String MD5Hash,
|
String MD5Hash,
|
||||||
TskData.FileKnown knownStatus,
|
TskData.FileKnown knownStatus,
|
||||||
String comment) throws EamDbException {
|
String comment) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
this(-1, globalSetID, MD5Hash, knownStatus, comment);
|
this(-1, globalSetID, MD5Hash, knownStatus, comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,17 +45,14 @@ public class EamGlobalFileInstance {
|
|||||||
int globalSetID,
|
int globalSetID,
|
||||||
String MD5Hash,
|
String MD5Hash,
|
||||||
TskData.FileKnown knownStatus,
|
TskData.FileKnown knownStatus,
|
||||||
String comment) throws EamDbException {
|
String comment) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
if(MD5Hash == null){
|
|
||||||
throw new EamDbException("null MD5 hash");
|
|
||||||
}
|
|
||||||
if(knownStatus == null){
|
if(knownStatus == null){
|
||||||
throw new EamDbException("null known status");
|
throw new EamDbException("null known status");
|
||||||
}
|
}
|
||||||
this.instanceID = instanceID;
|
this.instanceID = instanceID;
|
||||||
this.globalSetID = globalSetID;
|
this.globalSetID = globalSetID;
|
||||||
// Normalize hashes by lower casing
|
this.MD5Hash = CorrelationAttributeNormalizer.normalize(CorrelationAttributeInstance.FILES_TYPE_ID, MD5Hash);
|
||||||
this.MD5Hash = MD5Hash.toLowerCase();
|
|
||||||
this.knownStatus = knownStatus;
|
this.knownStatus = knownStatus;
|
||||||
this.comment = comment;
|
this.comment = comment;
|
||||||
}
|
}
|
||||||
@ -117,12 +114,8 @@ public class EamGlobalFileInstance {
|
|||||||
/**
|
/**
|
||||||
* @param MD5Hash the MD5Hash to set
|
* @param MD5Hash the MD5Hash to set
|
||||||
*/
|
*/
|
||||||
public void setMD5Hash(String MD5Hash) throws EamDbException {
|
public void setMD5Hash(String MD5Hash) throws CorrelationAttributeNormalizationException {
|
||||||
if(MD5Hash == null){
|
this.MD5Hash = CorrelationAttributeNormalizer.normalize(CorrelationAttributeInstance.FILES_TYPE_ID, MD5Hash);
|
||||||
throw new EamDbException("null MD5 hash");
|
|
||||||
}
|
|
||||||
// Normalize hashes by lower casing
|
|
||||||
this.MD5Hash = MD5Hash.toLowerCase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -106,4 +106,5 @@ public interface InstanceTableCallback {
|
|||||||
return resultSet.getString("comment");
|
return resultSet.getString("comment");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -447,7 +447,7 @@ final class SqliteEamDb extends AbstractSqlEamDb {
|
|||||||
* @return List of artifact instances for a given type/value
|
* @return List of artifact instances for a given type/value
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException {
|
public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
try {
|
try {
|
||||||
acquireSharedLock();
|
acquireSharedLock();
|
||||||
return super.getArtifactInstancesByTypeValue(aType, value);
|
return super.getArtifactInstancesByTypeValue(aType, value);
|
||||||
@ -489,7 +489,7 @@ final class SqliteEamDb extends AbstractSqlEamDb {
|
|||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Long getCountArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException {
|
public Long getCountArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
try {
|
try {
|
||||||
acquireSharedLock();
|
acquireSharedLock();
|
||||||
return super.getCountArtifactInstancesByTypeValue(aType, value);
|
return super.getCountArtifactInstancesByTypeValue(aType, value);
|
||||||
@ -499,7 +499,7 @@ final class SqliteEamDb extends AbstractSqlEamDb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getFrequencyPercentage(CorrelationAttributeInstance corAttr) throws EamDbException {
|
public int getFrequencyPercentage(CorrelationAttributeInstance corAttr) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
try {
|
try {
|
||||||
acquireSharedLock();
|
acquireSharedLock();
|
||||||
return super.getFrequencyPercentage(corAttr);
|
return super.getFrequencyPercentage(corAttr);
|
||||||
@ -520,7 +520,7 @@ final class SqliteEamDb extends AbstractSqlEamDb {
|
|||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException {
|
public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
try {
|
try {
|
||||||
acquireSharedLock();
|
acquireSharedLock();
|
||||||
return super.getCountUniqueCaseDataSourceTuplesHavingTypeValue(aType, value);
|
return super.getCountUniqueCaseDataSourceTuplesHavingTypeValue(aType, value);
|
||||||
@ -617,7 +617,7 @@ final class SqliteEamDb extends AbstractSqlEamDb {
|
|||||||
* @return List with 0 or more matching eamArtifact instances.
|
* @return List with 0 or more matching eamArtifact instances.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException {
|
public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
try {
|
try {
|
||||||
acquireSharedLock();
|
acquireSharedLock();
|
||||||
return super.getArtifactInstancesKnownBad(aType, value);
|
return super.getArtifactInstancesKnownBad(aType, value);
|
||||||
@ -654,7 +654,7 @@ final class SqliteEamDb extends AbstractSqlEamDb {
|
|||||||
* @return Number of matching eamArtifacts
|
* @return Number of matching eamArtifacts
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Long getCountArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException {
|
public Long getCountArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
try {
|
try {
|
||||||
acquireSharedLock();
|
acquireSharedLock();
|
||||||
return super.getCountArtifactInstancesKnownBad(aType, value);
|
return super.getCountArtifactInstancesKnownBad(aType, value);
|
||||||
@ -676,7 +676,7 @@ final class SqliteEamDb extends AbstractSqlEamDb {
|
|||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException {
|
public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
try {
|
try {
|
||||||
acquireSharedLock();
|
acquireSharedLock();
|
||||||
return super.getListCasesHavingArtifactInstancesKnownBad(aType, value);
|
return super.getListCasesHavingArtifactInstancesKnownBad(aType, value);
|
||||||
@ -710,7 +710,7 @@ final class SqliteEamDb extends AbstractSqlEamDb {
|
|||||||
* @return true if the hash is found in the reference set
|
* @return true if the hash is found in the reference set
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException {
|
public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
try {
|
try {
|
||||||
acquireSharedLock();
|
acquireSharedLock();
|
||||||
return super.isValueInReferenceSet(value, referenceSetID, correlationTypeID);
|
return super.isValueInReferenceSet(value, referenceSetID, correlationTypeID);
|
||||||
@ -782,7 +782,7 @@ final class SqliteEamDb extends AbstractSqlEamDb {
|
|||||||
* @return Global known status of the artifact
|
* @return Global known status of the artifact
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isArtifactKnownBadByReference(CorrelationAttributeInstance.Type aType, String value) throws EamDbException {
|
public boolean isArtifactKnownBadByReference(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
try {
|
try {
|
||||||
acquireSharedLock();
|
acquireSharedLock();
|
||||||
return super.isArtifactKnownBadByReference(aType, value);
|
return super.isArtifactKnownBadByReference(aType, value);
|
||||||
@ -967,7 +967,7 @@ final class SqliteEamDb extends AbstractSqlEamDb {
|
|||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String aValue) throws EamDbException {
|
public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String aValue) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||||
try {
|
try {
|
||||||
acquireSharedLock();
|
acquireSharedLock();
|
||||||
return super.getReferenceInstancesByTypeValue(aType, aValue);
|
return super.getReferenceInstancesByTypeValue(aType, aValue);
|
||||||
|
@ -34,6 +34,7 @@ import org.openide.util.NbBundle;
|
|||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
|
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||||
@ -123,19 +124,19 @@ public class IngestEventsListener {
|
|||||||
public synchronized static int getCeModuleInstanceCount() {
|
public synchronized static int getCeModuleInstanceCount() {
|
||||||
return correlationModuleInstanceCount;
|
return correlationModuleInstanceCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Are notable items being flagged?
|
* Are notable items being flagged?
|
||||||
*
|
*
|
||||||
* @return True if flagging notable items; otherwise false.
|
* @return True if flagging notable items; otherwise false.
|
||||||
*/
|
*/
|
||||||
public synchronized static boolean isFlagNotableItems() {
|
public synchronized static boolean isFlagNotableItems() {
|
||||||
return flagNotableItems;
|
return flagNotableItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure the listener to flag notable items or not.
|
* Configure the listener to flag notable items or not.
|
||||||
*
|
*
|
||||||
* @param value True to flag notable items; otherwise false.
|
* @param value True to flag notable items; otherwise false.
|
||||||
*/
|
*/
|
||||||
public synchronized static void setFlagNotableItems(boolean value) {
|
public synchronized static void setFlagNotableItems(boolean value) {
|
||||||
@ -259,13 +260,18 @@ public class IngestEventsListener {
|
|||||||
if (recentlyAddedCeArtifacts.add(eamArtifact.toString())) {
|
if (recentlyAddedCeArtifacts.add(eamArtifact.toString())) {
|
||||||
// Was it previously marked as bad?
|
// Was it previously marked as bad?
|
||||||
// query db for artifact instances having this TYPE/VALUE and knownStatus = "Bad".
|
// query db for artifact instances having this TYPE/VALUE and knownStatus = "Bad".
|
||||||
// if gettKnownStatus() is "Unknown" and this artifact instance was marked bad in a previous case,
|
// if getKnownStatus() is "Unknown" and this artifact instance was marked bad in a previous case,
|
||||||
// create TSK_INTERESTING_ARTIFACT_HIT artifact on BB.
|
// create TSK_INTERESTING_ARTIFACT_HIT artifact on BB.
|
||||||
if (flagNotableItemsEnabled) {
|
if (flagNotableItemsEnabled) {
|
||||||
List<String> caseDisplayNames = dbManager.getListCasesHavingArtifactInstancesKnownBad(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue());
|
List<String> caseDisplayNames;
|
||||||
if (!caseDisplayNames.isEmpty()) {
|
try {
|
||||||
postCorrelatedBadArtifactToBlackboard(bbArtifact,
|
caseDisplayNames = dbManager.getListCasesHavingArtifactInstancesKnownBad(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue());
|
||||||
caseDisplayNames);
|
if (!caseDisplayNames.isEmpty()) {
|
||||||
|
postCorrelatedBadArtifactToBlackboard(bbArtifact,
|
||||||
|
caseDisplayNames);
|
||||||
|
}
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
LOGGER.log(Level.INFO, String.format("Unable to flag notable item: %s.", eamArtifact.toString()), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
eamArtifacts.add(eamArtifact);
|
eamArtifacts.add(eamArtifact);
|
||||||
|
@ -28,6 +28,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
|
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
||||||
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.ingest.FileIngestModule;
|
import org.sleuthkit.autopsy.ingest.FileIngestModule;
|
||||||
@ -143,6 +144,9 @@ final class IngestModule implements FileIngestModule {
|
|||||||
} catch (EamDbException ex) {
|
} catch (EamDbException ex) {
|
||||||
logger.log(Level.SEVERE, "Error searching database for artifact.", ex); // NON-NLS
|
logger.log(Level.SEVERE, "Error searching database for artifact.", ex); // NON-NLS
|
||||||
return ProcessResult.ERROR;
|
return ProcessResult.ERROR;
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex){
|
||||||
|
logger.log(Level.INFO, "Error searching database for artifact.", ex); // NON-NLS
|
||||||
|
return ProcessResult.ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,6 +165,9 @@ final class IngestModule implements FileIngestModule {
|
|||||||
} catch (EamDbException ex) {
|
} catch (EamDbException ex) {
|
||||||
logger.log(Level.SEVERE, "Error adding artifact to bulk artifacts.", ex); // NON-NLS
|
logger.log(Level.SEVERE, "Error adding artifact to bulk artifacts.", ex); // NON-NLS
|
||||||
return ProcessResult.ERROR;
|
return ProcessResult.ERROR;
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
logger.log(Level.INFO, "Error adding artifact to bulk artifacts.", ex); // NON-NLS
|
||||||
|
return ProcessResult.ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProcessResult.OK;
|
return ProcessResult.OK;
|
||||||
|
@ -71,6 +71,12 @@ public abstract class AbstractCommonAttributeInstance {
|
|||||||
this.caseName = "";
|
this.caseName = "";
|
||||||
this.dataSource = "";
|
this.dataSource = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type of common attribute.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public abstract CorrelationAttributeInstance.Type getCorrelationAttributeInstanceType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an AbstractFile for this instance if it can be retrieved from the
|
* Get an AbstractFile for this instance if it can be retrieved from the
|
||||||
|
@ -33,9 +33,10 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
|||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prototype for an object which finds files with common attributes.
|
* Prototype for an object which finds files with common attributes.
|
||||||
* Subclass this and implement findFiles in order
|
* Subclass this and implement findMatches in order
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractCommonAttributeSearcher {
|
public abstract class AbstractCommonAttributeSearcher {
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ public abstract class AbstractCommonAttributeSearcher {
|
|||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
public abstract CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException;
|
public abstract CommonAttributeSearchResults findMatches() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implement this to create a descriptive string for the tab which will display
|
* Implement this to create a descriptive string for the tab which will display
|
||||||
@ -75,10 +76,10 @@ public abstract class AbstractCommonAttributeSearcher {
|
|||||||
* @return an informative string
|
* @return an informative string
|
||||||
*/
|
*/
|
||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"AbstractCommonFilesMetadataBuilder.buildTabTitle.titleIntraAll=Common Files (All Data Sources, %s)",
|
"AbstractCommonFilesMetadataBuilder.buildTabTitle.titleIntraAll=Common Attributes (All Data Sources, %s)",
|
||||||
"AbstractCommonFilesMetadataBuilder.buildTabTitle.titleIntraSingle=Common Files (Data Source: %s, %s)",
|
"AbstractCommonFilesMetadataBuilder.buildTabTitle.titleIntraSingle=Common Attributes (Data Source: %s, %s)",
|
||||||
"AbstractCommonFilesMetadataBuilder.buildTabTitle.titleInterAll=Common Files (All Central Repository Cases, %s)",
|
"AbstractCommonFilesMetadataBuilder.buildTabTitle.titleInterAll=Common Attributes (All Central Repository Cases, %s)",
|
||||||
"AbstractCommonFilesMetadataBuilder.buildTabTitle.titleInterSingle=Common Files (Central Repository Case: %s, %s)",
|
"AbstractCommonFilesMetadataBuilder.buildTabTitle.titleInterSingle=Common Attributes (Central Repository Case: %s, %s)",
|
||||||
})
|
})
|
||||||
abstract String buildTabTitle();
|
abstract String buildTabTitle();
|
||||||
|
|
||||||
@ -87,6 +88,7 @@ public abstract class AbstractCommonAttributeSearcher {
|
|||||||
"AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.media=Media",
|
"AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.media=Media",
|
||||||
"AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.all=All File Categories"
|
"AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.all=All File Categories"
|
||||||
})
|
})
|
||||||
|
|
||||||
String buildCategorySelectionString() {
|
String buildCategorySelectionString() {
|
||||||
if (!this.isFilterByDoc() && !this.isFilterByMedia()) {
|
if (!this.isFilterByDoc() && !this.isFilterByMedia()) {
|
||||||
return Bundle.AbstractCommonFilesMetadataBuilder_buildCategorySelectionString_all();
|
return Bundle.AbstractCommonFilesMetadataBuilder_buildCategorySelectionString_all();
|
||||||
|
@ -20,12 +20,12 @@
|
|||||||
package org.sleuthkit.autopsy.commonfilesearch;
|
package org.sleuthkit.autopsy.commonfilesearch;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Algorithm which finds files anywhere in the Central Repo which also occur in
|
* Algorithm which finds files anywhere in the Central Repo which also occur in
|
||||||
@ -34,28 +34,27 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
public class AllInterCaseCommonAttributeSearcher extends InterCaseCommonAttributeSearcher {
|
public class AllInterCaseCommonAttributeSearcher extends InterCaseCommonAttributeSearcher {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param filterByMediaMimeType match only on files whose mime types can be
|
* @param filterByMediaMimeType match only on files whose mime types can be
|
||||||
* broadly categorized as media types
|
* broadly categorized as media types
|
||||||
* @param filterByDocMimeType match only on files whose mime types can be
|
* @param filterByDocMimeType match only on files whose mime types can be
|
||||||
* broadly categorized as document types
|
* broadly categorized as document types
|
||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
public AllInterCaseCommonAttributeSearcher(Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType, int percentageThreshold) throws EamDbException {
|
public AllInterCaseCommonAttributeSearcher(Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType, Type corAttrType, int percentageThreshold) throws EamDbException {
|
||||||
super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType, percentageThreshold);
|
super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType, corAttrType, percentageThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException {
|
public CommonAttributeSearchResults findMatches() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException {
|
||||||
InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(this.getDataSourceIdToNameMap());
|
InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(this.getDataSourceIdToNameMap(), corAttrType);
|
||||||
Map<Integer, CommonAttributeValueList> interCaseCommonFiles = eamDbAttrInst.findInterCaseCommonAttributeValues(Case.getCurrentCase());
|
Map<Integer, CommonAttributeValueList> interCaseCommonFiles = eamDbAttrInst.findInterCaseCommonAttributeValues(Case.getCurrentCase());
|
||||||
return new CommonAttributeSearchResults(interCaseCommonFiles, this.frequencyPercentageThreshold);
|
return new CommonAttributeSearchResults(interCaseCommonFiles, this.frequencyPercentageThreshold, this.corAttrType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String buildTabTitle() {
|
String buildTabTitle() {
|
||||||
final String buildCategorySelectionString = this.buildCategorySelectionString();
|
|
||||||
final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleInterAll();
|
final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleInterAll();
|
||||||
return String.format(titleTemplate, new Object[]{buildCategorySelectionString});
|
return String.format(titleTemplate, new Object[]{this.corAttrType.getDisplayName()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,4 +27,11 @@ CommonAttributePanel.allFileCategoriesRadioButton.text=All file types
|
|||||||
CommonAttributePanel.cancelButton.actionCommand=Cancel
|
CommonAttributePanel.cancelButton.actionCommand=Cancel
|
||||||
CommonAttributePanel.cancelButton.text=Cancel
|
CommonAttributePanel.cancelButton.text=Cancel
|
||||||
CommonAttributePanel.searchButton.text=Search
|
CommonAttributePanel.searchButton.text=Search
|
||||||
|
CommonAttributePanel.jCheckBox1.text=Hide files found in over
|
||||||
|
CommonAttributePanel.jLabel1.text=% of data sources in central repository.
|
||||||
|
CommonAttributePanel.percentageThreshold.text=20
|
||||||
|
CommonAttributePanel.jLabel1.text_1=% of data sources in central repository.
|
||||||
|
CommonAttributePanel.percentageThresholdCheck.text_1=Hide files found in over
|
||||||
|
InterCasePanel.comboBoxLabel.text=Select correlation type to search:
|
||||||
|
InterCasePanel.correlationTypeComboBox.toolTipText=Selected Correlation Type
|
||||||
CommonAttributePanel.commonFilesSearchLabel2.text=Scope of Search
|
CommonAttributePanel.commonFilesSearchLabel2.text=Scope of Search
|
||||||
|
@ -23,6 +23,7 @@ import java.util.Arrays;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
|
import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
@ -70,4 +71,10 @@ final public class CaseDBCommonAttributeInstance extends AbstractCommonAttribute
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CorrelationAttributeInstance.Type getCorrelationAttributeInstanceType() {
|
||||||
|
//may be required at a later date
|
||||||
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,4 +94,4 @@ public class CaseDBCommonAttributeInstanceNode extends FileNode {
|
|||||||
sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), NO_DESCR, caseName));
|
sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), NO_DESCR, caseName));
|
||||||
return sheet;
|
return sheet;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -44,12 +44,19 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr
|
|||||||
private static final Logger LOGGER = Logger.getLogger(CentralRepoCommonAttributeInstance.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(CentralRepoCommonAttributeInstance.class.getName());
|
||||||
private final Integer crFileId;
|
private final Integer crFileId;
|
||||||
private CorrelationAttributeInstance currentAttribute;
|
private CorrelationAttributeInstance currentAttribute;
|
||||||
|
private final CorrelationAttributeInstance.Type correlationType;
|
||||||
private final Map<String, Long> dataSourceNameToIdMap;
|
private final Map<String, Long> dataSourceNameToIdMap;
|
||||||
|
|
||||||
CentralRepoCommonAttributeInstance(Integer attrInstId, Map<Long, String> dataSourceIdToNameMap) {
|
CentralRepoCommonAttributeInstance(Integer attrInstId, Map<Long, String> dataSourceIdToNameMap, CorrelationAttributeInstance.Type correlationType) {
|
||||||
super();
|
super();
|
||||||
this.crFileId = attrInstId;
|
this.crFileId = attrInstId;
|
||||||
this.dataSourceNameToIdMap = invertMap(dataSourceIdToNameMap);
|
this.dataSourceNameToIdMap = invertMap(dataSourceIdToNameMap);
|
||||||
|
this.correlationType = correlationType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CorrelationAttributeInstance.Type getCorrelationAttributeInstanceType(){
|
||||||
|
return this.correlationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCurrentAttributeInst(CorrelationAttributeInstance attribute) {
|
void setCurrentAttributeInst(CorrelationAttributeInstance attribute) {
|
||||||
@ -61,16 +68,15 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr
|
|||||||
|
|
||||||
Case currentCase;
|
Case currentCase;
|
||||||
if (this.currentAttribute != null) {
|
if (this.currentAttribute != null) {
|
||||||
|
|
||||||
final CorrelationAttributeInstance currentAttributeInstance = this.currentAttribute;
|
final CorrelationAttributeInstance currentAttributeInstance = this.currentAttribute;
|
||||||
|
|
||||||
String currentFullPath = currentAttributeInstance.getFilePath();
|
String currentFullPath = currentAttributeInstance.getFilePath();
|
||||||
String currentDataSource = currentAttributeInstance.getCorrelationDataSource().getName();
|
String currentDataSource = currentAttributeInstance.getCorrelationDataSource().getName();
|
||||||
|
|
||||||
|
if (this.dataSourceNameToIdMap.containsKey(currentDataSource)) {
|
||||||
if(this.dataSourceNameToIdMap.containsKey(currentDataSource)){
|
|
||||||
Long dataSourceObjectId = this.dataSourceNameToIdMap.get(currentDataSource);
|
Long dataSourceObjectId = this.dataSourceNameToIdMap.get(currentDataSource);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
currentCase = Case.getCurrentCaseThrows();
|
currentCase = Case.getCurrentCaseThrows();
|
||||||
|
|
||||||
@ -83,9 +89,9 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr
|
|||||||
final String whereClause = String.format("lower(name) = '%s' AND md5 = '%s' AND lower(parent_path) = '%s' AND data_source_obj_id = %s", fileName, currentAttribute.getCorrelationValue(), parentPath, dataSourceObjectId);
|
final String whereClause = String.format("lower(name) = '%s' AND md5 = '%s' AND lower(parent_path) = '%s' AND data_source_obj_id = %s", fileName, currentAttribute.getCorrelationValue(), parentPath, dataSourceObjectId);
|
||||||
List<AbstractFile> potentialAbstractFiles = tskDb.findAllFilesWhere(whereClause);
|
List<AbstractFile> potentialAbstractFiles = tskDb.findAllFilesWhere(whereClause);
|
||||||
|
|
||||||
if(potentialAbstractFiles.isEmpty()){
|
if (potentialAbstractFiles.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
} else if(potentialAbstractFiles.size() > 1){
|
} else if (potentialAbstractFiles.size() > 1) {
|
||||||
LOGGER.log(Level.WARNING, String.format("Unable to find an exact match for AbstractFile for record with filePath: %s. May have returned the wrong file.", new Object[]{currentFullPath}));
|
LOGGER.log(Level.WARNING, String.format("Unable to find an exact match for AbstractFile for record with filePath: %s. May have returned the wrong file.", new Object[]{currentFullPath}));
|
||||||
return potentialAbstractFiles.get(0);
|
return potentialAbstractFiles.get(0);
|
||||||
} else {
|
} else {
|
||||||
@ -98,7 +104,7 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -107,7 +113,7 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr
|
|||||||
public DisplayableItemNode[] generateNodes() {
|
public DisplayableItemNode[] generateNodes() {
|
||||||
|
|
||||||
// @@@ We should be doing more of this work in teh generateKeys method. We want to do as little as possible in generateNodes
|
// @@@ We should be doing more of this work in teh generateKeys method. We want to do as little as possible in generateNodes
|
||||||
InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor();
|
InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(correlationType);
|
||||||
CorrelationAttributeInstance corrAttr = eamDbAttrInst.findSingleCorrelationAttribute(crFileId);
|
CorrelationAttributeInstance corrAttr = eamDbAttrInst.findSingleCorrelationAttribute(crFileId);
|
||||||
List<DisplayableItemNode> attrInstNodeList = new ArrayList<>(0);
|
List<DisplayableItemNode> attrInstNodeList = new ArrayList<>(0);
|
||||||
String currCaseDbName = Case.getCurrentCase().getDisplayName();
|
String currCaseDbName = Case.getCurrentCase().getDisplayName();
|
||||||
@ -128,7 +134,7 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr
|
|||||||
|
|
||||||
private Map<String, Long> invertMap(Map<Long, String> dataSourceIdToNameMap) {
|
private Map<String, Long> invertMap(Map<Long, String> dataSourceIdToNameMap) {
|
||||||
HashMap<String, Long> invertedMap = new HashMap<>();
|
HashMap<String, Long> invertedMap = new HashMap<>();
|
||||||
for (Map.Entry<Long, String> entry : dataSourceIdToNameMap.entrySet()){
|
for (Map.Entry<Long, String> entry : dataSourceIdToNameMap.entrySet()) {
|
||||||
invertedMap.put(entry.getValue(), entry.getKey());
|
invertedMap.put(entry.getValue(), entry.getKey());
|
||||||
}
|
}
|
||||||
return invertedMap;
|
return invertedMap;
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
</NonVisualComponents>
|
</NonVisualComponents>
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[450, 375]"/>
|
<Dimension value="[450, 440]"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[450, 375]"/>
|
<Dimension value="[450, 440]"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="resizable" type="boolean" value="false"/>
|
<Property name="resizable" type="boolean" value="false"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
@ -32,7 +32,7 @@
|
|||||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-81,0,0,2,102"/>
|
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-72,0,0,1,-61"/>
|
||||||
</AuxValues>
|
</AuxValues>
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||||
@ -40,13 +40,13 @@
|
|||||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[450, 375]"/>
|
<Dimension value="[450, 440]"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[450, 375]"/>
|
<Dimension value="[450, 440]"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[450, 375]"/>
|
<Dimension value="[450, 440]"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="requestFocusEnabled" type="boolean" value="false"/>
|
<Property name="requestFocusEnabled" type="boolean" value="false"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
@ -107,7 +107,7 @@
|
|||||||
<Component id="percentageThresholdTextTwo" min="-2" max="-2" attributes="0"/>
|
<Component id="percentageThresholdTextTwo" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace pref="9" max="32767" attributes="0"/>
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
@ -199,6 +199,7 @@
|
|||||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||||
<ComponentRef name="fileTypeFilterButtonGroup"/>
|
<ComponentRef name="fileTypeFilterButtonGroup"/>
|
||||||
</Property>
|
</Property>
|
||||||
|
<Property name="selected" type="boolean" value="true"/>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.allFileCategoriesRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.allFileCategoriesRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
@ -215,7 +216,6 @@
|
|||||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||||
<ComponentRef name="fileTypeFilterButtonGroup"/>
|
<ComponentRef name="fileTypeFilterButtonGroup"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="selected" type="boolean" value="true"/>
|
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.selectedFileCategoriesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.selectedFileCategoriesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
@ -233,6 +233,7 @@
|
|||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.pictureVideoCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.pictureVideoCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Events>
|
<Events>
|
||||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="pictureVideoCheckboxActionPerformed"/>
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="pictureVideoCheckboxActionPerformed"/>
|
||||||
@ -244,6 +245,7 @@
|
|||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.documentsCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.documentsCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Events>
|
<Events>
|
||||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="documentsCheckboxActionPerformed"/>
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="documentsCheckboxActionPerformed"/>
|
||||||
|
@ -38,6 +38,7 @@ import org.openide.util.NbBundle;
|
|||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||||
@ -74,25 +75,26 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
* Creates new form CommonFilesPanel
|
* Creates new form CommonFilesPanel
|
||||||
*/
|
*/
|
||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"CommonFilesPanel.title=Common Files Panel",
|
"CommonAttributePanel.title=Common Attribute Panel",
|
||||||
"CommonFilesPanel.exception=Unexpected Exception loading DataSources.",
|
"CommonAttributePanel.exception=Unexpected Exception loading DataSources.",
|
||||||
"CommonFilesPanel.frame.title=Find Common Files",
|
"CommonAttributePanel.frame.title=Find Common Attributes",
|
||||||
"CommonFilesPanel.frame.msg=Find Common Files"})
|
"CommonAttributePanel.frame.msg=Find Common Attributes"})
|
||||||
public CommonAttributePanel() {
|
public CommonAttributePanel() {
|
||||||
super(new JFrame(Bundle.CommonFilesPanel_frame_title()),
|
super(new JFrame(Bundle.CommonAttributePanel_frame_title()),
|
||||||
Bundle.CommonFilesPanel_frame_msg(), true);
|
Bundle.CommonAttributePanel_frame_msg(), true);
|
||||||
initComponents();
|
initComponents();
|
||||||
|
|
||||||
this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
|
this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
|
||||||
this.setupDataSources();
|
this.setupDataSources();
|
||||||
|
|
||||||
if (CommonAttributePanel.isEamDbAvailableForIntercaseSearch()) {
|
if (CommonAttributePanel.isEamDbAvailableForIntercaseSearch()) {
|
||||||
this.setupCases();
|
this.setupCases();
|
||||||
|
this.interCasePanel.setupCorrelationTypeFilter();
|
||||||
} else {
|
} else {
|
||||||
this.disableIntercaseSearch();
|
this.disableIntercaseSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(CommonAttributePanel.isEamDbAvailableForPercentageFrequencyCalculations()){
|
if (CommonAttributePanel.isEamDbAvailableForPercentageFrequencyCalculations()) {
|
||||||
this.enablePercentageOptions();
|
this.enablePercentageOptions();
|
||||||
} else {
|
} else {
|
||||||
this.disablePercentageOptions();
|
this.disablePercentageOptions();
|
||||||
@ -103,11 +105,11 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
this.percentageThresholdTextOne.getDocument().addDocumentListener(new DocumentListener(){
|
this.percentageThresholdTextOne.getDocument().addDocumentListener(new DocumentListener(){
|
||||||
|
|
||||||
private Dimension preferredSize = CommonAttributePanel.this.percentageThresholdTextOne.getPreferredSize();
|
private Dimension preferredSize = CommonAttributePanel.this.percentageThresholdTextOne.getPreferredSize();
|
||||||
|
|
||||||
private void maintainSize(){
|
private void maintainSize() {
|
||||||
CommonAttributePanel.this.percentageThresholdTextOne.setSize(preferredSize);
|
CommonAttributePanel.this.percentageThresholdTextOne.setSize(preferredSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void insertUpdate(DocumentEvent event) {
|
public void insertUpdate(DocumentEvent event) {
|
||||||
this.maintainSize();
|
this.maintainSize();
|
||||||
@ -141,9 +143,9 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isEamDbAvailableForPercentageFrequencyCalculations(){
|
private static boolean isEamDbAvailableForPercentageFrequencyCalculations() {
|
||||||
try {
|
try {
|
||||||
return EamDb.isEnabled()
|
return EamDb.isEnabled()
|
||||||
&& EamDb.getInstance() != null
|
&& EamDb.getInstance() != null
|
||||||
&& EamDb.getInstance().getCases().size() > 0;
|
&& EamDb.getInstance().getCases().size() > 0;
|
||||||
@ -159,18 +161,18 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"CommonFilesPanel.search.results.titleAll=Common Files (All Data Sources)",
|
"CommonAttributePanel.search.results.titleAll=Common Attributes (All Data Sources)",
|
||||||
"CommonFilesPanel.search.results.titleSingle=Common Files (Match Within Data Source: %s)",
|
"CommonAttributePanel.search.results.titleSingle=Common Attributes (Match Within Data Source: %s)",
|
||||||
"CommonFilesPanel.search.results.pathText=Common Files Search Results",
|
"CommonAttributePanel.search.results.pathText=Common Attribute Search Results",
|
||||||
"CommonFilesPanel.search.done.searchProgressGathering=Gathering Common Files Search Results.",
|
"CommonAttributePanel.search.done.searchProgressGathering=Gathering Common Attribute Search Results.",
|
||||||
"CommonFilesPanel.search.done.searchProgressDisplay=Displaying Common Files Search Results.",
|
"CommonAttributePanel.search.done.searchProgressDisplay=Displaying Common Attribute Search Results.",
|
||||||
"CommonFilesPanel.search.done.tskCoreException=Unable to run query against DB.",
|
"CommonAttributePanel.search.done.tskCoreException=Unable to run query against DB.",
|
||||||
"CommonFilesPanel.search.done.noCurrentCaseException=Unable to open case file.",
|
"CommonAttributePanel.search.done.noCurrentCaseException=Unable to open case file.",
|
||||||
"CommonFilesPanel.search.done.exception=Unexpected exception running Common Files Search.",
|
"CommonAttributePanel.search.done.exception=Unexpected exception running Common Attribute Search.",
|
||||||
"CommonFilesPanel.search.done.interupted=Something went wrong finding common files.",
|
"CommonAttributePanel.search.done.interupted=Something went wrong finding common attributes.",
|
||||||
"CommonFilesPanel.search.done.sqlException=Unable to query db for files or data sources."})
|
"CommonAttributePanel.search.done.sqlException=Unable to query db for attributes or data sources."})
|
||||||
private void search() {
|
private void search() {
|
||||||
String pathText = Bundle.CommonFilesPanel_search_results_pathText();
|
String pathText = Bundle.CommonAttributePanel_search_results_pathText();
|
||||||
|
|
||||||
new SwingWorker<CommonAttributeSearchResults, Void>() {
|
new SwingWorker<CommonAttributeSearchResults, Void>() {
|
||||||
|
|
||||||
@ -178,20 +180,20 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
private ProgressHandle progress;
|
private ProgressHandle progress;
|
||||||
|
|
||||||
private void setTitleForAllDataSources() {
|
private void setTitleForAllDataSources() {
|
||||||
this.tabTitle = Bundle.CommonFilesPanel_search_results_titleAll();
|
this.tabTitle = Bundle.CommonAttributePanel_search_results_titleAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setTitleForSingleSource(Long dataSourceId) {
|
private void setTitleForSingleSource(Long dataSourceId) {
|
||||||
final String CommonFilesPanel_search_results_titleSingle = Bundle.CommonFilesPanel_search_results_titleSingle();
|
final String CommonAttributePanel_search_results_titleSingle = Bundle.CommonAttributePanel_search_results_titleSingle();
|
||||||
final Object[] dataSourceName = new Object[]{intraCasePanel.getDataSourceMap().get(dataSourceId)};
|
final Object[] dataSourceName = new Object[]{intraCasePanel.getDataSourceMap().get(dataSourceId)};
|
||||||
|
|
||||||
this.tabTitle = String.format(CommonFilesPanel_search_results_titleSingle, dataSourceName);
|
this.tabTitle = String.format(CommonAttributePanel_search_results_titleSingle, dataSourceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings({"BoxedValueEquality", "NumberEquality"})
|
@SuppressWarnings({"BoxedValueEquality", "NumberEquality"})
|
||||||
protected CommonAttributeSearchResults doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException {
|
protected CommonAttributeSearchResults doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException {
|
||||||
progress = ProgressHandle.createHandle(Bundle.CommonFilesPanel_search_done_searchProgressGathering());
|
progress = ProgressHandle.createHandle(Bundle.CommonAttributePanel_search_done_searchProgressGathering());
|
||||||
progress.start();
|
progress.start();
|
||||||
progress.switchToIndeterminate();
|
progress.switchToIndeterminate();
|
||||||
|
|
||||||
@ -213,18 +215,22 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int percentageThreshold = CommonAttributePanel.this.percentageThresholdValue;
|
int percentageThreshold = CommonAttributePanel.this.percentageThresholdValue;
|
||||||
|
|
||||||
if (!CommonAttributePanel.this.percentageThresholdCheck.isSelected()) {
|
if (!CommonAttributePanel.this.percentageThresholdCheck.isSelected()) {
|
||||||
//0 has the effect of disabling the feature
|
//0 has the effect of disabling the feature
|
||||||
percentageThreshold = 0;
|
percentageThreshold = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CommonAttributePanel.this.interCaseRadio.isSelected()) {
|
if (CommonAttributePanel.this.interCaseRadio.isSelected()) {
|
||||||
|
CorrelationAttributeInstance.Type corType = interCasePanel.getSelectedCorrelationType();
|
||||||
|
if (corType == null) {
|
||||||
|
corType = CorrelationAttributeInstance.getDefaultCorrelationTypes().get(0);
|
||||||
|
}
|
||||||
if (caseId == InterCasePanel.NO_CASE_SELECTED) {
|
if (caseId == InterCasePanel.NO_CASE_SELECTED) {
|
||||||
builder = new AllInterCaseCommonAttributeSearcher(intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments, percentageThreshold);
|
builder = new AllInterCaseCommonAttributeSearcher(intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments, corType, percentageThreshold);
|
||||||
} else {
|
} else {
|
||||||
builder = new SingleInterCaseCommonAttributeSearcher(caseId, intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments, percentageThreshold);
|
|
||||||
|
builder = new SingleInterCaseCommonAttributeSearcher(caseId, intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments, corType, percentageThreshold);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (dataSourceId == CommonAttributePanel.NO_DATA_SOURCE_SELECTED) {
|
if (dataSourceId == CommonAttributePanel.NO_DATA_SOURCE_SELECTED) {
|
||||||
@ -237,7 +243,7 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
setTitleForSingleSource(dataSourceId);
|
setTitleForSingleSource(dataSourceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
metadata = builder.findFiles();
|
metadata = builder.findMatches();
|
||||||
this.tabTitle = builder.buildTabTitle();
|
this.tabTitle = builder.buildTabTitle();
|
||||||
|
|
||||||
return metadata;
|
return metadata;
|
||||||
@ -262,28 +268,28 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
Collection<DataResultViewer> viewers = new ArrayList<>(1);
|
Collection<DataResultViewer> viewers = new ArrayList<>(1);
|
||||||
viewers.add(table);
|
viewers.add(table);
|
||||||
|
|
||||||
progress.setDisplayName(Bundle.CommonFilesPanel_search_done_searchProgressDisplay());
|
progress.setDisplayName(Bundle.CommonAttributePanel_search_done_searchProgressDisplay());
|
||||||
DataResultTopComponent.createInstance(tabTitle, pathText, tableFilterWithDescendantsNode, metadata.size(), viewers);
|
DataResultTopComponent.createInstance(tabTitle, pathText, tableFilterWithDescendantsNode, metadata.size(), viewers);
|
||||||
progress.finish();
|
progress.finish();
|
||||||
|
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Interrupted while loading Common Files", ex);
|
LOGGER.log(Level.SEVERE, "Interrupted while loading Common Files", ex);
|
||||||
MessageNotifyUtil.Message.error(Bundle.CommonFilesPanel_search_done_interupted());
|
MessageNotifyUtil.Message.error(Bundle.CommonAttributePanel_search_done_interupted());
|
||||||
} catch (ExecutionException ex) {
|
} catch (ExecutionException ex) {
|
||||||
String errorMessage;
|
String errorMessage;
|
||||||
Throwable inner = ex.getCause();
|
Throwable inner = ex.getCause();
|
||||||
if (inner instanceof TskCoreException) {
|
if (inner instanceof TskCoreException) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to load files from database.", ex);
|
LOGGER.log(Level.SEVERE, "Failed to load files from database.", ex);
|
||||||
errorMessage = Bundle.CommonFilesPanel_search_done_tskCoreException();
|
errorMessage = Bundle.CommonAttributePanel_search_done_tskCoreException();
|
||||||
} else if (inner instanceof NoCurrentCaseException) {
|
} else if (inner instanceof NoCurrentCaseException) {
|
||||||
LOGGER.log(Level.SEVERE, "Current case has been closed.", ex);
|
LOGGER.log(Level.SEVERE, "Current case has been closed.", ex);
|
||||||
errorMessage = Bundle.CommonFilesPanel_search_done_noCurrentCaseException();
|
errorMessage = Bundle.CommonAttributePanel_search_done_noCurrentCaseException();
|
||||||
} else if (inner instanceof SQLException) {
|
} else if (inner instanceof SQLException) {
|
||||||
LOGGER.log(Level.SEVERE, "Unable to query db for files.", ex);
|
LOGGER.log(Level.SEVERE, "Unable to query db for files.", ex);
|
||||||
errorMessage = Bundle.CommonFilesPanel_search_done_sqlException();
|
errorMessage = Bundle.CommonAttributePanel_search_done_sqlException();
|
||||||
} else {
|
} else {
|
||||||
LOGGER.log(Level.SEVERE, "Unexpected exception while running Common Files Search.", ex);
|
LOGGER.log(Level.SEVERE, "Unexpected exception while running Common Files Search.", ex);
|
||||||
errorMessage = Bundle.CommonFilesPanel_search_done_exception();
|
errorMessage = Bundle.CommonAttributePanel_search_done_exception();
|
||||||
}
|
}
|
||||||
MessageNotifyUtil.Message.error(errorMessage);
|
MessageNotifyUtil.Message.error(errorMessage);
|
||||||
}
|
}
|
||||||
@ -299,12 +305,12 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
* names
|
* names
|
||||||
*/
|
*/
|
||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"CommonFilesPanel.setupDataSources.done.tskCoreException=Unable to run query against DB.",
|
"CommonAttributePanel.setupDataSources.done.tskCoreException=Unable to run query against DB.",
|
||||||
"CommonFilesPanel.setupDataSources.done.noCurrentCaseException=Unable to open case file.",
|
"CommonAttributePanel.setupDataSources.done.noCurrentCaseException=Unable to open case file.",
|
||||||
"CommonFilesPanel.setupDataSources.done.exception=Unexpected exception loading data sources.",
|
"CommonAttributePanel.setupDataSources.done.exception=Unexpected exception loading data sources.",
|
||||||
"CommonFilesPanel.setupDataSources.done.interupted=Something went wrong building the Common Files Search dialog box.",
|
"CommonAttributePanel.setupDataSources.done.interupted=Something went wrong building the Common Files Search dialog box.",
|
||||||
"CommonFilesPanel.setupDataSources.done.sqlException=Unable to query db for data sources.",
|
"CommonAttributePanel.setupDataSources.done.sqlException=Unable to query db for data sources.",
|
||||||
"CommonFilesPanel.setupDataSources.updateUi.noDataSources=No data sources were found."})
|
"CommonAttributePanel.setupDataSources.updateUi.noDataSources=No data sources were found."})
|
||||||
private void setupDataSources() {
|
private void setupDataSources() {
|
||||||
|
|
||||||
new SwingWorker<Map<Long, String>, Void>() {
|
new SwingWorker<Map<Long, String>, Void>() {
|
||||||
@ -346,22 +352,22 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
|
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex);
|
LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex);
|
||||||
MessageNotifyUtil.Message.error(Bundle.CommonFilesPanel_setupDataSources_done_interupted());
|
MessageNotifyUtil.Message.error(Bundle.CommonAttributePanel_setupDataSources_done_interupted());
|
||||||
} catch (ExecutionException ex) {
|
} catch (ExecutionException ex) {
|
||||||
String errorMessage;
|
String errorMessage;
|
||||||
Throwable inner = ex.getCause();
|
Throwable inner = ex.getCause();
|
||||||
if (inner instanceof TskCoreException) {
|
if (inner instanceof TskCoreException) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to load data sources from database.", ex);
|
LOGGER.log(Level.SEVERE, "Failed to load data sources from database.", ex);
|
||||||
errorMessage = Bundle.CommonFilesPanel_setupDataSources_done_tskCoreException();
|
errorMessage = Bundle.CommonAttributePanel_setupDataSources_done_tskCoreException();
|
||||||
} else if (inner instanceof NoCurrentCaseException) {
|
} else if (inner instanceof NoCurrentCaseException) {
|
||||||
LOGGER.log(Level.SEVERE, "Current case has been closed.", ex);
|
LOGGER.log(Level.SEVERE, "Current case has been closed.", ex);
|
||||||
errorMessage = Bundle.CommonFilesPanel_setupDataSources_done_noCurrentCaseException();
|
errorMessage = Bundle.CommonAttributePanel_setupDataSources_done_noCurrentCaseException();
|
||||||
} else if (inner instanceof SQLException) {
|
} else if (inner instanceof SQLException) {
|
||||||
LOGGER.log(Level.SEVERE, "Unable to query db for data sources.", ex);
|
LOGGER.log(Level.SEVERE, "Unable to query db for data sources.", ex);
|
||||||
errorMessage = Bundle.CommonFilesPanel_setupDataSources_done_sqlException();
|
errorMessage = Bundle.CommonAttributePanel_setupDataSources_done_sqlException();
|
||||||
} else {
|
} else {
|
||||||
LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog panel.", ex);
|
LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog panel.", ex);
|
||||||
errorMessage = Bundle.CommonFilesPanel_setupDataSources_done_exception();
|
errorMessage = Bundle.CommonAttributePanel_setupDataSources_done_exception();
|
||||||
}
|
}
|
||||||
MessageNotifyUtil.Message.error(errorMessage);
|
MessageNotifyUtil.Message.error(errorMessage);
|
||||||
}
|
}
|
||||||
@ -370,8 +376,8 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"CommonFilesPanel.setupCases.done.interruptedException=Something went wrong building the Common Files Search dialog box.",
|
"CommonAttributePanel.setupCases.done.interruptedException=Something went wrong building the Common Files Search dialog box.",
|
||||||
"CommonFilesPanel.setupCases.done.exeutionException=Unexpected exception loading cases."})
|
"CommonAttributePanel.setupCases.done.exeutionException=Unexpected exception loading cases."})
|
||||||
private void setupCases() {
|
private void setupCases() {
|
||||||
|
|
||||||
new SwingWorker<Map<Integer, String>, Void>() {
|
new SwingWorker<Map<Integer, String>, Void>() {
|
||||||
@ -423,10 +429,10 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
this.updateUi();
|
this.updateUi();
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex);
|
LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex);
|
||||||
MessageNotifyUtil.Message.error(Bundle.CommonFilesPanel_setupCases_done_interruptedException());
|
MessageNotifyUtil.Message.error(Bundle.CommonAttributePanel_setupCases_done_interruptedException());
|
||||||
} catch (ExecutionException ex) {
|
} catch (ExecutionException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog.", ex);
|
LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog.", ex);
|
||||||
MessageNotifyUtil.Message.error(Bundle.CommonFilesPanel_setupCases_done_exeutionException());
|
MessageNotifyUtil.Message.error(Bundle.CommonAttributePanel_setupCases_done_exeutionException());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,8 +476,8 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
|
filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
|
||||||
filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 32767));
|
filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 32767));
|
||||||
|
|
||||||
setMaximumSize(new java.awt.Dimension(450, 375));
|
setMaximumSize(new java.awt.Dimension(450, 440));
|
||||||
setMinimumSize(new java.awt.Dimension(450, 375));
|
setMinimumSize(new java.awt.Dimension(450, 440));
|
||||||
setResizable(false);
|
setResizable(false);
|
||||||
addWindowListener(new java.awt.event.WindowAdapter() {
|
addWindowListener(new java.awt.event.WindowAdapter() {
|
||||||
public void windowClosed(java.awt.event.WindowEvent evt) {
|
public void windowClosed(java.awt.event.WindowEvent evt) {
|
||||||
@ -479,9 +485,9 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
jPanel1.setMaximumSize(new java.awt.Dimension(450, 375));
|
jPanel1.setMaximumSize(new java.awt.Dimension(450, 440));
|
||||||
jPanel1.setMinimumSize(new java.awt.Dimension(450, 375));
|
jPanel1.setMinimumSize(new java.awt.Dimension(450, 440));
|
||||||
jPanel1.setPreferredSize(new java.awt.Dimension(450, 375));
|
jPanel1.setPreferredSize(new java.awt.Dimension(450, 440));
|
||||||
jPanel1.setRequestFocusEnabled(false);
|
jPanel1.setRequestFocusEnabled(false);
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel2, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.commonFilesSearchLabel2.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel2, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.commonFilesSearchLabel2.text")); // NOI18N
|
||||||
@ -506,6 +512,7 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
});
|
});
|
||||||
|
|
||||||
fileTypeFilterButtonGroup.add(allFileCategoriesRadioButton);
|
fileTypeFilterButtonGroup.add(allFileCategoriesRadioButton);
|
||||||
|
allFileCategoriesRadioButton.setSelected(true);
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(allFileCategoriesRadioButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.allFileCategoriesRadioButton.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(allFileCategoriesRadioButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.allFileCategoriesRadioButton.text")); // NOI18N
|
||||||
allFileCategoriesRadioButton.setToolTipText(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.allFileCategoriesRadioButton.toolTipText")); // NOI18N
|
allFileCategoriesRadioButton.setToolTipText(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.allFileCategoriesRadioButton.toolTipText")); // NOI18N
|
||||||
allFileCategoriesRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
allFileCategoriesRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
@ -515,7 +522,6 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
});
|
});
|
||||||
|
|
||||||
fileTypeFilterButtonGroup.add(selectedFileCategoriesButton);
|
fileTypeFilterButtonGroup.add(selectedFileCategoriesButton);
|
||||||
selectedFileCategoriesButton.setSelected(true);
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(selectedFileCategoriesButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.selectedFileCategoriesButton.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(selectedFileCategoriesButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.selectedFileCategoriesButton.text")); // NOI18N
|
||||||
selectedFileCategoriesButton.setToolTipText(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.selectedFileCategoriesButton.toolTipText")); // NOI18N
|
selectedFileCategoriesButton.setToolTipText(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.selectedFileCategoriesButton.toolTipText")); // NOI18N
|
||||||
selectedFileCategoriesButton.addActionListener(new java.awt.event.ActionListener() {
|
selectedFileCategoriesButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
@ -526,6 +532,7 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
|
|
||||||
pictureVideoCheckbox.setSelected(true);
|
pictureVideoCheckbox.setSelected(true);
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(pictureVideoCheckbox, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.pictureVideoCheckbox.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(pictureVideoCheckbox, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.pictureVideoCheckbox.text")); // NOI18N
|
||||||
|
pictureVideoCheckbox.setEnabled(false);
|
||||||
pictureVideoCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
pictureVideoCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
pictureVideoCheckboxActionPerformed(evt);
|
pictureVideoCheckboxActionPerformed(evt);
|
||||||
@ -534,6 +541,7 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
|
|
||||||
documentsCheckbox.setSelected(true);
|
documentsCheckbox.setSelected(true);
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(documentsCheckbox, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.documentsCheckbox.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(documentsCheckbox, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.documentsCheckbox.text")); // NOI18N
|
||||||
|
documentsCheckbox.setEnabled(false);
|
||||||
documentsCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
documentsCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
documentsCheckboxActionPerformed(evt);
|
documentsCheckboxActionPerformed(evt);
|
||||||
@ -628,7 +636,7 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
.addComponent(percentageThresholdTextOne, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(percentageThresholdTextOne, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(percentageThresholdTextTwo)))
|
.addComponent(percentageThresholdTextTwo)))
|
||||||
.addContainerGap(9, Short.MAX_VALUE))))
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
|
||||||
);
|
);
|
||||||
jPanel1Layout.setVerticalGroup(
|
jPanel1Layout.setVerticalGroup(
|
||||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
@ -689,10 +697,19 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
|
|
||||||
private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed
|
private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed
|
||||||
((java.awt.CardLayout) this.layoutPanel.getLayout()).last(this.layoutPanel);
|
((java.awt.CardLayout) this.layoutPanel.getLayout()).last(this.layoutPanel);
|
||||||
|
this.categoriesLabel.setEnabled(false);
|
||||||
|
this.selectedFileCategoriesButton.setEnabled(false);
|
||||||
|
this.allFileCategoriesRadioButton.setEnabled(false);
|
||||||
|
this.allFileCategoriesRadioButton.setSelected(true);
|
||||||
|
this.documentsCheckbox.setEnabled(false);
|
||||||
|
this.pictureVideoCheckbox.setEnabled(false);
|
||||||
}//GEN-LAST:event_interCaseRadioActionPerformed
|
}//GEN-LAST:event_interCaseRadioActionPerformed
|
||||||
|
|
||||||
private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed
|
private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed
|
||||||
((java.awt.CardLayout) this.layoutPanel.getLayout()).first(this.layoutPanel);
|
((java.awt.CardLayout) this.layoutPanel.getLayout()).first(this.layoutPanel);
|
||||||
|
this.categoriesLabel.setEnabled(true);
|
||||||
|
this.selectedFileCategoriesButton.setEnabled(true);
|
||||||
|
this.allFileCategoriesRadioButton.setEnabled(true);
|
||||||
}//GEN-LAST:event_intraCaseRadioActionPerformed
|
}//GEN-LAST:event_intraCaseRadioActionPerformed
|
||||||
|
|
||||||
private void documentsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_documentsCheckboxActionPerformed
|
private void documentsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_documentsCheckboxActionPerformed
|
||||||
@ -720,19 +737,19 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
SwingUtilities.windowForComponent(this).dispose();
|
SwingUtilities.windowForComponent(this).dispose();
|
||||||
}//GEN-LAST:event_searchButtonActionPerformed
|
}//GEN-LAST:event_searchButtonActionPerformed
|
||||||
|
|
||||||
private void percentageThresholdChanged(){
|
private void percentageThresholdChanged() {
|
||||||
String percentageString = this.percentageThresholdTextOne.getText();
|
String percentageString = this.percentageThresholdTextOne.getText();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.percentageThresholdValue = Integer.parseInt(percentageString);
|
this.percentageThresholdValue = Integer.parseInt(percentageString);
|
||||||
|
|
||||||
} catch (NumberFormatException exception) {
|
} catch (NumberFormatException exception) {
|
||||||
this.percentageThresholdValue = -1;
|
this.percentageThresholdValue = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.handleFrequencyPercentageState();
|
this.handleFrequencyPercentageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateErrorTextAndSearchBox() {
|
private void updateErrorTextAndSearchBox() {
|
||||||
|
|
||||||
if (this.errorManager.anyErrors()) {
|
if (this.errorManager.anyErrors()) {
|
||||||
@ -768,7 +785,7 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
if (this.allFileCategoriesRadioButton.isSelected()) {
|
if (this.allFileCategoriesRadioButton.isSelected()) {
|
||||||
this.pictureVideoCheckbox.setEnabled(false);
|
this.pictureVideoCheckbox.setEnabled(false);
|
||||||
this.documentsCheckbox.setEnabled(false);
|
this.documentsCheckbox.setEnabled(false);
|
||||||
|
|
||||||
this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, false);
|
this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -786,7 +803,7 @@ public final class CommonAttributePanel extends javax.swing.JDialog {
|
|||||||
this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, false);
|
this.errorManager.setError(UserInputErrorManager.NO_FILE_CATEGORIES_SELECTED_KEY, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateErrorTextAndSearchBox();
|
this.updateErrorTextAndSearchBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,14 +32,14 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
/**
|
/**
|
||||||
* Encapsulates a menu action which triggers the common files search dialog.
|
* Encapsulates a menu action which triggers the common files search dialog.
|
||||||
*/
|
*/
|
||||||
final public class CommonFilesSearchAction extends CallableSystemAction {
|
final public class CommonAttributeSearchAction extends CallableSystemAction {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(CommonFilesSearchAction.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(CommonAttributeSearchAction.class.getName());
|
||||||
|
|
||||||
private static CommonFilesSearchAction instance = null;
|
private static CommonAttributeSearchAction instance = null;
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
CommonFilesSearchAction() {
|
CommonAttributeSearchAction() {
|
||||||
super();
|
super();
|
||||||
this.setEnabled(false);
|
this.setEnabled(false);
|
||||||
}
|
}
|
||||||
@ -68,9 +68,9 @@ final public class CommonFilesSearchAction extends CallableSystemAction {
|
|||||||
return super.isEnabled() && shouldBeEnabled;
|
return super.isEnabled() && shouldBeEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized CommonFilesSearchAction getDefault() {
|
public static synchronized CommonAttributeSearchAction getDefault() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new CommonFilesSearchAction();
|
instance = new CommonAttributeSearchAction();
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
@ -86,10 +86,10 @@ final public class CommonFilesSearchAction extends CallableSystemAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"CommonFilesAction.getName.text=Common Files Search"})
|
"CommonAttributeSearchAction.getName.text=Common Attribute Search"})
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return Bundle.CommonFilesAction_getName_text();
|
return Bundle.CommonAttributeSearchAction_getName_text();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -25,9 +25,12 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.logging.Level;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the results from the various types of common attribute searching
|
* Stores the results from the various types of common attribute searching
|
||||||
@ -35,10 +38,13 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
|||||||
*/
|
*/
|
||||||
final public class CommonAttributeSearchResults {
|
final public class CommonAttributeSearchResults {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(CommonAttributeSearchResults.class.getName());
|
||||||
|
|
||||||
// maps instance count to list of attribute values.
|
// maps instance count to list of attribute values.
|
||||||
private final Map<Integer, CommonAttributeValueList> instanceCountToAttributeValues;
|
private final Map<Integer, CommonAttributeValueList> instanceCountToAttributeValues;
|
||||||
|
|
||||||
private final int percentageThreshold;
|
private final int percentageThreshold;
|
||||||
|
private final int resultTypeId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a values object which can be handed off to the node factories.
|
* Create a values object which can be handed off to the node factories.
|
||||||
@ -46,10 +52,24 @@ final public class CommonAttributeSearchResults {
|
|||||||
* @param values list of CommonAttributeValue indexed by size of
|
* @param values list of CommonAttributeValue indexed by size of
|
||||||
* CommonAttributeValue
|
* CommonAttributeValue
|
||||||
*/
|
*/
|
||||||
|
CommonAttributeSearchResults(Map<Integer, CommonAttributeValueList> metadata, int percentageThreshold, CorrelationAttributeInstance.Type resultType) {
|
||||||
|
//wrap in a new object in case any client code has used an unmodifiable collection
|
||||||
|
this.instanceCountToAttributeValues = new HashMap<>(metadata);
|
||||||
|
this.percentageThreshold = percentageThreshold;
|
||||||
|
this.resultTypeId = resultType.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a values object which can be handed off to the node factories.
|
||||||
|
*
|
||||||
|
* @param values list of CommonAttributeValue indexed by size of
|
||||||
|
* CommonAttributeValue
|
||||||
|
*/
|
||||||
CommonAttributeSearchResults(Map<Integer, CommonAttributeValueList> metadata, int percentageThreshold) {
|
CommonAttributeSearchResults(Map<Integer, CommonAttributeValueList> metadata, int percentageThreshold) {
|
||||||
//wrap in a new object in case any client code has used an unmodifiable collection
|
//wrap in a new object in case any client code has used an unmodifiable collection
|
||||||
this.instanceCountToAttributeValues = new HashMap<>(metadata);
|
this.instanceCountToAttributeValues = new HashMap<>(metadata);
|
||||||
this.percentageThreshold = percentageThreshold;
|
this.percentageThreshold = percentageThreshold;
|
||||||
|
this.resultTypeId = CorrelationAttributeInstance.FILES_TYPE_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,7 +106,7 @@ final public class CommonAttributeSearchResults {
|
|||||||
* search.
|
* search.
|
||||||
*
|
*
|
||||||
* Remove results which are not found in the portion of available data
|
* Remove results which are not found in the portion of available data
|
||||||
sources described by maximumPercentageThreshold.
|
* sources described by maximumPercentageThreshold.
|
||||||
*
|
*
|
||||||
* @return metadata
|
* @return metadata
|
||||||
*/
|
*/
|
||||||
@ -99,7 +119,7 @@ final public class CommonAttributeSearchResults {
|
|||||||
CorrelationAttributeInstance.Type fileAttributeType = CorrelationAttributeInstance
|
CorrelationAttributeInstance.Type fileAttributeType = CorrelationAttributeInstance
|
||||||
.getDefaultCorrelationTypes()
|
.getDefaultCorrelationTypes()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(filterType -> filterType.getId() == CorrelationAttributeInstance.FILES_TYPE_ID)
|
.filter(filterType -> filterType.getId() == this.resultTypeId)
|
||||||
.findFirst().get();
|
.findFirst().get();
|
||||||
|
|
||||||
EamDb eamDb = EamDb.getInstance();
|
EamDb eamDb = EamDb.getInstance();
|
||||||
@ -113,16 +133,20 @@ final public class CommonAttributeSearchResults {
|
|||||||
|
|
||||||
for(CommonAttributeValue value : values.getDelayedMetadataList()){ // Need the real metadata
|
for(CommonAttributeValue value : values.getDelayedMetadataList()){ // Need the real metadata
|
||||||
|
|
||||||
int frequencyPercentage = eamDb.getFrequencyPercentage(new CorrelationAttributeInstance(fileAttributeType, value.getValue()));
|
try {
|
||||||
|
int frequencyPercentage = eamDb.getFrequencyPercentage(new CorrelationAttributeInstance(fileAttributeType, value.getValue()));
|
||||||
|
|
||||||
if(frequencyPercentage > maximumPercentageThreshold){
|
if(frequencyPercentage > maximumPercentageThreshold){
|
||||||
if(itemsToRemove.containsKey(key)){
|
if(itemsToRemove.containsKey(key)){
|
||||||
itemsToRemove.get(key).add(value);
|
itemsToRemove.get(key).add(value);
|
||||||
} else {
|
} else {
|
||||||
List<CommonAttributeValue> toRemove = new ArrayList<>();
|
List<CommonAttributeValue> toRemove = new ArrayList<>();
|
||||||
toRemove.add(value);
|
toRemove.add(value);
|
||||||
itemsToRemove.put(key, toRemove);
|
itemsToRemove.put(key, toRemove);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch(CorrelationAttributeNormalizationException ex){
|
||||||
|
LOGGER.log(Level.WARNING, "Unable to determine frequency percentage attribute - frequency filter may not be accurate for these results.", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,7 +178,7 @@ final public class CommonAttributeSearchResults {
|
|||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (CommonAttributeValueList data : this.instanceCountToAttributeValues.values()) {
|
for (CommonAttributeValueList data : this.instanceCountToAttributeValues.values()) {
|
||||||
for(CommonAttributeValue md5 : data.getMetadataList()){
|
for(CommonAttributeValue md5 : data.getDelayedMetadataList()){
|
||||||
count += md5.getInstanceCount();
|
count += md5.getInstanceCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,4 @@ final public class CommonAttributeValue {
|
|||||||
public int getInstanceCount() {
|
public int getInstanceCount() {
|
||||||
return this.fileInstances.size();
|
return this.fileInstances.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ public class CommonAttributeValueNode extends DisplayableItemNode {
|
|||||||
private final String dataSources;
|
private final String dataSources;
|
||||||
|
|
||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"Md5Node.Md5Node.format=MD5: %s"
|
"CommonAttributeValueNode.CommonAttributeValueNode.format=Value: %s"
|
||||||
})
|
})
|
||||||
/**
|
/**
|
||||||
* Create a Match node whose children will all have this object in common.
|
* Create a Match node whose children will all have this object in common.
|
||||||
@ -57,7 +57,7 @@ public class CommonAttributeValueNode extends DisplayableItemNode {
|
|||||||
this.dataSources = String.join(", ", data.getDataSources());
|
this.dataSources = String.join(", ", data.getDataSources());
|
||||||
this.value = data.getValue();
|
this.value = data.getValue();
|
||||||
|
|
||||||
this.setDisplayName(String.format(Bundle.Md5Node_Md5Node_format(), this.value));
|
this.setDisplayName(String.format(Bundle.CommonAttributeValueNode_CommonAttributeValueNode_format(), this.value));
|
||||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/fileset-icon-16.png"); //NON-NLS
|
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/fileset-icon-16.png"); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import java.util.Map;
|
|||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides logic for selecting common files from all data sources and all cases
|
* Provides logic for selecting common files from all data sources and all cases
|
||||||
@ -31,6 +32,10 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
|||||||
abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeSearcher {
|
abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeSearcher {
|
||||||
|
|
||||||
private final EamDb dbManager;
|
private final EamDb dbManager;
|
||||||
|
/**
|
||||||
|
* The Correlation Type to find matches on.
|
||||||
|
*/
|
||||||
|
final Type corAttrType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements the algorithm for getting common files across all data sources
|
* Implements the algorithm for getting common files across all data sources
|
||||||
@ -43,9 +48,10 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS
|
|||||||
*
|
*
|
||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
InterCaseCommonAttributeSearcher(Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType, int percentageThreshold) throws EamDbException {
|
InterCaseCommonAttributeSearcher(Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType, Type corAttrType, int percentageThreshold) throws EamDbException {
|
||||||
super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType, percentageThreshold);
|
super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType, percentageThreshold);
|
||||||
dbManager = EamDb.getInstance();
|
dbManager = EamDb.getInstance();
|
||||||
|
this.corAttrType = corAttrType;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CorrelationCase getCorrelationCaseFromId(int correlationCaseId) throws EamDbException {
|
protected CorrelationCase getCorrelationCaseFromId(int correlationCaseId) throws EamDbException {
|
||||||
@ -56,4 +62,5 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS
|
|||||||
}
|
}
|
||||||
throw new IllegalArgumentException("Cannot locate case.");
|
throw new IllegalArgumentException("Cannot locate case.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,11 +24,17 @@
|
|||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="anyCentralRepoCaseRadio" alignment="0" min="-2" max="-2" attributes="0"/>
|
<Component id="anyCentralRepoCaseRadio" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
<Group type="102" attributes="0">
|
|
||||||
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
|
|
||||||
<Component id="caseComboBox" min="-2" pref="261" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<Component id="specificCentralRepoCaseRadio" min="-2" max="-2" attributes="0"/>
|
<Component id="specificCentralRepoCaseRadio" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace min="-2" pref="21" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="1" attributes="0">
|
||||||
|
<Component id="caseComboBox" min="-2" pref="261" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" alignment="1" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="comboBoxLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="correlationTypeComboBox" min="-2" pref="260" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
@ -42,6 +48,11 @@
|
|||||||
<Component id="specificCentralRepoCaseRadio" min="-2" max="-2" attributes="0"/>
|
<Component id="specificCentralRepoCaseRadio" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="caseComboBox" min="-2" max="-2" attributes="0"/>
|
<Component id="caseComboBox" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="comboBoxLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="correlationTypeComboBox" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
@ -85,5 +96,25 @@
|
|||||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||||
</AuxValues>
|
</AuxValues>
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="comboBoxLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.comboBoxLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JComboBox" name="correlationTypeComboBox">
|
||||||
|
<Properties>
|
||||||
|
<Property name="selectedItem" type="java.lang.Object" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
|
<Connection code="null" type="code"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.correlationTypeComboBox.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -21,9 +21,13 @@ package org.sleuthkit.autopsy.commonfilesearch;
|
|||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import javax.swing.ComboBoxModel;
|
import javax.swing.ComboBoxModel;
|
||||||
|
import org.openide.util.Exceptions;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UI controls for Common Files Search scenario where the user intends to find
|
* UI controls for Common Files Search scenario where the user intends to find
|
||||||
@ -43,6 +47,8 @@ public class InterCasePanel extends javax.swing.JPanel {
|
|||||||
// false if we must find matches in a given case plus the current case
|
// false if we must find matches in a given case plus the current case
|
||||||
private boolean anyCase;
|
private boolean anyCase;
|
||||||
|
|
||||||
|
private Map<String, CorrelationAttributeInstance.Type> correlationTypeFilters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new form InterCasePanel
|
* Creates new form InterCasePanel
|
||||||
*/
|
*/
|
||||||
@ -50,6 +56,8 @@ public class InterCasePanel extends javax.swing.JPanel {
|
|||||||
initComponents();
|
initComponents();
|
||||||
this.caseMap = new HashMap<>();
|
this.caseMap = new HashMap<>();
|
||||||
this.anyCase = true;
|
this.anyCase = true;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void specificCaseSelected(boolean selected) {
|
private void specificCaseSelected(boolean selected) {
|
||||||
@ -60,6 +68,25 @@ public class InterCasePanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the EamDB is enabled, the UI will populate the correlation type ComboBox with
|
||||||
|
* available types in the CR.
|
||||||
|
*/
|
||||||
|
void setupCorrelationTypeFilter() {
|
||||||
|
this.correlationTypeFilters = new HashMap<>();
|
||||||
|
try {
|
||||||
|
List<CorrelationAttributeInstance.Type> types = CorrelationAttributeInstance.getDefaultCorrelationTypes();
|
||||||
|
for (CorrelationAttributeInstance.Type type : types) {
|
||||||
|
correlationTypeFilters.put(type.getDisplayName(), type);
|
||||||
|
this.correlationTypeComboBox.addItem(type.getDisplayName());
|
||||||
|
}
|
||||||
|
} catch (EamDbException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
}
|
||||||
|
this.correlationTypeComboBox.setSelectedIndex(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called from within the constructor to initialize the form.
|
* 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
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
@ -73,6 +100,8 @@ public class InterCasePanel extends javax.swing.JPanel {
|
|||||||
anyCentralRepoCaseRadio = new javax.swing.JRadioButton();
|
anyCentralRepoCaseRadio = new javax.swing.JRadioButton();
|
||||||
specificCentralRepoCaseRadio = new javax.swing.JRadioButton();
|
specificCentralRepoCaseRadio = new javax.swing.JRadioButton();
|
||||||
caseComboBox = new javax.swing.JComboBox<>();
|
caseComboBox = new javax.swing.JComboBox<>();
|
||||||
|
comboBoxLabel = new javax.swing.JLabel();
|
||||||
|
correlationTypeComboBox = new javax.swing.JComboBox<>();
|
||||||
|
|
||||||
buttonGroup.add(anyCentralRepoCaseRadio);
|
buttonGroup.add(anyCentralRepoCaseRadio);
|
||||||
anyCentralRepoCaseRadio.setSelected(true);
|
anyCentralRepoCaseRadio.setSelected(true);
|
||||||
@ -94,6 +123,11 @@ public class InterCasePanel extends javax.swing.JPanel {
|
|||||||
caseComboBox.setModel(casesList);
|
caseComboBox.setModel(casesList);
|
||||||
caseComboBox.setEnabled(false);
|
caseComboBox.setEnabled(false);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(comboBoxLabel, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.comboBoxLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
correlationTypeComboBox.setSelectedItem(null);
|
||||||
|
correlationTypeComboBox.setToolTipText(org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.correlationTypeComboBox.toolTipText")); // NOI18N
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
@ -102,10 +136,14 @@ public class InterCasePanel extends javax.swing.JPanel {
|
|||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(anyCentralRepoCaseRadio)
|
.addComponent(anyCentralRepoCaseRadio)
|
||||||
|
.addComponent(specificCentralRepoCaseRadio)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(21, 21, 21)
|
.addGap(21, 21, 21)
|
||||||
.addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||||
.addComponent(specificCentralRepoCaseRadio))
|
.addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(comboBoxLabel)
|
||||||
|
.addComponent(correlationTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 260, javax.swing.GroupLayout.PREFERRED_SIZE)))))
|
||||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
@ -115,7 +153,12 @@ public class InterCasePanel extends javax.swing.JPanel {
|
|||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(specificCentralRepoCaseRadio)
|
.addComponent(specificCentralRepoCaseRadio)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(comboBoxLabel)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(correlationTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
@ -137,6 +180,8 @@ public class InterCasePanel extends javax.swing.JPanel {
|
|||||||
private javax.swing.JRadioButton anyCentralRepoCaseRadio;
|
private javax.swing.JRadioButton anyCentralRepoCaseRadio;
|
||||||
private javax.swing.ButtonGroup buttonGroup;
|
private javax.swing.ButtonGroup buttonGroup;
|
||||||
private javax.swing.JComboBox<String> caseComboBox;
|
private javax.swing.JComboBox<String> caseComboBox;
|
||||||
|
private javax.swing.JLabel comboBoxLabel;
|
||||||
|
private javax.swing.JComboBox<String> correlationTypeComboBox;
|
||||||
private javax.swing.JRadioButton specificCentralRepoCaseRadio;
|
private javax.swing.JRadioButton specificCentralRepoCaseRadio;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
@ -181,4 +226,12 @@ public class InterCasePanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
return InterCasePanel.NO_CASE_SELECTED;
|
return InterCasePanel.NO_CASE_SELECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the selected Correlation Type by getting the Type from the stored HashMap.
|
||||||
|
* @return Type the selected Correlation Type to query for.
|
||||||
|
*/
|
||||||
|
CorrelationAttributeInstance.Type getSelectedCorrelationType() {
|
||||||
|
return correlationTypeFilters.get(this.correlationTypeComboBox.getSelectedItem().toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,10 +26,13 @@ import java.util.Map;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance.Type;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.InstanceTableCallback;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.InstanceTableCallback;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.datamodel.TskData;
|
import org.sleuthkit.datamodel.TskData;
|
||||||
@ -42,46 +45,87 @@ import org.sleuthkit.datamodel.HashUtility;
|
|||||||
final class InterCaseSearchResultsProcessor {
|
final class InterCaseSearchResultsProcessor {
|
||||||
|
|
||||||
private Map<Long, String> dataSources;
|
private Map<Long, String> dataSources;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The CorrelationAttributeInstance.Type this Processor will query on
|
||||||
|
*/
|
||||||
|
private final Type correlationType;
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(CommonAttributePanel.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(CommonAttributePanel.class.getName());
|
||||||
|
|
||||||
private final String interCaseWhereClause = "value IN (SELECT value FROM file_instances"
|
|
||||||
+ " WHERE value IN (SELECT value FROM file_instances"
|
|
||||||
+ " WHERE case_id=%s AND (known_status !=%s OR known_status IS NULL) GROUP BY value)"
|
|
||||||
+ " GROUP BY value HAVING COUNT(DISTINCT case_id) > 1) ORDER BY value";
|
|
||||||
|
|
||||||
private final String singleInterCaseWhereClause = "value IN (SELECT value FROM file_instances "
|
|
||||||
+ "WHERE value IN (SELECT value FROM file_instances "
|
|
||||||
+ "WHERE case_id=%s AND (known_status !=%s OR known_status IS NULL) GROUP BY value) "
|
|
||||||
+ "AND (case_id=%s OR case_id=%s) GROUP BY value HAVING COUNT(DISTINCT case_id) > 1) ORDER BY value";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used in the InterCaseCommonAttributeSearchers to find common attribute instances and generate nodes at the UI level.
|
* The initial CorrelationAttributeInstance ids lookup query.
|
||||||
* @param dataSources
|
|
||||||
*/
|
*/
|
||||||
InterCaseSearchResultsProcessor(Map<Long, String> dataSources){
|
private final String interCaseWhereClause;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The single CorrelationAttributeInstance object retrieval query
|
||||||
|
*/
|
||||||
|
private final String singleInterCaseWhereClause;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used in the InterCaseCommonAttributeSearchers to find common attribute
|
||||||
|
* instances and generate nodes at the UI level.
|
||||||
|
*
|
||||||
|
* @param dataSources the cases to filter and correlate on
|
||||||
|
* @param theType the type of CR data to search
|
||||||
|
*/
|
||||||
|
InterCaseSearchResultsProcessor(Map<Long, String> dataSources, CorrelationAttributeInstance.Type theType) {
|
||||||
|
this.correlationType = theType;
|
||||||
this.dataSources = dataSources;
|
this.dataSources = dataSources;
|
||||||
|
interCaseWhereClause = getInterCaseWhereClause();
|
||||||
|
singleInterCaseWhereClause = getSingleInterCaseWhereClause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getInterCaseWhereClause() {
|
||||||
|
String tableName = EamDbUtil.correlationTypeToInstanceTableName(correlationType);
|
||||||
|
StringBuilder sqlString = new StringBuilder(250);
|
||||||
|
sqlString.append("value IN (SELECT value FROM ")
|
||||||
|
.append(tableName)
|
||||||
|
.append(" WHERE value IN (SELECT value FROM ")
|
||||||
|
.append(tableName)
|
||||||
|
.append(" WHERE case_id=%s AND (known_status !=%s OR known_status IS NULL) GROUP BY value)")
|
||||||
|
.append(" GROUP BY value HAVING COUNT(DISTINCT case_id) > 1) ORDER BY value");
|
||||||
|
return sqlString.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getSingleInterCaseWhereClause() {
|
||||||
|
String tableName = EamDbUtil.correlationTypeToInstanceTableName(correlationType);
|
||||||
|
StringBuilder sqlString = new StringBuilder(250);
|
||||||
|
sqlString.append("value IN (SELECT value FROM ")
|
||||||
|
.append(tableName)
|
||||||
|
.append(" WHERE value IN (SELECT value FROM ")
|
||||||
|
.append(tableName)
|
||||||
|
.append(" WHERE case_id=%s AND (known_status !=%s OR known_status IS NULL) GROUP BY value)")
|
||||||
|
.append(" AND (case_id=%s OR case_id=%s) GROUP BY value HAVING COUNT(DISTINCT case_id) > 1) ORDER BY value");
|
||||||
|
return sqlString.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used in the CentralRepoCommonAttributeInstance to find common attribute instances and generate nodes at the UI level.
|
* Used in the CentralRepoCommonAttributeInstance to find common attribute
|
||||||
|
* instances and generate nodes at the UI level.
|
||||||
|
*
|
||||||
|
* @param theType the type of CR data to search
|
||||||
*/
|
*/
|
||||||
InterCaseSearchResultsProcessor(){
|
InterCaseSearchResultsProcessor(CorrelationAttributeInstance.Type theType) {
|
||||||
//intentionally emtpy - we need a constructor which does not set the data sources field
|
this.correlationType = theType;
|
||||||
|
interCaseWhereClause = getInterCaseWhereClause();
|
||||||
|
singleInterCaseWhereClause = getSingleInterCaseWhereClause();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a single CorrelationAttribute given an id.
|
* Finds a single CorrelationAttribute given an id.
|
||||||
*
|
*
|
||||||
* @param attrbuteId Row of CorrelationAttribute to retrieve from the EamDb
|
* @param attrbuteId Row of CorrelationAttribute to retrieve from the EamDb
|
||||||
|
*
|
||||||
* @return CorrelationAttribute object representation of retrieved match
|
* @return CorrelationAttribute object representation of retrieved match
|
||||||
*/
|
*/
|
||||||
CorrelationAttributeInstance findSingleCorrelationAttribute(int attrbuteId) {
|
CorrelationAttributeInstance findSingleCorrelationAttribute(int attrbuteId) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
InterCaseCommonAttributeRowCallback instancetableCallback = new InterCaseCommonAttributeRowCallback();
|
InterCaseCommonAttributeRowCallback instancetableCallback = new InterCaseCommonAttributeRowCallback();
|
||||||
EamDb DbManager = EamDb.getInstance();
|
EamDb DbManager = EamDb.getInstance();
|
||||||
CorrelationAttributeInstance.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID);
|
DbManager.processInstanceTableWhere(correlationType, String.format("id = %s", attrbuteId), instancetableCallback);
|
||||||
DbManager.processInstanceTableWhere(fileType, String.format("id = %s", attrbuteId), instancetableCallback);
|
|
||||||
|
|
||||||
return instancetableCallback.getCorrelationAttribute();
|
return instancetableCallback.getCorrelationAttribute();
|
||||||
|
|
||||||
@ -102,15 +146,15 @@ final class InterCaseSearchResultsProcessor {
|
|||||||
try {
|
try {
|
||||||
InterCaseCommonAttributesCallback instancetableCallback = new InterCaseCommonAttributesCallback();
|
InterCaseCommonAttributesCallback instancetableCallback = new InterCaseCommonAttributesCallback();
|
||||||
EamDb DbManager = EamDb.getInstance();
|
EamDb DbManager = EamDb.getInstance();
|
||||||
CorrelationAttributeInstance.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID);
|
|
||||||
int caseId = DbManager.getCase(currentCase).getID();
|
int caseId = DbManager.getCase(currentCase).getID();
|
||||||
|
|
||||||
DbManager.processInstanceTableWhere(fileType, String.format(interCaseWhereClause, caseId,
|
DbManager.processInstanceTableWhere(correlationType, String.format(interCaseWhereClause, caseId,
|
||||||
TskData.FileKnown.KNOWN.getFileKnownValue()),
|
TskData.FileKnown.KNOWN.getFileKnownValue()),
|
||||||
instancetableCallback);
|
instancetableCallback);
|
||||||
|
|
||||||
return instancetableCallback.getInstanceCollatedCommonFiles();
|
return instancetableCallback.getInstanceCollatedCommonFiles();
|
||||||
|
|
||||||
} catch (EamDbException ex) {
|
} catch (EamDbException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex);
|
LOGGER.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex);
|
||||||
}
|
}
|
||||||
@ -123,16 +167,15 @@ final class InterCaseSearchResultsProcessor {
|
|||||||
* md5 and case.
|
* md5 and case.
|
||||||
*
|
*
|
||||||
* @param currentCase The current TSK Case.
|
* @param currentCase The current TSK Case.
|
||||||
* @param singleCase The case of interest. Matches must exist in this case.
|
* @param singleCase The case of interest. Matches must exist in this case.
|
||||||
*/
|
*/
|
||||||
Map<Integer, CommonAttributeValueList> findSingleInterCaseCommonAttributeValues(Case currentCase, CorrelationCase singleCase) {
|
Map<Integer, CommonAttributeValueList> findSingleInterCaseCommonAttributeValues(Case currentCase, CorrelationCase singleCase) {
|
||||||
try {
|
try {
|
||||||
InterCaseCommonAttributesCallback instancetableCallback = new InterCaseCommonAttributesCallback();
|
InterCaseCommonAttributesCallback instancetableCallback = new InterCaseCommonAttributesCallback();
|
||||||
EamDb DbManager = EamDb.getInstance();
|
EamDb DbManager = EamDb.getInstance();
|
||||||
CorrelationAttributeInstance.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID);
|
|
||||||
int caseId = DbManager.getCase(currentCase).getID();
|
int caseId = DbManager.getCase(currentCase).getID();
|
||||||
int targetCaseId = singleCase.getID();
|
int targetCaseId = singleCase.getID();
|
||||||
DbManager.processInstanceTableWhere(fileType, String.format(singleInterCaseWhereClause, caseId,
|
DbManager.processInstanceTableWhere(correlationType, String.format(singleInterCaseWhereClause, caseId,
|
||||||
TskData.FileKnown.KNOWN.getFileKnownValue(), caseId, targetCaseId), instancetableCallback);
|
TskData.FileKnown.KNOWN.getFileKnownValue(), caseId, targetCaseId), instancetableCallback);
|
||||||
return instancetableCallback.getInstanceCollatedCommonFiles();
|
return instancetableCallback.getInstanceCollatedCommonFiles();
|
||||||
} catch (EamDbException ex) {
|
} catch (EamDbException ex) {
|
||||||
@ -158,27 +201,42 @@ final class InterCaseSearchResultsProcessor {
|
|||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
|
|
||||||
int resultId = InstanceTableCallback.getId(resultSet);
|
int resultId = InstanceTableCallback.getId(resultSet);
|
||||||
String md5Value = InstanceTableCallback.getValue(resultSet);
|
String corValue = InstanceTableCallback.getValue(resultSet);
|
||||||
if (previousRowMd5.isEmpty()) {
|
if (previousRowMd5.isEmpty()) {
|
||||||
previousRowMd5 = md5Value;
|
previousRowMd5 = corValue;
|
||||||
}
|
}
|
||||||
if (md5Value == null || HashUtility.isNoDataMd5(md5Value)) {
|
if (corValue == null || HashUtility.isNoDataMd5(corValue)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
countAndAddCommonAttributes(md5Value, resultId);
|
countAndAddCommonAttributes(corValue, resultId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
//Add the final instances
|
||||||
|
CommonAttributeValueList value = new CommonAttributeValueList();
|
||||||
|
if (commonAttributeValue != null) {
|
||||||
|
value.addMetadataToList(commonAttributeValue);
|
||||||
|
instanceCollatedCommonFiles.put(commonAttributeValue.getInstanceCount(), value);
|
||||||
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS
|
LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void countAndAddCommonAttributes(String md5Value, int resultId) {
|
/**
|
||||||
|
* Add a resultId to the list of matches for a given corValue, which
|
||||||
|
* counts to number of instances of that match, determining which
|
||||||
|
* InstanceCountNode the match will be added to.
|
||||||
|
*
|
||||||
|
* @param corValue the value which matches
|
||||||
|
* @param resultId the CorrelationAttributeInstance id to be retrieved
|
||||||
|
* later.
|
||||||
|
*/
|
||||||
|
private void countAndAddCommonAttributes(String corValue, int resultId) {
|
||||||
if (commonAttributeValue == null) {
|
if (commonAttributeValue == null) {
|
||||||
commonAttributeValue = new CommonAttributeValue(md5Value);
|
commonAttributeValue = new CommonAttributeValue(corValue);
|
||||||
}
|
}
|
||||||
if (!md5Value.equals(previousRowMd5)) {
|
if (!corValue.equals(previousRowMd5)) {
|
||||||
int size = commonAttributeValue.getInstanceCount();
|
int size = commonAttributeValue.getInstanceCount();
|
||||||
if (instanceCollatedCommonFiles.containsKey(size)) {
|
if (instanceCollatedCommonFiles.containsKey(size)) {
|
||||||
instanceCollatedCommonFiles.get(size).addMetadataToList(commonAttributeValue);
|
instanceCollatedCommonFiles.get(size).addMetadataToList(commonAttributeValue);
|
||||||
@ -188,13 +246,13 @@ final class InterCaseSearchResultsProcessor {
|
|||||||
instanceCollatedCommonFiles.put(size, value);
|
instanceCollatedCommonFiles.put(size, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
commonAttributeValue = new CommonAttributeValue(md5Value);
|
commonAttributeValue = new CommonAttributeValue(corValue);
|
||||||
previousRowMd5 = md5Value;
|
previousRowMd5 = corValue;
|
||||||
}
|
}
|
||||||
// we don't *have* all the information for the rows in the CR,
|
// we don't *have* all the information for the rows in the CR,
|
||||||
// so we need to consult the present case via the SleuthkitCase object
|
// so we need to consult the present case via the SleuthkitCase object
|
||||||
// Later, when the FileInstanceNode is built. Therefore, build node generators for now.
|
// Later, when the FileInstanceNode is built. Therefore, build node generators for now.
|
||||||
AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(resultId, InterCaseSearchResultsProcessor.this.dataSources);
|
AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(resultId, InterCaseSearchResultsProcessor.this.dataSources, correlationType);
|
||||||
commonAttributeValue.addInstance(searchResult);
|
commonAttributeValue.addInstance(searchResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,16 +273,19 @@ final class InterCaseSearchResultsProcessor {
|
|||||||
public void process(ResultSet resultSet) {
|
public void process(ResultSet resultSet) {
|
||||||
try {
|
try {
|
||||||
EamDb DbManager = EamDb.getInstance();
|
EamDb DbManager = EamDb.getInstance();
|
||||||
CorrelationAttributeInstance.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID);
|
|
||||||
|
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
CorrelationCase correlationCase = DbManager.getCaseById(InstanceTableCallback.getCaseId(resultSet));
|
CorrelationCase correlationCase = DbManager.getCaseById(InstanceTableCallback.getCaseId(resultSet));
|
||||||
CorrelationDataSource dataSource = DbManager.getDataSourceById(correlationCase, InstanceTableCallback.getDataSourceId(resultSet));
|
CorrelationDataSource dataSource = DbManager.getDataSourceById(correlationCase, InstanceTableCallback.getDataSourceId(resultSet));
|
||||||
correlationAttributeInstance = DbManager.getCorrelationAttributeInstance(fileType,
|
try {
|
||||||
correlationCase,
|
correlationAttributeInstance = DbManager.getCorrelationAttributeInstance(correlationType,
|
||||||
dataSource,
|
correlationCase,
|
||||||
InstanceTableCallback.getValue(resultSet),
|
dataSource,
|
||||||
InstanceTableCallback.getFilePath(resultSet));
|
InstanceTableCallback.getValue(resultSet),
|
||||||
|
InstanceTableCallback.getFilePath(resultSet));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
LOGGER.log(Level.INFO, "Unable to get CorrelationAttributeInstance.", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (SQLException | EamDbException ex) {
|
} catch (SQLException | EamDbException ex) {
|
||||||
|
@ -36,8 +36,8 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Generates a <code>List<CommonFilesMetadata></code> when
|
* Generates a <code>List<CommonFilesMetadata></code> when
|
||||||
* <code>findFiles()</code> is called, which organizes files by md5 to
|
* <code>findMatches()</code> is called, which organizes files by md5 to prepare
|
||||||
* prepare to display in viewer.
|
* to display in viewer.
|
||||||
*
|
*
|
||||||
* This entire thing runs on a background thread where exceptions are handled.
|
* This entire thing runs on a background thread where exceptions are handled.
|
||||||
*/
|
*/
|
||||||
@ -93,14 +93,14 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt
|
|||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException {
|
public CommonAttributeSearchResults findMatches() throws TskCoreException, NoCurrentCaseException, SQLException {
|
||||||
Map<String, CommonAttributeValue> commonFiles = new HashMap<>();
|
Map<String, CommonAttributeValue> commonFiles = new HashMap<>();
|
||||||
|
|
||||||
final Case currentCase = Case.getCurrentCaseThrows();
|
final Case currentCase = Case.getCurrentCaseThrows();
|
||||||
final String caseName = currentCase.getDisplayName();
|
final String caseName = currentCase.getDisplayName();
|
||||||
|
|
||||||
SleuthkitCase sleuthkitCase = currentCase.getSleuthkitCase();
|
SleuthkitCase sleuthkitCase = currentCase.getSleuthkitCase();
|
||||||
|
|
||||||
String selectStatement = this.buildSqlSelectStatement();
|
String selectStatement = this.buildSqlSelectStatement();
|
||||||
|
|
||||||
try (
|
try (
|
||||||
@ -127,21 +127,21 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Integer, CommonAttributeValueList> instanceCollatedCommonFiles = collateMatchesByNumberOfInstances(commonFiles);
|
Map<Integer, CommonAttributeValueList> instanceCollatedCommonFiles = collateMatchesByNumberOfInstances(commonFiles);
|
||||||
|
|
||||||
return new CommonAttributeSearchResults(instanceCollatedCommonFiles, this.frequencyPercentageThreshold);
|
return new CommonAttributeSearchResults(instanceCollatedCommonFiles, this.frequencyPercentageThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should be used by subclasses, in their
|
* Should be used by subclasses, in their
|
||||||
* <code>buildSqlSelectStatement()</code> function to create an SQL boolean
|
* <code>buildSqlSelectStatement()</code> function to create an SQL boolean
|
||||||
* expression which will filter our matches based on mime type. The
|
* expression which will filter our matches based on mime type. The
|
||||||
* expression will be conjoined to base query with an AND operator.
|
* expression will be conjoined to base query with an AND operator.
|
||||||
*
|
*
|
||||||
* @return sql fragment of the form:
|
* @return sql fragment of the form: 'and "mime_type" in ( [comma delimited
|
||||||
* 'and "mime_type" in ( [comma delimited list of mime types] )'
|
* list of mime types] )' or empty string in the event that no types to
|
||||||
* or empty string in the event that no types to filter on were given.
|
* filter on were given.
|
||||||
*/
|
*/
|
||||||
String determineMimeTypeFilter() {
|
String determineMimeTypeFilter() {
|
||||||
|
|
||||||
|
@ -20,42 +20,44 @@
|
|||||||
package org.sleuthkit.autopsy.commonfilesearch;
|
package org.sleuthkit.autopsy.commonfilesearch;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttributeSearcher {
|
public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttributeSearcher {
|
||||||
|
|
||||||
private final int corrleationCaseId;
|
private final int corrleationCaseId;
|
||||||
private String correlationCaseName;
|
private String correlationCaseName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param correlationCaseId
|
* @param correlationCaseId
|
||||||
* @param filterByMediaMimeType
|
* @param filterByMediaMimeType
|
||||||
* @param filterByDocMimeType
|
* @param filterByDocMimeType
|
||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
public SingleInterCaseCommonAttributeSearcher(int correlationCaseId, Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType, int percentageThreshold) throws EamDbException {
|
public SingleInterCaseCommonAttributeSearcher(int correlationCaseId, Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType,
|
||||||
super(dataSourceIdMap,filterByMediaMimeType, filterByDocMimeType, percentageThreshold);
|
boolean filterByDocMimeType, Type corAttrType, int percentageThreshold) throws EamDbException {
|
||||||
|
super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType, corAttrType, percentageThreshold);
|
||||||
|
|
||||||
this.corrleationCaseId = correlationCaseId;
|
this.corrleationCaseId = correlationCaseId;
|
||||||
this.correlationCaseName = "";
|
this.correlationCaseName = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collect metadata required to render the tree table where matches must
|
* Collect metadata required to render the tree table where matches must
|
||||||
* occur in the case with the given ID.
|
* occur in the case with the given ID.
|
||||||
*
|
*
|
||||||
* @param correlationCaseId id of case where matches must occur (no other matches will be shown)
|
* @param correlationCaseId id of case where matches must occur (no other
|
||||||
|
* matches will be shown)
|
||||||
* @return business object needed to populate tree table with results
|
* @return business object needed to populate tree table with results
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
* @throws NoCurrentCaseException
|
* @throws NoCurrentCaseException
|
||||||
@ -63,24 +65,23 @@ public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttri
|
|||||||
* @throws EamDbException
|
* @throws EamDbException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException {
|
public CommonAttributeSearchResults findMatches() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException {
|
||||||
|
|
||||||
CorrelationCase cCase = this.getCorrelationCaseFromId(this.corrleationCaseId);
|
CorrelationCase cCase = this.getCorrelationCaseFromId(this.corrleationCaseId);
|
||||||
correlationCaseName = cCase.getDisplayName();
|
this.correlationCaseName = cCase.getDisplayName();
|
||||||
return this.findFiles(cCase);
|
return this.findFiles(cCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
CommonAttributeSearchResults findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException {
|
CommonAttributeSearchResults findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException {
|
||||||
InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(this.getDataSourceIdToNameMap());
|
InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(this.getDataSourceIdToNameMap(), this.corAttrType);
|
||||||
Map<Integer, CommonAttributeValueList> interCaseCommonFiles = eamDbAttrInst.findSingleInterCaseCommonAttributeValues(Case.getCurrentCase(), correlationCase);
|
Map<Integer, CommonAttributeValueList> interCaseCommonFiles = eamDbAttrInst.findSingleInterCaseCommonAttributeValues(Case.getCurrentCase(), correlationCase);
|
||||||
|
|
||||||
return new CommonAttributeSearchResults(interCaseCommonFiles, this.frequencyPercentageThreshold);
|
return new CommonAttributeSearchResults(interCaseCommonFiles, this.frequencyPercentageThreshold, this.corAttrType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String buildTabTitle() {
|
String buildTabTitle() {
|
||||||
final String buildCategorySelectionString = this.buildCategorySelectionString();
|
|
||||||
final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleInterSingle();
|
final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleInterSingle();
|
||||||
return String.format(titleTemplate, new Object[]{correlationCaseName, buildCategorySelectionString});
|
return String.format(titleTemplate, new Object[]{this.correlationCaseName, this.corAttrType.getDisplayName()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
50
Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.form
Executable file
50
Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.form
Executable file
@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<Properties>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[100, 58]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<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="false"/>
|
||||||
|
<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">
|
||||||
|
<Component id="jScrollPane5" alignment="0" pref="907" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="jScrollPane5" alignment="1" pref="435" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JScrollPane" name="jScrollPane5">
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JTextPane" name="jTextPane1">
|
||||||
|
<Properties>
|
||||||
|
<Property name="editable" type="boolean" value="false"/>
|
||||||
|
<Property name="name" type="java.lang.String" value="" noResource="true"/>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[600, 52]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
466
Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java
Executable file
466
Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java
Executable file
@ -0,0 +1,466 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2018 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.contentviewers;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.apache.commons.lang3.StringEscapeUtils;
|
||||||
|
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||||
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||||
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifactTag;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
import org.sleuthkit.datamodel.ContentTag;
|
||||||
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
|
import org.sleuthkit.datamodel.Tag;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotations view of file contents.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
||||||
|
@ServiceProvider(service = DataContentViewer.class, position = 8)
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"AnnotationsContentViewer.title=Annotations",
|
||||||
|
"AnnotationsContentViewer.toolTip=Displays tags and comments associated with the selected content."
|
||||||
|
})
|
||||||
|
public class AnnotationsContentViewer extends javax.swing.JPanel implements DataContentViewer {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(AnnotationsContentViewer.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance of AnnotationsContentViewer.
|
||||||
|
*/
|
||||||
|
public AnnotationsContentViewer() {
|
||||||
|
initComponents();
|
||||||
|
Utilities.configureTextPaneAsHtml(jTextPane1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNode(Node node) {
|
||||||
|
if ((node == null) || (!isSupported(node))) {
|
||||||
|
resetComponent();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder html = new StringBuilder();
|
||||||
|
|
||||||
|
BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class);
|
||||||
|
Content sourceFile = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (artifact != null) {
|
||||||
|
/*
|
||||||
|
* Get the source content based on the artifact to ensure we
|
||||||
|
* display the correct data instead of whatever was in the node.
|
||||||
|
*/
|
||||||
|
sourceFile = artifact.getSleuthkitCase().getAbstractFileById(artifact.getObjectID());
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* No artifact is present, so get the content based on what's
|
||||||
|
* present in the node. In this case, the selected item IS the
|
||||||
|
* source file.
|
||||||
|
*/
|
||||||
|
sourceFile = node.getLookup().lookup(AbstractFile.class);
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, String.format(
|
||||||
|
"Exception while trying to retrieve a Content instance from the BlackboardArtifact '%s' (id=%d).",
|
||||||
|
artifact.getDisplayName(), artifact.getArtifactID()), ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (artifact != null) {
|
||||||
|
populateTagData(html, artifact, sourceFile);
|
||||||
|
} else {
|
||||||
|
populateTagData(html, sourceFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sourceFile instanceof AbstractFile) {
|
||||||
|
populateCentralRepositoryData(html, artifact, (AbstractFile) sourceFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
setText(html.toString());
|
||||||
|
jTextPane1.setCaretPosition(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the "Selected Item" sections with tag data for the supplied
|
||||||
|
* content.
|
||||||
|
*
|
||||||
|
* @param html The HTML text to update.
|
||||||
|
* @param content Selected content.
|
||||||
|
*/
|
||||||
|
private void populateTagData(StringBuilder html, Content content) {
|
||||||
|
try {
|
||||||
|
SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||||
|
|
||||||
|
startSection(html, "Selected Item");
|
||||||
|
List<ContentTag> fileTagsList = tskCase.getContentTagsByContent(content);
|
||||||
|
if (fileTagsList.isEmpty()) {
|
||||||
|
addMessage(html, "There are no tags for the selected content.");
|
||||||
|
} else {
|
||||||
|
for (ContentTag tag : fileTagsList) {
|
||||||
|
addTagEntry(html, tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endSection(html);
|
||||||
|
} catch (NoCurrentCaseException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Exception while getting open case.", ex); // NON-NLS
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Exception while getting tags from the case database.", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the "Selected Item" and "Source File" sections with tag data for
|
||||||
|
* a supplied artifact.
|
||||||
|
*
|
||||||
|
* @param html The HTML text to update.
|
||||||
|
* @param artifact A selected artifact.
|
||||||
|
* @param sourceFile The source content of the selected artifact.
|
||||||
|
*/
|
||||||
|
private void populateTagData(StringBuilder html, BlackboardArtifact artifact, Content sourceFile) {
|
||||||
|
try {
|
||||||
|
SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||||
|
|
||||||
|
startSection(html, "Selected Item");
|
||||||
|
List<BlackboardArtifactTag> artifactTagsList = tskCase.getBlackboardArtifactTagsByArtifact(artifact);
|
||||||
|
if (artifactTagsList.isEmpty()) {
|
||||||
|
addMessage(html, "There are no tags for the selected artifact.");
|
||||||
|
} else {
|
||||||
|
for (BlackboardArtifactTag tag : artifactTagsList) {
|
||||||
|
addTagEntry(html, tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endSection(html);
|
||||||
|
|
||||||
|
if (sourceFile != null) {
|
||||||
|
startSection(html, "Source File");
|
||||||
|
List<ContentTag> fileTagsList = tskCase.getContentTagsByContent(sourceFile);
|
||||||
|
if (fileTagsList.isEmpty()) {
|
||||||
|
addMessage(html, "There are no tags for the source content.");
|
||||||
|
} else {
|
||||||
|
for (ContentTag tag : fileTagsList) {
|
||||||
|
addTagEntry(html, tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endSection(html);
|
||||||
|
}
|
||||||
|
} catch (NoCurrentCaseException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Exception while getting open case.", ex); // NON-NLS
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Exception while getting tags from the case database.", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the "Central Repository Comments" section with data.
|
||||||
|
*
|
||||||
|
* @param html The HTML text to update.
|
||||||
|
* @param artifact A selected artifact (can be null).
|
||||||
|
* @param sourceFile A selected file, or a source file of the selected
|
||||||
|
* artifact.
|
||||||
|
*/
|
||||||
|
private void populateCentralRepositoryData(StringBuilder html, BlackboardArtifact artifact, AbstractFile sourceFile) {
|
||||||
|
if (EamDb.isEnabled()) {
|
||||||
|
startSection(html, "Central Repository Comments");
|
||||||
|
List<CorrelationAttributeInstance> instancesList = new ArrayList<>();
|
||||||
|
if (artifact != null) {
|
||||||
|
instancesList.addAll(EamArtifactUtil.makeInstancesFromBlackboardArtifact(artifact, false));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
List<CorrelationAttributeInstance.Type> artifactTypes = EamDb.getInstance().getDefinedCorrelationTypes();
|
||||||
|
String md5 = sourceFile.getMd5Hash();
|
||||||
|
if (md5 != null && !md5.isEmpty() && null != artifactTypes && !artifactTypes.isEmpty()) {
|
||||||
|
for (CorrelationAttributeInstance.Type attributeType : artifactTypes) {
|
||||||
|
if (attributeType.getId() == CorrelationAttributeInstance.FILES_TYPE_ID) {
|
||||||
|
CorrelationCase correlationCase = EamDb.getInstance().getCase(Case.getCurrentCase());
|
||||||
|
instancesList.add(new CorrelationAttributeInstance(
|
||||||
|
md5,
|
||||||
|
attributeType,
|
||||||
|
correlationCase,
|
||||||
|
CorrelationDataSource.fromTSKDataSource(correlationCase, sourceFile.getDataSource()),
|
||||||
|
sourceFile.getParentPath() + sourceFile.getName(),
|
||||||
|
"",
|
||||||
|
sourceFile.getKnown()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean commentDataFound = false;
|
||||||
|
|
||||||
|
for (CorrelationAttributeInstance instance : instancesList) {
|
||||||
|
List<CorrelationAttributeInstance> correlatedInstancesList =
|
||||||
|
EamDb.getInstance().getArtifactInstancesByTypeValue(instance.getCorrelationType(), instance.getCorrelationValue());
|
||||||
|
for (CorrelationAttributeInstance correlatedInstance : correlatedInstancesList) {
|
||||||
|
if (correlatedInstance.getComment() != null && correlatedInstance.getComment().isEmpty() == false) {
|
||||||
|
commentDataFound = true;
|
||||||
|
addCentralRepositoryEntry(html, correlatedInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commentDataFound == false) {
|
||||||
|
addMessage(html, "There is no comment data for the selected content in the central repository.");
|
||||||
|
}
|
||||||
|
} catch (EamDbException | TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error connecting to the central repository database.", ex); // NON-NLS
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error normalizing instance from repository database.", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
endSection(html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the text of the text panel.
|
||||||
|
*
|
||||||
|
* @param text The text to set to the text panel.
|
||||||
|
*/
|
||||||
|
private void setText(String text) {
|
||||||
|
jTextPane1.setText("<html><body>" + text + "</body></html>"); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a new data section.
|
||||||
|
*
|
||||||
|
* @param html The HTML text to add the section to.
|
||||||
|
* @param sectionName The name of the section.
|
||||||
|
*/
|
||||||
|
private void startSection(StringBuilder html, String sectionName) {
|
||||||
|
html.append("<p style=\"font-size:14px;font-weight:bold;\">")
|
||||||
|
.append(sectionName)
|
||||||
|
.append("</p><br>"); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a message.
|
||||||
|
*
|
||||||
|
* @param html The HTML text to add the message to.
|
||||||
|
* @param message The message text.
|
||||||
|
*/
|
||||||
|
private void addMessage(StringBuilder html, String message) {
|
||||||
|
html.append("<p style=\"font-style:italic;\">")
|
||||||
|
.append(message)
|
||||||
|
.append("</p><br>"); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a data table containing information about a tag.
|
||||||
|
*
|
||||||
|
* @param html The HTML text to add the table to.
|
||||||
|
* @param tag The tag whose information will be used to populate the table.
|
||||||
|
*/
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"AnnotationsContentViewer.tagEntryDataLabel.tag=Tag:",
|
||||||
|
"AnnotationsContentViewer.tagEntryDataLabel.tagUser=Tag User:",
|
||||||
|
"AnnotationsContentViewer.tagEntryDataLabel.comment=Comment:"
|
||||||
|
})
|
||||||
|
private void addTagEntry(StringBuilder html, Tag tag) {
|
||||||
|
startTable(html);
|
||||||
|
addRow(html, Bundle.AnnotationsContentViewer_tagEntryDataLabel_tag(), tag.getName().getDisplayName());
|
||||||
|
addRow(html, Bundle.AnnotationsContentViewer_tagEntryDataLabel_tagUser(), tag.getUserName());
|
||||||
|
addRow(html, Bundle.AnnotationsContentViewer_tagEntryDataLabel_comment(), formatHtmlString(tag.getComment()));
|
||||||
|
endTable(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a data table containing information about a correlation attribute
|
||||||
|
* instance in the central repository.
|
||||||
|
*
|
||||||
|
* @param html The HTML text to add the table to.
|
||||||
|
* @param attributeInstance The attribute instance whose information will be
|
||||||
|
* used to populate the table.
|
||||||
|
* @param correlationType The correlation data type.
|
||||||
|
*/
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"AnnotationsContentViewer.centralRepositoryEntryDataLabel.case=Case:",
|
||||||
|
"AnnotationsContentViewer.centralRepositoryEntryDataLabel.type=Type:",
|
||||||
|
"AnnotationsContentViewer.centralRepositoryEntryDataLabel.comment=Comment:",
|
||||||
|
"AnnotationsContentViewer.centralRepositoryEntryDataLabel.path=Path:"
|
||||||
|
})
|
||||||
|
private void addCentralRepositoryEntry(StringBuilder html, CorrelationAttributeInstance attributeInstance) {
|
||||||
|
startTable(html);
|
||||||
|
addRow(html, Bundle.AnnotationsContentViewer_centralRepositoryEntryDataLabel_case(), attributeInstance.getCorrelationCase().getDisplayName());
|
||||||
|
addRow(html, Bundle.AnnotationsContentViewer_centralRepositoryEntryDataLabel_type(), attributeInstance.getCorrelationType().getDisplayName());
|
||||||
|
addRow(html, Bundle.AnnotationsContentViewer_centralRepositoryEntryDataLabel_comment(), formatHtmlString(attributeInstance.getComment()));
|
||||||
|
addRow(html, Bundle.AnnotationsContentViewer_centralRepositoryEntryDataLabel_path(), attributeInstance.getFilePath());
|
||||||
|
endTable(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a data table.
|
||||||
|
*
|
||||||
|
* @param html The HTML text to add the table to.
|
||||||
|
*/
|
||||||
|
private void startTable(StringBuilder html) {
|
||||||
|
html.append("<table>"); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a data row to a table.
|
||||||
|
*
|
||||||
|
* @param html The HTML text to add the row to.
|
||||||
|
* @param key The key for the left column of the data row.
|
||||||
|
* @param value The value for the right column of the data row.
|
||||||
|
*/
|
||||||
|
private void addRow(StringBuilder html, String key, String value) {
|
||||||
|
html.append("<tr><td valign=\"top\">"); //NON-NLS
|
||||||
|
html.append(key);
|
||||||
|
html.append("</td><td>"); //NON-NLS
|
||||||
|
html.append(value);
|
||||||
|
html.append("</td></tr>"); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End a data table.
|
||||||
|
*
|
||||||
|
* @param html The HTML text on which to end a table.
|
||||||
|
*/
|
||||||
|
private void endTable(StringBuilder html) {
|
||||||
|
html.append("</table><br><br>"); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End a data section.
|
||||||
|
*
|
||||||
|
* @param html The HTML text on which to end a section.
|
||||||
|
*/
|
||||||
|
private void endSection(StringBuilder html) {
|
||||||
|
html.append("<br>"); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply escape sequence to special characters. Line feed and carriage
|
||||||
|
* return character combinations will be converted to HTML line breaks.
|
||||||
|
*
|
||||||
|
* @param text The text to format.
|
||||||
|
* @return The formatted text.
|
||||||
|
*/
|
||||||
|
private String formatHtmlString(String text) {
|
||||||
|
String formattedString = StringEscapeUtils.escapeHtml4(text);
|
||||||
|
return formattedString.replaceAll("(\r\n|\r|\n|\n\r)", "<br>");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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() {
|
||||||
|
|
||||||
|
jScrollPane5 = new javax.swing.JScrollPane();
|
||||||
|
jTextPane1 = new javax.swing.JTextPane();
|
||||||
|
|
||||||
|
setPreferredSize(new java.awt.Dimension(100, 58));
|
||||||
|
|
||||||
|
jTextPane1.setEditable(false);
|
||||||
|
jTextPane1.setName(""); // NOI18N
|
||||||
|
jTextPane1.setPreferredSize(new java.awt.Dimension(600, 52));
|
||||||
|
jScrollPane5.setViewportView(jTextPane1);
|
||||||
|
|
||||||
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
|
this.setLayout(layout);
|
||||||
|
layout.setHorizontalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 907, Short.MAX_VALUE)
|
||||||
|
);
|
||||||
|
layout.setVerticalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(jScrollPane5, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 435, Short.MAX_VALUE)
|
||||||
|
);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JScrollPane jScrollPane5;
|
||||||
|
private javax.swing.JTextPane jTextPane1;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTitle() {
|
||||||
|
return Bundle.AnnotationsContentViewer_title();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getToolTip() {
|
||||||
|
return Bundle.AnnotationsContentViewer_toolTip();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataContentViewer createInstance() {
|
||||||
|
return new AnnotationsContentViewer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSupported(Node node) {
|
||||||
|
BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (artifact != null) {
|
||||||
|
if (artifact.getSleuthkitCase().getAbstractFileById(artifact.getObjectID()) != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (node.getLookup().lookup(AbstractFile.class) != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, String.format(
|
||||||
|
"Exception while trying to retrieve a Content instance from the BlackboardArtifact '%s' (id=%d).",
|
||||||
|
artifact.getDisplayName(), artifact.getArtifactID()), ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int isPreferred(Node node) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getComponent() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetComponent() {
|
||||||
|
setText("");
|
||||||
|
}
|
||||||
|
}
|
@ -46,4 +46,4 @@ Metadata.toolTip=\u30d5\u30a1\u30a4\u30eb\u306e\u30e1\u30bf\u30c7\u30fc\u30bf\u3
|
|||||||
Metadata.tableRowTitle.type=\u30bf\u30a4\u30d7
|
Metadata.tableRowTitle.type=\u30bf\u30a4\u30d7
|
||||||
Metadata.nodeText.exceptionNotice.text=\u30d5\u30a1\u30a4\u30eb\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a
|
Metadata.nodeText.exceptionNotice.text=\u30d5\u30a1\u30a4\u30eb\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a
|
||||||
Metadata.nodeText.text=Sleuth Kit istat\u30c4\u30fc\u30eb\u304b\u3089\uff1a
|
Metadata.nodeText.text=Sleuth Kit istat\u30c4\u30fc\u30eb\u304b\u3089\uff1a
|
||||||
Metadata.nodeText.nonFilePassedIn=\u5165\u529b\u3055\u308c\u305f\u3082\u306e\u306f\u30d5\u30a1\u30a4\u30eb\u3067\u306f\u3042\u308a\u307e\u305b\u3093
|
Metadata.nodeText.nonFilePassedIn=\u5165\u529b\u3055\u308c\u305f\u3082\u306e\u306f\u30d5\u30a1\u30a4\u30eb\u3067\u306f\u3042\u308a\u307e\u305b\u3093
|
||||||
|
@ -77,7 +77,7 @@
|
|||||||
</folder>
|
</folder>
|
||||||
<folder name="Tools">
|
<folder name="Tools">
|
||||||
<file name="org-sleuthkit-autopsy-filesearch-FileSearchAction.instance"/>
|
<file name="org-sleuthkit-autopsy-filesearch-FileSearchAction.instance"/>
|
||||||
<file name="org-sleuthkit-autopsy-commonfilesearch-CommonFilesSearchAction.instance"/>
|
<file name="org-sleuthkit-autopsy-commonfilesearch-CommonAttributeSearchAction.instance"/>
|
||||||
<file name="org-sleuthkit-autopsy-ingest-IngestMessagesAction.instance">
|
<file name="org-sleuthkit-autopsy-ingest-IngestMessagesAction.instance">
|
||||||
<attr name="delegate" newvalue="org.sleuthkit.autopsy.ingest.IngestMessagesAction"/>
|
<attr name="delegate" newvalue="org.sleuthkit.autopsy.ingest.IngestMessagesAction"/>
|
||||||
</file>
|
</file>
|
||||||
@ -198,7 +198,7 @@
|
|||||||
<file name="org-netbeans-modules-templates-actions-TemplatesAction.shadow_hidden"/>
|
<file name="org-netbeans-modules-templates-actions-TemplatesAction.shadow_hidden"/>
|
||||||
<file name="org-openide-actions-ToolsAction.shadow_hidden"/>
|
<file name="org-openide-actions-ToolsAction.shadow_hidden"/>
|
||||||
<file name="org-sleuthkit-autopsy-commonfilesearch-CommonFilesAction.shadow">
|
<file name="org-sleuthkit-autopsy-commonfilesearch-CommonFilesAction.shadow">
|
||||||
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-commonfilesearch-CommonFilesSearchAction.instance"/>
|
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-commonfilesearch-CommonAttributeSearchAction.instance"/>
|
||||||
<attr name="position" intvalue="103"/>
|
<attr name="position" intvalue="103"/>
|
||||||
</file>
|
</file>
|
||||||
<file name="org-sleuthkit-autopsy-filesearch-FileSearchAction.shadow">
|
<file name="org-sleuthkit-autopsy-filesearch-FileSearchAction.shadow">
|
||||||
|
@ -86,6 +86,7 @@ HashDbImportDatabaseDialog.failedToGetDbPathMsg=Failed to get the path of the se
|
|||||||
HashDbImportDatabaseDialog.importHashDbErr=Import Hash Set Error
|
HashDbImportDatabaseDialog.importHashDbErr=Import Hash Set Error
|
||||||
HashDbImportDatabaseDialog.mustSelectHashDbFilePathMsg=A hash set file path must be selected.
|
HashDbImportDatabaseDialog.mustSelectHashDbFilePathMsg=A hash set file path must be selected.
|
||||||
HashDbImportDatabaseDialog.hashDbDoesNotExistMsg=The selected hash set does not exist.
|
HashDbImportDatabaseDialog.hashDbDoesNotExistMsg=The selected hash set does not exist.
|
||||||
|
HashDbImportDatabaseDialog.unableToCopyToUserDirMsg=Unable to copy the hash set to user configuration directory {0}.
|
||||||
HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg=Failed to open hash set at {0}.
|
HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg=Failed to open hash set at {0}.
|
||||||
HashLookupModuleFactory.moduleName.text=Hash Lookup
|
HashLookupModuleFactory.moduleName.text=Hash Lookup
|
||||||
HashLookupModuleFactory.moduleDescription.text=Identifies known and notable files using supplied hash sets, such as a standard NSRL hash set.
|
HashLookupModuleFactory.moduleDescription.text=Identifies known and notable files using supplied hash sets, such as a standard NSRL hash set.
|
||||||
@ -237,3 +238,5 @@ HashDbCreateDatabaseDialog.lbOrg.text=Source Organization:
|
|||||||
HashDbCreateDatabaseDialog.orgButton.text=Manage Organizations
|
HashDbCreateDatabaseDialog.orgButton.text=Manage Organizations
|
||||||
HashDbCreateDatabaseDialog.databasePathLabel.text=Hash Set Path:
|
HashDbCreateDatabaseDialog.databasePathLabel.text=Hash Set Path:
|
||||||
AddHashValuesToDatabaseDialog.okButton.text_2=OK
|
AddHashValuesToDatabaseDialog.okButton.text_2=OK
|
||||||
|
HashDbImportDatabaseDialog.saveInUserConfigFolderCheckbox.text=Copy hash set into user configuration folder
|
||||||
|
HashDbImportDatabaseDialog.saveInUserConfigFolderCheckbox.toolTipText=In Live Triage situations, this option ensures that path to the hash set will be valid
|
||||||
|
@ -60,6 +60,7 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
|||||||
private final static String LAST_FILE_PATH_KEY = "HashDbCreate_Path";
|
private final static String LAST_FILE_PATH_KEY = "HashDbCreate_Path";
|
||||||
private EamOrganization selectedOrg = null;
|
private EamOrganization selectedOrg = null;
|
||||||
private List<EamOrganization> orgs = null;
|
private List<EamOrganization> orgs = null;
|
||||||
|
static final String HASH_DATABASE_DIR_NAME = "HashDatabases";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays a dialog that allows a user to create a new hash database and
|
* Displays a dialog that allows a user to create a new hash database and
|
||||||
@ -404,7 +405,7 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
|||||||
|
|
||||||
private void saveAsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveAsButtonActionPerformed
|
private void saveAsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveAsButtonActionPerformed
|
||||||
try {
|
try {
|
||||||
String lastBaseDirectory = Paths.get(PlatformUtil.getUserConfigDirectory(), "HashDatabases").toString();
|
String lastBaseDirectory = Paths.get(PlatformUtil.getUserConfigDirectory(), HASH_DATABASE_DIR_NAME).toString();
|
||||||
if (ModuleSettings.settingExists(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY)) {
|
if (ModuleSettings.settingExists(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY)) {
|
||||||
lastBaseDirectory = ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY);
|
lastBaseDirectory = ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
<Layout>
|
<Layout>
|
||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
@ -86,6 +86,7 @@
|
|||||||
</Group>
|
</Group>
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="saveInUserConfigFolderCheckbox" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
|
<Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="readOnlyCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
<Component id="readOnlyCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
@ -145,7 +146,9 @@
|
|||||||
<Component id="readOnlyCheckbox" min="-2" max="-2" attributes="0"/>
|
<Component id="readOnlyCheckbox" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="sendIngestMessagesCheckbox" min="-2" max="-2" attributes="0"/>
|
<Component id="sendIngestMessagesCheckbox" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="0" pref="39" max="32767" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="saveInUserConfigFolderCheckbox" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="0" pref="29" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="1" attributes="0">
|
<Group type="102" alignment="1" attributes="0">
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
@ -354,5 +357,15 @@
|
|||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component class="javax.swing.JCheckBox" name="saveInUserConfigFolderCheckbox">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.saveInUserConfigFolderCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.saveInUserConfigFolderCheckbox.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -27,6 +27,7 @@ import javax.swing.JFileChooser;
|
|||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
@ -180,6 +181,7 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
|||||||
fileTypeRadioButton = new javax.swing.JRadioButton();
|
fileTypeRadioButton = new javax.swing.JRadioButton();
|
||||||
centralRepoRadioButton = new javax.swing.JRadioButton();
|
centralRepoRadioButton = new javax.swing.JRadioButton();
|
||||||
jLabel4 = new javax.swing.JLabel();
|
jLabel4 = new javax.swing.JLabel();
|
||||||
|
saveInUserConfigFolderCheckbox = new javax.swing.JCheckBox();
|
||||||
|
|
||||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||||
|
|
||||||
@ -286,6 +288,9 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
|||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(jLabel4, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.jLabel4.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel4, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.jLabel4.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(saveInUserConfigFolderCheckbox, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.saveInUserConfigFolderCheckbox.text")); // NOI18N
|
||||||
|
saveInUserConfigFolderCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.saveInUserConfigFolderCheckbox.toolTipText")); // NOI18N
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||||
getContentPane().setLayout(layout);
|
getContentPane().setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
@ -334,6 +339,7 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
|||||||
.addComponent(cancelButton))
|
.addComponent(cancelButton))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(saveInUserConfigFolderCheckbox)
|
||||||
.addComponent(jLabel2)
|
.addComponent(jLabel2)
|
||||||
.addComponent(readOnlyCheckbox)
|
.addComponent(readOnlyCheckbox)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
@ -384,7 +390,9 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
|||||||
.addComponent(readOnlyCheckbox)
|
.addComponent(readOnlyCheckbox)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(sendIngestMessagesCheckbox)
|
.addComponent(sendIngestMessagesCheckbox)
|
||||||
.addGap(0, 39, Short.MAX_VALUE))
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(saveInUserConfigFolderCheckbox)
|
||||||
|
.addGap(0, 29, Short.MAX_VALUE))
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||||
.addGap(0, 0, Short.MAX_VALUE)
|
.addGap(0, 0, Short.MAX_VALUE)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
@ -397,7 +405,7 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
|||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
private void openButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openButtonActionPerformed
|
private void openButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openButtonActionPerformed
|
||||||
String lastBaseDirectory = Paths.get(PlatformUtil.getUserConfigDirectory(), "HashDatabases").toString();
|
String lastBaseDirectory = Paths.get(PlatformUtil.getUserConfigDirectory(), HashDbCreateDatabaseDialog.HASH_DATABASE_DIR_NAME).toString();
|
||||||
if (ModuleSettings.settingExists(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY)) {
|
if (ModuleSettings.settingExists(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY)) {
|
||||||
lastBaseDirectory = ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY);
|
lastBaseDirectory = ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY);
|
||||||
}
|
}
|
||||||
@ -492,6 +500,7 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
|||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
File file = new File(selectedFilePath);
|
File file = new File(selectedFilePath);
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
JOptionPane.showMessageDialog(this,
|
JOptionPane.showMessageDialog(this,
|
||||||
@ -503,6 +512,22 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (saveInUserConfigFolderCheckbox.isSelected()) {
|
||||||
|
// copy the hash database to user configuration directory and use that path instead (JIRA-4177)
|
||||||
|
String locationInUserConfigDir = Paths.get(PlatformUtil.getUserConfigDirectory(), HashDbCreateDatabaseDialog.HASH_DATABASE_DIR_NAME, hashSetNameTextField.getText(), file.getName()).toString();
|
||||||
|
try {
|
||||||
|
FileUtils.copyFile(file, new File(locationInUserConfigDir));
|
||||||
|
// update the hash database location
|
||||||
|
selectedFilePath = locationInUserConfigDir;
|
||||||
|
} catch (IOException ex) {
|
||||||
|
String errorMessage = NbBundle.getMessage(this.getClass(), "HashDbImportDatabaseDialog.unableToCopyToUserDirMsg", locationInUserConfigDir);
|
||||||
|
Logger.getLogger(HashDbImportDatabaseDialog.class.getName()).log(Level.SEVERE, errorMessage, ex);
|
||||||
|
JOptionPane.showMessageDialog(this, errorMessage, NbBundle.getMessage(this.getClass(), "HashDbImportDatabaseDialog.importHashDbErr"),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
KnownFilesType type;
|
KnownFilesType type;
|
||||||
if (knownRadioButton.isSelected()) {
|
if (knownRadioButton.isSelected()) {
|
||||||
type = KnownFilesType.KNOWN;
|
type = KnownFilesType.KNOWN;
|
||||||
@ -622,6 +647,7 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
|||||||
private javax.swing.JButton orgButton;
|
private javax.swing.JButton orgButton;
|
||||||
private javax.swing.JComboBox<String> orgComboBox;
|
private javax.swing.JComboBox<String> orgComboBox;
|
||||||
private javax.swing.JCheckBox readOnlyCheckbox;
|
private javax.swing.JCheckBox readOnlyCheckbox;
|
||||||
|
private javax.swing.JCheckBox saveInUserConfigFolderCheckbox;
|
||||||
private javax.swing.JCheckBox sendIngestMessagesCheckbox;
|
private javax.swing.JCheckBox sendIngestMessagesCheckbox;
|
||||||
private javax.swing.ButtonGroup storageTypeButtonGroup;
|
private javax.swing.ButtonGroup storageTypeButtonGroup;
|
||||||
private javax.swing.JTextField versionTextField;
|
private javax.swing.JTextField versionTextField;
|
||||||
|
@ -39,6 +39,7 @@ import org.netbeans.api.progress.ProgressHandle;
|
|||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||||
@ -644,7 +645,7 @@ public class HashDbManager implements PropertyChangeListener {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getValidFilePath(String hashSetName, String configuredPath) {
|
private String getValidFilePath(String hashSetName, String configuredPath) {
|
||||||
// Check the configured path.
|
// Check the configured path.
|
||||||
File database = new File(configuredPath);
|
File database = new File(configuredPath);
|
||||||
if (database.exists()) {
|
if (database.exists()) {
|
||||||
@ -1238,8 +1239,8 @@ public class HashDbManager implements PropertyChangeListener {
|
|||||||
EamGlobalFileInstance fileInstance = new EamGlobalFileInstance(referenceSetID, file.getMd5Hash(),
|
EamGlobalFileInstance fileInstance = new EamGlobalFileInstance(referenceSetID, file.getMd5Hash(),
|
||||||
type, comment);
|
type, comment);
|
||||||
EamDb.getInstance().addReferenceInstance(fileInstance,EamDb.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID));
|
EamDb.getInstance().addReferenceInstance(fileInstance,EamDb.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID));
|
||||||
} catch (EamDbException ex){
|
} catch (EamDbException | CorrelationAttributeNormalizationException ex){
|
||||||
throw new TskCoreException("Error adding hashes to " + getDisplayName(), ex);
|
throw new TskCoreException("Error adding hashes to " + getDisplayName(), ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1264,7 +1265,7 @@ public class HashDbManager implements PropertyChangeListener {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
globalFileInstances.add(new EamGlobalFileInstance(referenceSetID, hashEntry.getMd5Hash(), type, hashEntry.getComment()));
|
globalFileInstances.add(new EamGlobalFileInstance(referenceSetID, hashEntry.getMd5Hash(), type, hashEntry.getComment()));
|
||||||
} catch (EamDbException ex){
|
} catch (EamDbException | CorrelationAttributeNormalizationException ex){
|
||||||
throw new TskCoreException("Error adding hashes to " + getDisplayName(), ex);
|
throw new TskCoreException("Error adding hashes to " + getDisplayName(), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1295,7 +1296,7 @@ public class HashDbManager implements PropertyChangeListener {
|
|||||||
if (null != file.getMd5Hash()) {
|
if (null != file.getMd5Hash()) {
|
||||||
try{
|
try{
|
||||||
return EamDb.getInstance().isFileHashInReferenceSet(file.getMd5Hash(), this.referenceSetID);
|
return EamDb.getInstance().isFileHashInReferenceSet(file.getMd5Hash(), this.referenceSetID);
|
||||||
} catch (EamDbException ex){
|
} catch (EamDbException | CorrelationAttributeNormalizationException ex){
|
||||||
Logger.getLogger(SleuthkitHashSet.class.getName()).log(Level.SEVERE, "Error performing central reposiotry hash lookup for hash "
|
Logger.getLogger(SleuthkitHashSet.class.getName()).log(Level.SEVERE, "Error performing central reposiotry hash lookup for hash "
|
||||||
+ file.getMd5Hash() + " in reference set " + referenceSetID, ex); //NON-NLS
|
+ file.getMd5Hash() + " in reference set " + referenceSetID, ex); //NON-NLS
|
||||||
throw new TskCoreException("Error performing central reposiotry hash lookup", ex);
|
throw new TskCoreException("Error performing central reposiotry hash lookup", ex);
|
||||||
@ -1327,7 +1328,7 @@ public class HashDbManager implements PropertyChangeListener {
|
|||||||
// Make a bare-bones HashHitInfo for now
|
// Make a bare-bones HashHitInfo for now
|
||||||
result = new HashHitInfo(file.getMd5Hash(), "", "");
|
result = new HashHitInfo(file.getMd5Hash(), "", "");
|
||||||
}
|
}
|
||||||
} catch (EamDbException ex){
|
} catch (EamDbException | CorrelationAttributeNormalizationException ex){
|
||||||
Logger.getLogger(SleuthkitHashSet.class.getName()).log(Level.SEVERE, "Error performing central reposiotry hash lookup for hash "
|
Logger.getLogger(SleuthkitHashSet.class.getName()).log(Level.SEVERE, "Error performing central reposiotry hash lookup for hash "
|
||||||
+ file.getMd5Hash() + " in reference set " + referenceSetID, ex); //NON-NLS
|
+ file.getMd5Hash() + " in reference set " + referenceSetID, ex); //NON-NLS
|
||||||
throw new TskCoreException("Error performing central reposiotry hash lookup", ex);
|
throw new TskCoreException("Error performing central reposiotry hash lookup", ex);
|
||||||
|
@ -62,6 +62,9 @@ final class HashLookupSettings implements Serializable {
|
|||||||
private static final String CONFIG_FILE_NAME = "hashsets.xml"; //NON-NLS
|
private static final String CONFIG_FILE_NAME = "hashsets.xml"; //NON-NLS
|
||||||
private static final String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + CONFIG_FILE_NAME;
|
private static final String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + CONFIG_FILE_NAME;
|
||||||
private static final Logger logger = Logger.getLogger(HashDbManager.class.getName());
|
private static final Logger logger = Logger.getLogger(HashDbManager.class.getName());
|
||||||
|
|
||||||
|
private static final String USER_DIR_PLACEHOLDER = "[UserConfigFolder]";
|
||||||
|
private static final String CURRENT_USER_DIR = PlatformUtil.getUserConfigDirectory();
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private final List<HashDbInfo> hashDbInfoList;
|
private final List<HashDbInfo> hashDbInfoList;
|
||||||
@ -122,10 +125,17 @@ final class HashLookupSettings implements Serializable {
|
|||||||
* @throws HashLookupSettingsException If there's a problem importing the
|
* @throws HashLookupSettingsException If there's a problem importing the
|
||||||
* settings
|
* settings
|
||||||
*/
|
*/
|
||||||
private static HashLookupSettings readSerializedSettings() throws HashLookupSettingsException {
|
private static HashLookupSettings readSerializedSettings() throws HashLookupSettingsException {
|
||||||
try {
|
try {
|
||||||
try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(SERIALIZATION_FILE_PATH))) {
|
try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(SERIALIZATION_FILE_PATH))) {
|
||||||
HashLookupSettings filesSetsSettings = (HashLookupSettings) in.readObject();
|
HashLookupSettings filesSetsSettings = (HashLookupSettings) in.readObject();
|
||||||
|
|
||||||
|
/* NOTE: to support JIRA-4177, we need to check if any of the hash
|
||||||
|
database paths are in Windows user directory. If so, we replace the path
|
||||||
|
with USER_DIR_PLACEHOLDER before saving to disk. When reading from disk,
|
||||||
|
USER_DIR_PLACEHOLDER needs to be replaced with current user directory path.
|
||||||
|
*/
|
||||||
|
convertPlaceholderToPath(filesSetsSettings);
|
||||||
return filesSetsSettings;
|
return filesSetsSettings;
|
||||||
}
|
}
|
||||||
} catch (IOException | ClassNotFoundException ex) {
|
} catch (IOException | ClassNotFoundException ex) {
|
||||||
@ -282,8 +292,16 @@ final class HashLookupSettings implements Serializable {
|
|||||||
*/
|
*/
|
||||||
static boolean writeSettings(HashLookupSettings settings) {
|
static boolean writeSettings(HashLookupSettings settings) {
|
||||||
|
|
||||||
|
/* NOTE: to support JIRA-4177, we need to check if any of the hash
|
||||||
|
database paths are in Windows user directory. If so, replace the path
|
||||||
|
with USER_DIR_PLACEHOLDER so that when it is read, it gets updated to be
|
||||||
|
the current user directory path.
|
||||||
|
*/
|
||||||
|
convertPathToPlaceholder(settings);
|
||||||
try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(SERIALIZATION_FILE_PATH))) {
|
try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(SERIALIZATION_FILE_PATH))) {
|
||||||
out.writeObject(settings);
|
out.writeObject(settings);
|
||||||
|
// restore the paths, in case they are going to be used somewhere
|
||||||
|
convertPlaceholderToPath(settings);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
logger.log(Level.SEVERE, "Could not write hash set settings.");
|
logger.log(Level.SEVERE, "Could not write hash set settings.");
|
||||||
@ -291,13 +309,54 @@ final class HashLookupSettings implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For file type hash sets, check if hash set paths needs to be modified
|
||||||
|
* per JIRA-4177. If the file path is in current Windows user directory,
|
||||||
|
* replace the path with USER_DIR_PLACEHOLDER.
|
||||||
|
*
|
||||||
|
* @param settings HashLookupSettings settings object to examiner and modify
|
||||||
|
*/
|
||||||
|
static void convertPathToPlaceholder(HashLookupSettings settings) {
|
||||||
|
for (HashDbInfo hashDbInfo : settings.getHashDbInfo()) {
|
||||||
|
if (hashDbInfo.isFileDatabaseType()) {
|
||||||
|
String dbPath = hashDbInfo.getPath();
|
||||||
|
if (dbPath.startsWith(CURRENT_USER_DIR)) {
|
||||||
|
// replace the current user directory with place holder
|
||||||
|
String remainingPath = dbPath.substring(CURRENT_USER_DIR.length());
|
||||||
|
hashDbInfo.setPath(USER_DIR_PLACEHOLDER + remainingPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For file type hash sets, check if hash set paths needs to be modified per
|
||||||
|
* JIRA-4177. Replace USER_DIR_PLACEHOLDER with path to current Windows user
|
||||||
|
* directory.
|
||||||
|
*
|
||||||
|
* @param settings HashLookupSettings settings object to examiner and modify
|
||||||
|
*/
|
||||||
|
static void convertPlaceholderToPath(HashLookupSettings settings) {
|
||||||
|
for (HashDbInfo hashDbInfo : settings.getHashDbInfo()) {
|
||||||
|
if (hashDbInfo.isFileDatabaseType()) {
|
||||||
|
String dbPath = hashDbInfo.getPath();
|
||||||
|
if (dbPath.startsWith(USER_DIR_PLACEHOLDER)) {
|
||||||
|
// replace the place holder with current user directory
|
||||||
|
String remainingPath = dbPath.substring(USER_DIR_PLACEHOLDER.length());
|
||||||
|
hashDbInfo.setPath(CURRENT_USER_DIR + remainingPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the serializable information within a hash lookup in order to
|
* Represents the serializable information within a hash lookup in order to
|
||||||
* be written to disk. Used to hand off information when loading and saving
|
* be written to disk. Used to hand off information when loading and saving
|
||||||
* hash lookups.
|
* hash lookups.
|
||||||
*/
|
*/
|
||||||
static final class HashDbInfo implements Serializable {
|
static final class HashDbInfo implements Serializable {
|
||||||
|
|
||||||
enum DatabaseType{
|
enum DatabaseType{
|
||||||
FILE,
|
FILE,
|
||||||
CENTRAL_REPOSITORY
|
CENTRAL_REPOSITORY
|
||||||
@ -308,7 +367,7 @@ final class HashLookupSettings implements Serializable {
|
|||||||
private final HashDbManager.HashDb.KnownFilesType knownFilesType;
|
private final HashDbManager.HashDb.KnownFilesType knownFilesType;
|
||||||
private boolean searchDuringIngest;
|
private boolean searchDuringIngest;
|
||||||
private final boolean sendIngestMessages;
|
private final boolean sendIngestMessages;
|
||||||
private final String path;
|
private String path;
|
||||||
private final String version;
|
private final String version;
|
||||||
private final boolean readOnly;
|
private final boolean readOnly;
|
||||||
private final int referenceSetID;
|
private final int referenceSetID;
|
||||||
@ -345,7 +404,7 @@ final class HashLookupSettings implements Serializable {
|
|||||||
this.searchDuringIngest = searchDuringIngest;
|
this.searchDuringIngest = searchDuringIngest;
|
||||||
this.sendIngestMessages = sendIngestMessages;
|
this.sendIngestMessages = sendIngestMessages;
|
||||||
this.path = "";
|
this.path = "";
|
||||||
dbType = DatabaseType.CENTRAL_REPOSITORY;
|
dbType = DatabaseType.CENTRAL_REPOSITORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
HashDbInfo(HashDbManager.HashDb db) throws TskCoreException{
|
HashDbInfo(HashDbManager.HashDb db) throws TskCoreException{
|
||||||
@ -445,6 +504,14 @@ final class HashLookupSettings implements Serializable {
|
|||||||
*/
|
*/
|
||||||
String getPath() {
|
String getPath() {
|
||||||
return path;
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the path.
|
||||||
|
* @param path the path to set
|
||||||
|
*/
|
||||||
|
public void setPath(String path) {
|
||||||
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getReferenceSetID(){
|
int getReferenceSetID(){
|
||||||
|
@ -1068,13 +1068,17 @@ class TableReportGenerator {
|
|||||||
orderedRowData.add(makeCommaSeparatedList(getTags()));
|
orderedRowData.add(makeCommaSeparatedList(getTags()));
|
||||||
|
|
||||||
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() == getArtifact().getArtifactTypeID()) {
|
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() == getArtifact().getArtifactTypeID()) {
|
||||||
String[] attributeDataArray = new String[3];
|
String[] attributeDataArray = new String[5];
|
||||||
// Array is used so that order of the attributes is maintained.
|
// Array is used so that order of the attributes is maintained.
|
||||||
for (BlackboardAttribute attr : attributes) {
|
for (BlackboardAttribute attr : attributes) {
|
||||||
if (attr.getAttributeType().equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME))) {
|
if (attr.getAttributeType().equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME))) {
|
||||||
attributeDataArray[0] = attr.getDisplayString();
|
attributeDataArray[0] = attr.getDisplayString();
|
||||||
} else if (attr.getAttributeType().equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY))) {
|
} else if (attr.getAttributeType().equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY))) {
|
||||||
attributeDataArray[1] = attr.getDisplayString();
|
attributeDataArray[1] = attr.getDisplayString();
|
||||||
|
} else if (attr.getAttributeType().equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT))) {
|
||||||
|
attributeDataArray[3] = attr.getDisplayString();
|
||||||
|
} else if (attr.getAttributeType().equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION))) {
|
||||||
|
attributeDataArray[4] = attr.getDisplayString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1163,6 +1167,7 @@ class TableReportGenerator {
|
|||||||
*
|
*
|
||||||
* @return List<String> row titles
|
* @return List<String> row titles
|
||||||
*/
|
*/
|
||||||
|
@Messages({"ReportGenerator.artTableColHdr.comment=Comment"})
|
||||||
private List<Column> getArtifactTableColumns(int artifactTypeId, Set<BlackboardAttribute.Type> attributeTypeSet) {
|
private List<Column> getArtifactTableColumns(int artifactTypeId, Set<BlackboardAttribute.Type> attributeTypeSet) {
|
||||||
ArrayList<Column> columns = new ArrayList<>();
|
ArrayList<Column> columns = new ArrayList<>();
|
||||||
|
|
||||||
@ -1557,6 +1562,12 @@ class TableReportGenerator {
|
|||||||
|
|
||||||
columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskPath"),
|
columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskPath"),
|
||||||
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)));
|
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)));
|
||||||
|
|
||||||
|
columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.comment"),
|
||||||
|
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT)));
|
||||||
|
|
||||||
|
columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.description"),
|
||||||
|
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION)));
|
||||||
|
|
||||||
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID() == artifactTypeId) {
|
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID() == artifactTypeId) {
|
||||||
columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskGpsRouteCategory"),
|
columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskGpsRouteCategory"),
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,315 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2018 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.centralrepository.datamodel;
|
||||||
|
|
||||||
|
import junit.framework.Test;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.netbeans.junit.NbModuleSuite;
|
||||||
|
import org.netbeans.junit.NbTestCase;
|
||||||
|
import org.openide.util.Exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for validation on each correlation attribute type.
|
||||||
|
*/
|
||||||
|
public class CorrelationAttributeNormalizerTest extends NbTestCase {
|
||||||
|
|
||||||
|
public static Test suite() {
|
||||||
|
NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(CorrelationAttributeNormalizerTest.class).
|
||||||
|
clusters(".*").
|
||||||
|
enableModules(".*");
|
||||||
|
return conf.suite();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CorrelationAttributeNormalizerTest(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testValidateMd5() {
|
||||||
|
final String aValidHash = "e34a8899ef6468b74f8a1048419ccc8b"; //should pass
|
||||||
|
final String anInValidHash = "e34asdfa8899ef6468b74f8a1048419ccc8b"; //should fail
|
||||||
|
final String aValidHashWithCaps = "E34A8899EF6468B74F8A1048419CCC8B"; //should pass and be lowered
|
||||||
|
final String emptyHash = ""; //should fail
|
||||||
|
final String nullHash = null; //should fail
|
||||||
|
|
||||||
|
final int FILES_TYPE_ID = CorrelationAttributeInstance.FILES_TYPE_ID;
|
||||||
|
|
||||||
|
try {
|
||||||
|
assertTrue("This hash should just work", CorrelationAttributeNormalizer.normalize(FILES_TYPE_ID, aValidHash).equals(aValidHash));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
assertTrue("This hash just needs to be converted to lower case", CorrelationAttributeNormalizer.normalize(CorrelationAttributeInstance.FILES_TYPE_ID, aValidHashWithCaps).equals(aValidHash));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(FILES_TYPE_ID, anInValidHash);
|
||||||
|
fail(THIS_SHOULD_HAVE_THROWN_AN_EXCEPTION);
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(FILES_TYPE_ID, emptyHash);
|
||||||
|
fail(THIS_SHOULD_HAVE_THROWN_AN_EXCEPTION);
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(FILES_TYPE_ID, nullHash);
|
||||||
|
fail(THIS_SHOULD_HAVE_THROWN_AN_EXCEPTION);
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static final String WE_EXPECT_AN_EXCEPTION_HERE = "We expect an exception here.";
|
||||||
|
private static final String THIS_SHOULD_HAVE_THROWN_AN_EXCEPTION = "This should have thrown an exception.";
|
||||||
|
|
||||||
|
public void testValidateDomain() {
|
||||||
|
final String goodDomainOne = "www.test.com"; //should pass
|
||||||
|
final String badDomainTwo = "http://www.test.com"; //should fail (includes protocol)
|
||||||
|
final String goodDomainThree = "test.com"; //should pass
|
||||||
|
final String badDomainFour = "http://1270.0.1"; //should fail
|
||||||
|
final String badDomainFive = "?>\\/)(*&.com"; //should fail
|
||||||
|
final String badDomainSix = null; //should fail
|
||||||
|
final String badDomainSeven = ""; //should fail
|
||||||
|
final String badDomainEight = "HTTP://tests.com"; //should fail
|
||||||
|
final String badDomainNine = "http://www.test.com/aPage?aQuestion=aParam&anotherQuestion=anotherParam"; //should fail
|
||||||
|
final String goodDomainTen = "WWW.TEST.COM"; //should pass but be lowered
|
||||||
|
final String goodDomainEleven = "TEST.COM"; //should pass but be lowered
|
||||||
|
|
||||||
|
final int DOMAIN_TYPE_ID = CorrelationAttributeInstance.DOMAIN_TYPE_ID;
|
||||||
|
|
||||||
|
try {
|
||||||
|
assertTrue(THIS_DOMAIN_SHOULD_PASS, CorrelationAttributeNormalizer.normalize(DOMAIN_TYPE_ID, goodDomainOne).equals(goodDomainOne));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(DOMAIN_TYPE_ID, badDomainTwo);
|
||||||
|
fail(THIS_SHOULD_HAVE_THROWN_AN_EXCEPTION);
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
assertTrue(THIS_DOMAIN_SHOULD_PASS, CorrelationAttributeNormalizer.normalize(DOMAIN_TYPE_ID, goodDomainThree).equals(goodDomainThree));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
assertTrue(THIS_DOMAIN_SHOULD_PASS, CorrelationAttributeNormalizer.normalize(DOMAIN_TYPE_ID, badDomainFour).equals(badDomainFour));
|
||||||
|
fail(THIS_SHOULD_HAVE_THROWN_AN_EXCEPTION);
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(DOMAIN_TYPE_ID, badDomainFive);
|
||||||
|
fail(THIS_SHOULD_HAVE_THROWN_AN_EXCEPTION);
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(DOMAIN_TYPE_ID, badDomainSix);
|
||||||
|
fail(THIS_SHOULD_HAVE_THROWN_AN_EXCEPTION);
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(DOMAIN_TYPE_ID, badDomainSeven);
|
||||||
|
fail(THIS_SHOULD_HAVE_THROWN_AN_EXCEPTION);
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(DOMAIN_TYPE_ID, badDomainEight);
|
||||||
|
fail("This should have thrown an exception");
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(DOMAIN_TYPE_ID, badDomainNine);
|
||||||
|
fail("This should have thrown an exception");
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
assertTrue(THIS_DOMAIN_SHOULD_PASS, CorrelationAttributeNormalizer.normalize(DOMAIN_TYPE_ID, goodDomainTen).equals(goodDomainTen.toLowerCase()));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
assertTrue(THIS_DOMAIN_SHOULD_PASS, CorrelationAttributeNormalizer.normalize(DOMAIN_TYPE_ID, goodDomainEleven).equals(goodDomainEleven.toLowerCase()));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static final String THIS_DOMAIN_SHOULD_PASS = "This domain should pass.";
|
||||||
|
|
||||||
|
public void testValidateEmail() {
|
||||||
|
final String goodEmailOne = "bsweeney@cipehrtechsolutions.com"; //should pass
|
||||||
|
final String goodEmailTwo = "BSWEENEY@ciphertechsolutions.com"; //should pass and be lowered
|
||||||
|
final String badEmailThree = ""; //should fail
|
||||||
|
final String badEmailFour = null; //should fail
|
||||||
|
final String badEmailFive = "asdf"; //should fail
|
||||||
|
final String goodEmailSix = "asdf@asdf"; //TODO looks bad but the lib accepts it...
|
||||||
|
final String badEmailSeven = "asdf.asdf"; //should
|
||||||
|
|
||||||
|
final int EMAIL_TYPE_ID = CorrelationAttributeInstance.EMAIL_TYPE_ID;
|
||||||
|
|
||||||
|
try {
|
||||||
|
assertTrue("This email should pass.", CorrelationAttributeNormalizer.normalize(EMAIL_TYPE_ID, goodEmailOne).equals(goodEmailOne));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
assertTrue("This email should pass.", CorrelationAttributeNormalizer.normalize(EMAIL_TYPE_ID, goodEmailTwo).equals(goodEmailTwo.toLowerCase()));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(EMAIL_TYPE_ID, badEmailThree);
|
||||||
|
fail(THIS_SHOULD_HAVE_THROWN_AN_EXCEPTION);
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(EMAIL_TYPE_ID, badEmailFour);
|
||||||
|
fail(THIS_SHOULD_HAVE_THROWN_AN_EXCEPTION);
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(EMAIL_TYPE_ID, badEmailFive);
|
||||||
|
fail(THIS_SHOULD_HAVE_THROWN_AN_EXCEPTION);
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
try { //TODO consider a better library?
|
||||||
|
assertTrue("This email should pass", CorrelationAttributeNormalizer.normalize(EMAIL_TYPE_ID, goodEmailSix).equals(goodEmailSix));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(EMAIL_TYPE_ID, badEmailSeven);
|
||||||
|
fail(THIS_SHOULD_HAVE_THROWN_AN_EXCEPTION);
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testValidatePhone() {
|
||||||
|
final String goodPnOne = "19784740486";
|
||||||
|
final String goodPnTwo = "1(978) 474-0486";
|
||||||
|
final String goodPnThree = "+19784740486";
|
||||||
|
final String goodPnFour = "1 978-474-0486";
|
||||||
|
final String badPnFive = "9879879819784740486";
|
||||||
|
final String goodPnSix = "+1(978) 474-0486";
|
||||||
|
final String goodPnSeven = "+1(978) 474-0486";
|
||||||
|
final String badPnEight = "asdfasdfasdf";
|
||||||
|
final String badPnNine = "asdf19784740486adsf";
|
||||||
|
|
||||||
|
final int PHONE_TYPE_ID = CorrelationAttributeInstance.PHONE_TYPE_ID;
|
||||||
|
|
||||||
|
try {
|
||||||
|
assertTrue(THIS_PHONE_NUMBER_SHOULD_PASS, CorrelationAttributeNormalizer.normalize(PHONE_TYPE_ID, goodPnOne).equals(goodPnOne));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
assertTrue(THIS_PHONE_NUMBER_SHOULD_PASS, CorrelationAttributeNormalizer.normalize(PHONE_TYPE_ID, goodPnTwo).equals(goodPnOne));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
assertTrue(THIS_PHONE_NUMBER_SHOULD_PASS, CorrelationAttributeNormalizer.normalize(PHONE_TYPE_ID, goodPnThree).equals(goodPnThree));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
assertTrue(THIS_PHONE_NUMBER_SHOULD_PASS, CorrelationAttributeNormalizer.normalize(PHONE_TYPE_ID, goodPnFour).equals(goodPnOne));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(PHONE_TYPE_ID, badPnFive);
|
||||||
|
//fail("This should have thrown an exception."); //this will eventually pass when we do a better job at this
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
assertTrue(THIS_PHONE_NUMBER_SHOULD_PASS, CorrelationAttributeNormalizer.normalize(PHONE_TYPE_ID, goodPnSix).equals(goodPnThree));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
assertTrue(THIS_PHONE_NUMBER_SHOULD_PASS, CorrelationAttributeNormalizer.normalize(PHONE_TYPE_ID, goodPnSeven).equals(goodPnThree));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(PHONE_TYPE_ID, badPnEight);
|
||||||
|
fail("This should have thrown an exception.");
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CorrelationAttributeNormalizer.normalize(PHONE_TYPE_ID, badPnNine);
|
||||||
|
fail("This should have thrown an exception.");
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
assertTrue(WE_EXPECT_AN_EXCEPTION_HERE, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static final String THIS_PHONE_NUMBER_SHOULD_PASS = "This phone number should pass.";
|
||||||
|
|
||||||
|
public void testValidateUsbId() {
|
||||||
|
//TODO will need to be updated once usb validation does somethign interesting
|
||||||
|
final String goodIdOne = "0202:AAFF"; //should pass
|
||||||
|
/*final String goodIdTwo = "0202:aaff"; //should pass
|
||||||
|
final String badIdThree = "0202:axxf"; //should fail
|
||||||
|
final String badIdFour = ""; //should fail
|
||||||
|
final String badIdFive = null; //should fail
|
||||||
|
final String goodIdSix = "0202 AAFF"; //should pass
|
||||||
|
final String goodIdSeven = "0202AAFF"; //should pass
|
||||||
|
final String goodIdEight = "0202-AAFF"; //should pass*/
|
||||||
|
|
||||||
|
final int USBID_TYPE_ID = CorrelationAttributeInstance.USBID_TYPE_ID;
|
||||||
|
|
||||||
|
try {
|
||||||
|
assertTrue(THIS_USB_ID_SHOULD_PASS, CorrelationAttributeNormalizer.normalize(USBID_TYPE_ID, goodIdOne).equals(goodIdOne));
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
Assert.fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static final String THIS_USB_ID_SHOULD_PASS = "This USB ID should pass.";
|
||||||
|
}
|
@ -0,0 +1,174 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2018 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.commonfilessearch;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Map;
|
||||||
|
import junit.framework.Assert;
|
||||||
|
import junit.framework.Test;
|
||||||
|
import org.netbeans.junit.NbModuleSuite;
|
||||||
|
import org.netbeans.junit.NbTestCase;
|
||||||
|
import org.openide.util.Exceptions;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||||
|
import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher;
|
||||||
|
import org.sleuthkit.autopsy.commonfilesearch.AllInterCaseCommonAttributeSearcher;
|
||||||
|
import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults;
|
||||||
|
import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.CASE1;
|
||||||
|
import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.CASE2;
|
||||||
|
import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.CASE3;
|
||||||
|
import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.CASE4;
|
||||||
|
import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.verifyInstanceCount;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for commonality in different sorts of attributes (files, usb devices,
|
||||||
|
* emails, domains). Observe that frequency filtering works for various types.
|
||||||
|
*
|
||||||
|
* TODO (JIRA-4166): The following tests are commented out because the
|
||||||
|
* functional test framework needs to be able to configure the keyword search
|
||||||
|
* ingest module to produce instances of the correlation attributes for the
|
||||||
|
* tests. This cannot be easily done at present because the keyword search
|
||||||
|
* module resides in an NBM with a dependency on the Autopsy-Core NBM; the
|
||||||
|
* otherwise obvious solution of publicly exposing the keyword search module
|
||||||
|
* settings fails due to a circular dependency.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CommonAttributeSearchInterCaseTests extends NbTestCase {
|
||||||
|
|
||||||
|
private final InterCaseTestUtils utils;
|
||||||
|
|
||||||
|
public static Test suite() {
|
||||||
|
NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(CommonAttributeSearchInterCaseTests.class).
|
||||||
|
clusters(".*").
|
||||||
|
enableModules(".*");
|
||||||
|
return conf.suite();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommonAttributeSearchInterCaseTests(String name) {
|
||||||
|
super(name);
|
||||||
|
this.utils = new InterCaseTestUtils(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() {
|
||||||
|
this.utils.clearTestDir();
|
||||||
|
try {
|
||||||
|
this.utils.enableCentralRepo();
|
||||||
|
|
||||||
|
String[] cases = new String[]{
|
||||||
|
CASE1,
|
||||||
|
CASE2,
|
||||||
|
CASE3,
|
||||||
|
CASE4};
|
||||||
|
|
||||||
|
Path[][] paths = {
|
||||||
|
{this.utils.attrCase1Path},
|
||||||
|
{this.utils.attrCase2Path},
|
||||||
|
{this.utils.attrCase3Path},
|
||||||
|
{this.utils.attrCase4Path}};
|
||||||
|
|
||||||
|
this.utils.createCases(cases, paths, this.utils.getIngestSettingsForKitchenSink(), InterCaseTestUtils.CASE1);
|
||||||
|
} catch (TskCoreException | EamDbException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
Assert.fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tearDown() {
|
||||||
|
this.utils.clearTestDir();
|
||||||
|
this.utils.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run a search on the given type and ensure that all results are off that
|
||||||
|
* type.
|
||||||
|
*
|
||||||
|
* No frequency filtering applied.
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
*/
|
||||||
|
private void assertResultsAreOfType(CorrelationAttributeInstance.Type type) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
||||||
|
|
||||||
|
AbstractCommonAttributeSearcher builder = new AllInterCaseCommonAttributeSearcher(dataSources, false, false, type, 0);
|
||||||
|
|
||||||
|
CommonAttributeSearchResults metadata = builder.findMatches();
|
||||||
|
|
||||||
|
metadata.size();
|
||||||
|
|
||||||
|
assertFalse(verifyInstanceCount(metadata, 0));
|
||||||
|
|
||||||
|
assertTrue(this.utils.areAllResultsOfType(metadata, type));
|
||||||
|
|
||||||
|
} catch (TskCoreException | NoCurrentCaseException | SQLException | EamDbException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
Assert.fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that a search for each type returns results of that type only.
|
||||||
|
*/
|
||||||
|
public void testOne() {
|
||||||
|
// assertResultsAreOfType(this.utils.USB_ID_TYPE);
|
||||||
|
// assertResultsAreOfType(this.utils.DOMAIN_TYPE);
|
||||||
|
// assertResultsAreOfType(this.utils.FILE_TYPE);
|
||||||
|
// assertResultsAreOfType(this.utils.EMAIL_TYPE);
|
||||||
|
// assertResultsAreOfType(this.utils.PHONE_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that the frequency filter behaves reasonably for attributes other
|
||||||
|
* than the file type.
|
||||||
|
*/
|
||||||
|
public void testTwo() {
|
||||||
|
try {
|
||||||
|
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
||||||
|
|
||||||
|
AbstractCommonAttributeSearcher builder;
|
||||||
|
CommonAttributeSearchResults metadata;
|
||||||
|
|
||||||
|
builder = new AllInterCaseCommonAttributeSearcher(dataSources, false, false, this.utils.USB_ID_TYPE, 100);
|
||||||
|
metadata = builder.findMatches();
|
||||||
|
metadata.size();
|
||||||
|
//assertTrue("This should yield 13 results.", verifyInstanceCount(metadata, 13));
|
||||||
|
|
||||||
|
builder = new AllInterCaseCommonAttributeSearcher(dataSources, false, false, this.utils.USB_ID_TYPE, 20);
|
||||||
|
metadata = builder.findMatches();
|
||||||
|
metadata.size();
|
||||||
|
//assertTrue("This should yield no results.", verifyInstanceCount(metadata, 0));
|
||||||
|
|
||||||
|
builder = new AllInterCaseCommonAttributeSearcher(dataSources, false, false, this.utils.USB_ID_TYPE, 90);
|
||||||
|
metadata = builder.findMatches();
|
||||||
|
metadata.size();
|
||||||
|
//assertTrue("This should yield 2 results.", verifyInstanceCount(metadata, 2));
|
||||||
|
|
||||||
|
} catch (TskCoreException | NoCurrentCaseException | SQLException | EamDbException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
Assert.fail(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.commonfilessearch;
|
package org.sleuthkit.autopsy.commonfilessearch;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
@ -27,6 +28,7 @@ import org.netbeans.junit.NbTestCase;
|
|||||||
import org.openide.util.Exceptions;
|
import org.openide.util.Exceptions;
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||||
import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher;
|
import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher;
|
||||||
import org.sleuthkit.autopsy.commonfilesearch.AllInterCaseCommonAttributeSearcher;
|
import org.sleuthkit.autopsy.commonfilesearch.AllInterCaseCommonAttributeSearcher;
|
||||||
@ -37,7 +39,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests with case 3 as the current case.
|
* Tests with case 3 as the current case.
|
||||||
*
|
*
|
||||||
* If I use the search all cases option: One node for Hash A (1_1_A.jpg,
|
* If I use the search all cases option: One node for Hash A (1_1_A.jpg,
|
||||||
* 1_2_A.jpg, 3_1_A.jpg) If I search for matches only in Case 1: One node for
|
* 1_2_A.jpg, 3_1_A.jpg) If I search for matches only in Case 1: One node for
|
||||||
* Hash A (1_1_A.jpg, 1_2_A.jpg, 3_1_A.jpg) If I search for matches only in Case
|
* Hash A (1_1_A.jpg, 1_2_A.jpg, 3_1_A.jpg) If I search for matches only in Case
|
||||||
@ -45,27 +47,38 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
* all data sources: One node for Hash C (3_1_C.jpg, 3_2_C.jpg)
|
* all data sources: One node for Hash C (3_1_C.jpg, 3_2_C.jpg)
|
||||||
*/
|
*/
|
||||||
public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase {
|
public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase {
|
||||||
|
|
||||||
private final InterCaseTestUtils utils;
|
private final InterCaseTestUtils utils;
|
||||||
|
|
||||||
public static Test suite() {
|
public static Test suite() {
|
||||||
NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(IngestedWithHashAndFileTypeInterCaseTests.class).
|
NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(IngestedWithHashAndFileTypeInterCaseTests.class).
|
||||||
clusters(".*").
|
clusters(".*").
|
||||||
enableModules(".*");
|
enableModules(".*");
|
||||||
return conf.suite();
|
return conf.suite();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IngestedWithHashAndFileTypeInterCaseTests(String name) {
|
public IngestedWithHashAndFileTypeInterCaseTests(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
this.utils = new InterCaseTestUtils(this);
|
this.utils = new InterCaseTestUtils(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUp(){
|
public void setUp() {
|
||||||
this.utils.clearTestDir();
|
this.utils.clearTestDir();
|
||||||
try {
|
try {
|
||||||
this.utils.enableCentralRepo();
|
this.utils.enableCentralRepo();
|
||||||
this.utils.createCases(this.utils.getIngestSettingsForHashAndFileType(), InterCaseTestUtils.CASE3);
|
|
||||||
|
String[] cases = new String[]{
|
||||||
|
CASE1,
|
||||||
|
CASE2,
|
||||||
|
CASE3};
|
||||||
|
|
||||||
|
Path[][] paths = {
|
||||||
|
{this.utils.case1DataSet1Path, this.utils.case1DataSet2Path},
|
||||||
|
{this.utils.case2DataSet1Path, this.utils.case2DataSet2Path},
|
||||||
|
{this.utils.case3DataSet1Path, this.utils.case3DataSet2Path}};
|
||||||
|
|
||||||
|
this.utils.createCases(cases, paths, this.utils.getIngestSettingsForHashAndFileType(), InterCaseTestUtils.CASE3);
|
||||||
} catch (TskCoreException | EamDbException ex) {
|
} catch (TskCoreException | EamDbException ex) {
|
||||||
Exceptions.printStackTrace(ex);
|
Exceptions.printStackTrace(ex);
|
||||||
Assert.fail(ex.getMessage());
|
Assert.fail(ex.getMessage());
|
||||||
@ -73,118 +86,115 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tearDown(){
|
public void tearDown() {
|
||||||
this.utils.clearTestDir();
|
this.utils.clearTestDir();
|
||||||
this.utils.tearDown();
|
this.utils.tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search All cases with no file type filtering.
|
* Search All cases with no file type filtering.
|
||||||
*/
|
*/
|
||||||
public void testOne() {
|
public void testOne() {
|
||||||
try {
|
try {
|
||||||
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
||||||
|
|
||||||
//note that the params false and false are presently meaningless because that feature is not supported yet
|
//note that the params false and false are presently meaningless because that feature is not supported yet
|
||||||
AbstractCommonAttributeSearcher builder = new AllInterCaseCommonAttributeSearcher(dataSources, false, false, 0);
|
AbstractCommonAttributeSearcher builder = new AllInterCaseCommonAttributeSearcher(dataSources, false, false, this.utils.FILE_TYPE, 0);
|
||||||
|
CommonAttributeSearchResults metadata = builder.findMatches();
|
||||||
CommonAttributeSearchResults metadata = builder.findFiles();
|
|
||||||
|
|
||||||
assertTrue("Results should not be empty", metadata.size() != 0);
|
assertTrue("Results should not be empty", metadata.size() != 0);
|
||||||
|
|
||||||
//case 1 data set 1
|
//case 1 data set 1
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_1, CASE1, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_1, CASE1, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_1, CASE1, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_1, CASE1, 1));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_1, CASE1, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_1, CASE1, 1));
|
||||||
|
|
||||||
//case 1 data set 2
|
//case 1 data set 2
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_2, CASE1, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_2, CASE1, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_2, CASE1, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_2, CASE1, 1));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_2, CASE1, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_2, CASE1, 1));
|
||||||
|
|
||||||
//case 2 data set 1
|
//case 2 data set 1
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_PDF, CASE2_DATASET_1, CASE2, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_PDF, CASE2_DATASET_1, CASE2, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_JPG, CASE2_DATASET_1, CASE2, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_JPG, CASE2_DATASET_1, CASE2, 0));
|
||||||
|
|
||||||
//case 2 data set 2
|
//case 2 data set 2
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE2_DATASET_2, CASE2, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE2_DATASET_2, CASE2, 1));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE2_DATASET_2, CASE2, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE2_DATASET_2, CASE2, 1));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE2_DATASET_2, CASE2, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE2_DATASET_2, CASE2, 1));
|
||||||
|
|
||||||
//case 3 data set 1
|
//case 3 data set 1
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE3_DATASET_1, CASE3, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE3_DATASET_1, CASE3, 1));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE3_DATASET_1, CASE3, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE3_DATASET_1, CASE3, 1));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_1, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_1, CASE3, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_1, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_1, CASE3, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_JPG, CASE3_DATASET_1, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_JPG, CASE3_DATASET_1, CASE3, 0));
|
||||||
|
|
||||||
//case 3 data set 2
|
//case 3 data set 2
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_2, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_2, CASE3, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_2, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_2, CASE3, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE3_DATASET_2, CASE3, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE3_DATASET_2, CASE3, 1));
|
||||||
|
|
||||||
|
|
||||||
} catch (TskCoreException | NoCurrentCaseException | SQLException | EamDbException ex) {
|
} catch (TskCoreException | NoCurrentCaseException | SQLException | EamDbException ex) {
|
||||||
Exceptions.printStackTrace(ex);
|
Exceptions.printStackTrace(ex);
|
||||||
Assert.fail(ex.getMessage());
|
Assert.fail(ex.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search All cases with no file type filtering.
|
* Search All cases with no file type filtering.
|
||||||
*/
|
*/
|
||||||
public void testTwo() {
|
public void testTwo() {
|
||||||
try {
|
try {
|
||||||
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
||||||
|
|
||||||
int matchesMustAlsoBeFoundInThisCase = this.utils.getCaseMap().get(CASE2);
|
int matchesMustAlsoBeFoundInThisCase = this.utils.getCaseMap().get(CASE2);
|
||||||
|
CorrelationAttributeInstance.Type fileType = CorrelationAttributeInstance.getDefaultCorrelationTypes().get(0);
|
||||||
AbstractCommonAttributeSearcher builder = new SingleInterCaseCommonAttributeSearcher(matchesMustAlsoBeFoundInThisCase, dataSources, false, false, 0);
|
AbstractCommonAttributeSearcher builder = new SingleInterCaseCommonAttributeSearcher(matchesMustAlsoBeFoundInThisCase, dataSources, false, false, fileType, 0);
|
||||||
|
|
||||||
CommonAttributeSearchResults metadata = builder.findFiles();
|
|
||||||
|
|
||||||
|
CommonAttributeSearchResults metadata = builder.findMatches();
|
||||||
|
|
||||||
assertTrue("Results should not be empty", metadata.size() != 0);
|
assertTrue("Results should not be empty", metadata.size() != 0);
|
||||||
|
|
||||||
//case 1 data set 1
|
//case 1 data set 1
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_1, CASE1, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_1, CASE1, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_1, CASE1, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_1, CASE1, 1));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_1, CASE1, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_1, CASE1, 1));
|
||||||
|
|
||||||
//case 1 data set 2
|
//case 1 data set 2
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_2, CASE1, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_2, CASE1, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_2, CASE1, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_2, CASE1, 1));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_2, CASE1, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_2, CASE1, 1));
|
||||||
|
|
||||||
//case 2 data set 1
|
//case 2 data set 1
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_PDF, CASE2_DATASET_1, CASE2, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_PDF, CASE2_DATASET_1, CASE2, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_JPG, CASE2_DATASET_1, CASE2, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_JPG, CASE2_DATASET_1, CASE2, 0));
|
||||||
|
|
||||||
//case 2 data set 2
|
//case 2 data set 2
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE2_DATASET_2, CASE2, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE2_DATASET_2, CASE2, 1));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE2_DATASET_2, CASE2, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE2_DATASET_2, CASE2, 1));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE2_DATASET_2, CASE2, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE2_DATASET_2, CASE2, 1));
|
||||||
|
|
||||||
//case 3 data set 1
|
//case 3 data set 1
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE3_DATASET_1, CASE3, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE3_DATASET_1, CASE3, 1));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE3_DATASET_1, CASE3, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE3_DATASET_1, CASE3, 1));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_1, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_1, CASE3, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_1, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_1, CASE3, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_JPG, CASE3_DATASET_1, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_JPG, CASE3_DATASET_1, CASE3, 0));
|
||||||
|
|
||||||
//case 3 data set 2
|
//case 3 data set 2
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_2, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_2, CASE3, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_2, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_2, CASE3, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE3_DATASET_2, CASE3, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE3_DATASET_2, CASE3, 1));
|
||||||
|
|
||||||
|
|
||||||
} catch (TskCoreException | NoCurrentCaseException | SQLException | EamDbException ex) {
|
} catch (TskCoreException | NoCurrentCaseException | SQLException | EamDbException ex) {
|
||||||
Exceptions.printStackTrace(ex);
|
Exceptions.printStackTrace(ex);
|
||||||
Assert.fail(ex.getMessage());
|
Assert.fail(ex.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We should be able to observe that certain files o no longer returned
|
* We should be able to observe that certain files are no longer returned
|
||||||
* in the result set since they do not appear frequently enough.
|
* in the result set since they do not appear frequently enough.
|
||||||
*/
|
*/
|
||||||
public void testThree(){
|
public void testThree(){
|
||||||
@ -192,34 +202,35 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase {
|
|||||||
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
||||||
|
|
||||||
//note that the params false and false are presently meaningless because that feature is not supported yet
|
//note that the params false and false are presently meaningless because that feature is not supported yet
|
||||||
AbstractCommonAttributeSearcher builder = new AllInterCaseCommonAttributeSearcher(dataSources, false, false, 50);
|
CorrelationAttributeInstance.Type fileType = CorrelationAttributeInstance.getDefaultCorrelationTypes().get(0);
|
||||||
|
AbstractCommonAttributeSearcher builder = new AllInterCaseCommonAttributeSearcher(dataSources, false, false, fileType, 50);
|
||||||
|
|
||||||
CommonAttributeSearchResults metadata = builder.findFiles();
|
CommonAttributeSearchResults metadata = builder.findMatches();
|
||||||
|
|
||||||
assertTrue("Results should not be empty", metadata.size() != 0);
|
assertTrue("Results should not be empty", metadata.size() != 0);
|
||||||
|
|
||||||
//case 1 data set 1
|
//case 1 data set 1
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_1, CASE1, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_1, CASE1, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_1, CASE1, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_1, CASE1, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_1, CASE1, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_1, CASE1, 0));
|
||||||
|
|
||||||
//case 1 data set 2
|
//case 1 data set 2
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_2, CASE1, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_2, CASE1, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_2, CASE1, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_2, CASE1, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_2, CASE1, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_2, CASE1, 0));
|
||||||
|
|
||||||
//case 2 data set 1
|
//case 2 data set 1
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_PDF, CASE2_DATASET_1, CASE2, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_PDF, CASE2_DATASET_1, CASE2, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_JPG, CASE2_DATASET_1, CASE2, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_JPG, CASE2_DATASET_1, CASE2, 0));
|
||||||
|
|
||||||
//case 2 data set 2
|
//case 2 data set 2
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE2_DATASET_2, CASE2, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE2_DATASET_2, CASE2, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE2_DATASET_2, CASE2, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE2_DATASET_2, CASE2, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE2_DATASET_2, CASE2, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE2_DATASET_2, CASE2, 1));
|
||||||
|
|
||||||
//case 3 data set 1
|
//case 3 data set 1
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE3_DATASET_1, CASE3, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE3_DATASET_1, CASE3, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE3_DATASET_1, CASE3, 1));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE3_DATASET_1, CASE3, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_1, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_1, CASE3, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_1, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_1, CASE3, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_JPG, CASE3_DATASET_1, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_JPG, CASE3_DATASET_1, CASE3, 0));
|
||||||
@ -227,7 +238,7 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase {
|
|||||||
//case 3 data set 2
|
//case 3 data set 2
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_2, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_2, CASE3, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_2, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_2, CASE3, 0));
|
||||||
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE3_DATASET_2, CASE3, 0));
|
assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE3_DATASET_2, CASE3, 1));
|
||||||
|
|
||||||
} catch (TskCoreException | NoCurrentCaseException | SQLException | EamDbException ex) {
|
} catch (TskCoreException | NoCurrentCaseException | SQLException | EamDbException ex) {
|
||||||
Exceptions.printStackTrace(ex);
|
Exceptions.printStackTrace(ex);
|
||||||
|
@ -100,7 +100,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase {
|
|||||||
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
||||||
|
|
||||||
AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false, 0);
|
AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false, 0);
|
||||||
CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles();
|
CommonAttributeSearchResults metadata = allSourcesBuilder.findMatches();
|
||||||
|
|
||||||
Map<Long, String> objectIdToDataSource = IntraCaseTestUtils.mapFileInstancesToDataSources(metadata);
|
Map<Long, String> objectIdToDataSource = IntraCaseTestUtils.mapFileInstancesToDataSources(metadata);
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase {
|
|||||||
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
||||||
|
|
||||||
AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, true, false, 0);
|
AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, true, false, 0);
|
||||||
CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles();
|
CommonAttributeSearchResults metadata = allSourcesBuilder.findMatches();
|
||||||
|
|
||||||
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
||||||
|
|
||||||
@ -182,7 +182,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase {
|
|||||||
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
||||||
|
|
||||||
AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, true, 0);
|
AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, true, 0);
|
||||||
CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles();
|
CommonAttributeSearchResults metadata = allSourcesBuilder.findMatches();
|
||||||
|
|
||||||
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
||||||
|
|
||||||
@ -224,7 +224,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase {
|
|||||||
Long first = getDataSourceIdByName(SET1, dataSources);
|
Long first = getDataSourceIdByName(SET1, dataSources);
|
||||||
|
|
||||||
AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, false, 0);
|
AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, false, 0);
|
||||||
CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles();
|
CommonAttributeSearchResults metadata = singleSourceBuilder.findMatches();
|
||||||
|
|
||||||
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase {
|
|||||||
Long first = getDataSourceIdByName(SET1, dataSources);
|
Long first = getDataSourceIdByName(SET1, dataSources);
|
||||||
|
|
||||||
AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, true, false, 0);
|
AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, true, false, 0);
|
||||||
CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles();
|
CommonAttributeSearchResults metadata = singleSourceBuilder.findMatches();
|
||||||
|
|
||||||
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
||||||
|
|
||||||
@ -308,7 +308,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase {
|
|||||||
Long first = getDataSourceIdByName(SET1, dataSources);
|
Long first = getDataSourceIdByName(SET1, dataSources);
|
||||||
|
|
||||||
AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, true, 0);
|
AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, true, 0);
|
||||||
CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles();
|
CommonAttributeSearchResults metadata = singleSourceBuilder.findMatches();
|
||||||
|
|
||||||
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
||||||
|
|
||||||
@ -350,7 +350,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase {
|
|||||||
Long second = getDataSourceIdByName(SET2, dataSources);
|
Long second = getDataSourceIdByName(SET2, dataSources);
|
||||||
|
|
||||||
AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(second, dataSources, false, false, 0);
|
AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(second, dataSources, false, false, 0);
|
||||||
CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles();
|
CommonAttributeSearchResults metadata = singleSourceBuilder.findMatches();
|
||||||
|
|
||||||
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
||||||
|
|
||||||
@ -391,7 +391,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase {
|
|||||||
Long last = getDataSourceIdByName(SET4, dataSources);
|
Long last = getDataSourceIdByName(SET4, dataSources);
|
||||||
|
|
||||||
AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(last, dataSources, false, false, 0);
|
AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(last, dataSources, false, false, 0);
|
||||||
CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles();
|
CommonAttributeSearchResults metadata = singleSourceBuilder.findMatches();
|
||||||
|
|
||||||
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
||||||
|
|
||||||
@ -432,7 +432,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase {
|
|||||||
Long third = getDataSourceIdByName(SET3, dataSources);
|
Long third = getDataSourceIdByName(SET3, dataSources);
|
||||||
|
|
||||||
AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(third, dataSources, false, false, 0);
|
AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(third, dataSources, false, false, 0);
|
||||||
CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles();
|
CommonAttributeSearchResults metadata = singleSourceBuilder.findMatches();
|
||||||
|
|
||||||
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
Map<Long, String> objectIdToDataSource = mapFileInstancesToDataSources(metadata);
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ public class IngestedWithNoFileTypesIntraCaseTests extends NbTestCase {
|
|||||||
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
||||||
|
|
||||||
IntraCaseCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, true, false, 0);
|
IntraCaseCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, true, false, 0);
|
||||||
CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles();
|
CommonAttributeSearchResults metadata = allSourcesBuilder.findMatches();
|
||||||
|
|
||||||
Map<Long, String> objectIdToDataSource = IntraCaseTestUtils.mapFileInstancesToDataSources(metadata);
|
Map<Long, String> objectIdToDataSource = IntraCaseTestUtils.mapFileInstancesToDataSources(metadata);
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ public class IngestedWithNoFileTypesIntraCaseTests extends NbTestCase {
|
|||||||
Long third = IntraCaseTestUtils.getDataSourceIdByName(IntraCaseTestUtils.SET3, dataSources);
|
Long third = IntraCaseTestUtils.getDataSourceIdByName(IntraCaseTestUtils.SET3, dataSources);
|
||||||
|
|
||||||
IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(third, dataSources, true, false, 0);
|
IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(third, dataSources, true, false, 0);
|
||||||
CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles();
|
CommonAttributeSearchResults metadata = singleSourceBuilder.findMatches();
|
||||||
|
|
||||||
Map<Long, String> objectIdToDataSource = IntraCaseTestUtils.mapFileInstancesToDataSources(metadata);
|
Map<Long, String> objectIdToDataSource = IntraCaseTestUtils.mapFileInstancesToDataSources(metadata);
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@ import java.nio.file.Path;
|
|||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.netbeans.junit.NbTestCase;
|
import org.netbeans.junit.NbTestCase;
|
||||||
@ -59,6 +59,14 @@ import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader;
|
|||||||
import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue;
|
import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue;
|
||||||
import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValueList;
|
import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValueList;
|
||||||
import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
|
import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
|
||||||
|
import org.sleuthkit.autopsy.modules.e01verify.E01VerifierModuleFactory;
|
||||||
|
import org.sleuthkit.autopsy.modules.embeddedfileextractor.EmbeddedFileExtractorModuleFactory;
|
||||||
|
import org.sleuthkit.autopsy.modules.exif.ExifParserModuleFactory;
|
||||||
|
import org.sleuthkit.autopsy.modules.fileextmismatch.FileExtMismatchDetectorModuleFactory;
|
||||||
|
import org.sleuthkit.autopsy.modules.iOS.iOSModuleFactory;
|
||||||
|
import org.sleuthkit.autopsy.modules.interestingitems.InterestingItemsIngestModuleFactory;
|
||||||
|
import org.sleuthkit.autopsy.modules.photoreccarver.PhotoRecCarverIngestModuleFactory;
|
||||||
|
import org.sleuthkit.autopsy.modules.vmextractor.VMExtractorIngestModuleFactory;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,23 +81,54 @@ import org.sleuthkit.datamodel.AbstractFile;
|
|||||||
* Description of Test Data: (Note: files of the same name and extension are
|
* Description of Test Data: (Note: files of the same name and extension are
|
||||||
* identical; files of the same name and differing extension are not identical.)
|
* identical; files of the same name and differing extension are not identical.)
|
||||||
*
|
*
|
||||||
* Case 1 +Data Set 1 - Hash-0.dat [testFile of size 0] - Hash-A.jpg -
|
* Case 1
|
||||||
* Hash-A.pdf +Data Set2 - Hash-0.dat [testFile of size 0] - Hash-A.jpg -
|
* +Data Set 1
|
||||||
* Hash-A.pdf Case 2 +Data Set 1 - Hash-B.jpg - Hash-B.pdf +Data Set 2 -
|
* - Hash-0.dat [testFile of size 0]
|
||||||
* Hash-A.jpg - Hash-A.pdf - Hash_D.doc Case 3 +Data Set 1 - Hash-A.jpg -
|
* - Hash-A.jpg
|
||||||
* Hash-A.pdf - Hash-C.jpg - Hash-C.pdf - Hash-D.jpg +Data Set 2 - Hash-C.jpg -
|
* - Hash-A.pdf
|
||||||
* Hash-C.pdf - Hash-D.doc
|
*
|
||||||
|
* +Data Set2
|
||||||
|
* - Hash-0.dat [testFile of size 0]
|
||||||
|
* - Hash-A.jpg
|
||||||
|
* - Hash-A.pdf
|
||||||
|
*
|
||||||
|
* Case 2
|
||||||
|
* +Data Set 1
|
||||||
|
* - Hash-B.jpg
|
||||||
|
* - Hash-B.pdf
|
||||||
|
* +Data Set 2
|
||||||
|
* - Hash-A.jpg
|
||||||
|
* - Hash-A.pdf
|
||||||
|
* - Hash_D.doc
|
||||||
|
*
|
||||||
|
* Case 3
|
||||||
|
* +Data Set 1
|
||||||
|
* - Hash-A.jpg
|
||||||
|
* - Hash-A.pdf
|
||||||
|
* - Hash-C.jpg
|
||||||
|
* - Hash-C.pdf
|
||||||
|
* - Hash-D.jpg
|
||||||
|
* +Data Set 2
|
||||||
|
* - Hash-C.jpg
|
||||||
|
* - Hash-C.pdf
|
||||||
|
* - Hash-D.doc
|
||||||
*
|
*
|
||||||
* Frequency Breakdown (ratio of datasources a given file appears in to total
|
* Frequency Breakdown (ratio of datasources a given file appears in to total
|
||||||
* number of datasources):
|
* number of datasources):
|
||||||
*
|
*
|
||||||
* Hash-0.dat - moot; these are always excluded Hash-A.jpg - 4/6 Hash-A.pdf -
|
* Hash-0.dat - moot; these are always excluded
|
||||||
* 4/6 Hash-B.jpg - 1/6 Hash-B.pdf - 1/6 Hash-C.jpg - 2/6 Hash-C.pdf - 2/6
|
* Hash-A.jpg - 4/6
|
||||||
* Hash_D.doc - 2/6 Hash-D.jpg - 1/6
|
* Hash-A.pdf - 4/6
|
||||||
|
* Hash-B.jpg - 1/6
|
||||||
|
* Hash-B.pdf - 1/6
|
||||||
|
* Hash-C.jpg - 2/6
|
||||||
|
* Hash-C.pdf - 2/6
|
||||||
|
* Hash_D.doc - 2/6
|
||||||
|
* Hash-D.jpg - 1/6
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class InterCaseTestUtils {
|
class InterCaseTestUtils {
|
||||||
|
|
||||||
private static final Path CASE_DIRECTORY_PATH = Paths.get(System.getProperty("java.io.tmpdir"), "InterCaseCommonFilesSearchTest");
|
private static final Path CASE_DIRECTORY_PATH = Paths.get(System.getProperty("java.io.tmpdir"), "InterCaseCommonFilesSearchTest");
|
||||||
private static final String CR_DB_NAME = "testcentralrepo.db";
|
private static final String CR_DB_NAME = "testcentralrepo.db";
|
||||||
|
|
||||||
@ -121,13 +160,31 @@ class InterCaseTestUtils {
|
|||||||
static final String CASE2_DATASET_2 = "c2ds2_v1.vhd";
|
static final String CASE2_DATASET_2 = "c2ds2_v1.vhd";
|
||||||
static final String CASE3_DATASET_1 = "c3ds1_v1.vhd";
|
static final String CASE3_DATASET_1 = "c3ds1_v1.vhd";
|
||||||
static final String CASE3_DATASET_2 = "c3ds2_v1.vhd";
|
static final String CASE3_DATASET_2 = "c3ds2_v1.vhd";
|
||||||
|
|
||||||
|
final Path attrCase1Path;
|
||||||
|
final Path attrCase2Path;
|
||||||
|
final Path attrCase3Path;
|
||||||
|
final Path attrCase4Path;
|
||||||
|
|
||||||
|
static final String ATTR_CASE1 = "CommonFilesAttrs_img1_v1.vhd";
|
||||||
|
static final String ATTR_CASE2 = "CommonFilesAttrs_img2_v1.vhd";
|
||||||
|
static final String ATTR_CASE3 = "CommonFilesAttrs_img3_v1.vhd";
|
||||||
|
static final String ATTR_CASE4 = "CommonFilesAttrs_img4_v1.vhd";
|
||||||
|
|
||||||
private final ImageDSProcessor imageDSProcessor;
|
private final ImageDSProcessor imageDSProcessor;
|
||||||
|
|
||||||
private final IngestJobSettings hashAndFileType;
|
private final IngestJobSettings hashAndFileType;
|
||||||
private final IngestJobSettings hashAndNoFileType;
|
private final IngestJobSettings hashAndNoFileType;
|
||||||
|
private final IngestJobSettings kitchenShink;
|
||||||
|
|
||||||
private final DataSourceLoader dataSourceLoader;
|
private final DataSourceLoader dataSourceLoader;
|
||||||
|
|
||||||
|
CorrelationAttributeInstance.Type FILE_TYPE;
|
||||||
|
CorrelationAttributeInstance.Type DOMAIN_TYPE;
|
||||||
|
CorrelationAttributeInstance.Type USB_ID_TYPE;
|
||||||
|
CorrelationAttributeInstance.Type EMAIL_TYPE;
|
||||||
|
CorrelationAttributeInstance.Type PHONE_TYPE;
|
||||||
|
|
||||||
InterCaseTestUtils(NbTestCase testCase) {
|
InterCaseTestUtils(NbTestCase testCase) {
|
||||||
|
|
||||||
this.case1DataSet1Path = Paths.get(testCase.getDataDir().toString(), CASE1_DATASET_1);
|
this.case1DataSet1Path = Paths.get(testCase.getDataDir().toString(), CASE1_DATASET_1);
|
||||||
@ -136,13 +193,32 @@ class InterCaseTestUtils {
|
|||||||
this.case2DataSet2Path = Paths.get(testCase.getDataDir().toString(), CASE2_DATASET_2);
|
this.case2DataSet2Path = Paths.get(testCase.getDataDir().toString(), CASE2_DATASET_2);
|
||||||
this.case3DataSet1Path = Paths.get(testCase.getDataDir().toString(), CASE3_DATASET_1);
|
this.case3DataSet1Path = Paths.get(testCase.getDataDir().toString(), CASE3_DATASET_1);
|
||||||
this.case3DataSet2Path = Paths.get(testCase.getDataDir().toString(), CASE3_DATASET_2);
|
this.case3DataSet2Path = Paths.get(testCase.getDataDir().toString(), CASE3_DATASET_2);
|
||||||
|
|
||||||
|
this.attrCase1Path = Paths.get(testCase.getDataDir().toString(), ATTR_CASE1);
|
||||||
|
this.attrCase2Path = Paths.get(testCase.getDataDir().toString(), ATTR_CASE2);
|
||||||
|
this.attrCase3Path = Paths.get(testCase.getDataDir().toString(), ATTR_CASE3);
|
||||||
|
this.attrCase4Path = Paths.get(testCase.getDataDir().toString(), ATTR_CASE4);
|
||||||
|
|
||||||
this.imageDSProcessor = new ImageDSProcessor();
|
this.imageDSProcessor = new ImageDSProcessor();
|
||||||
|
|
||||||
final IngestModuleTemplate hashLookupTemplate = IngestUtils.getIngestModuleTemplate(new HashLookupModuleFactory());
|
final IngestModuleTemplate exifTemplate = IngestUtils.getIngestModuleTemplate(new ExifParserModuleFactory());
|
||||||
|
final IngestModuleTemplate iOsTemplate = IngestUtils.getIngestModuleTemplate(new iOSModuleFactory());
|
||||||
|
final IngestModuleTemplate embeddedFileExtractorTemplate = IngestUtils.getIngestModuleTemplate(new EmbeddedFileExtractorModuleFactory());
|
||||||
|
final IngestModuleTemplate interestingItemsTemplate = IngestUtils.getIngestModuleTemplate(new InterestingItemsIngestModuleFactory());
|
||||||
final IngestModuleTemplate mimeTypeLookupTemplate = IngestUtils.getIngestModuleTemplate(new FileTypeIdModuleFactory());
|
final IngestModuleTemplate mimeTypeLookupTemplate = IngestUtils.getIngestModuleTemplate(new FileTypeIdModuleFactory());
|
||||||
|
final IngestModuleTemplate hashLookupTemplate = IngestUtils.getIngestModuleTemplate(new HashLookupModuleFactory());
|
||||||
|
final IngestModuleTemplate vmExtractorTemplate = IngestUtils.getIngestModuleTemplate(new VMExtractorIngestModuleFactory());
|
||||||
|
final IngestModuleTemplate photoRecTemplate = IngestUtils.getIngestModuleTemplate(new PhotoRecCarverIngestModuleFactory());
|
||||||
|
final IngestModuleTemplate e01VerifierTemplate = IngestUtils.getIngestModuleTemplate(new E01VerifierModuleFactory());
|
||||||
final IngestModuleTemplate eamDbTemplate = IngestUtils.getIngestModuleTemplate(new org.sleuthkit.autopsy.centralrepository.ingestmodule.IngestModuleFactory());
|
final IngestModuleTemplate eamDbTemplate = IngestUtils.getIngestModuleTemplate(new org.sleuthkit.autopsy.centralrepository.ingestmodule.IngestModuleFactory());
|
||||||
|
final IngestModuleTemplate fileExtMismatchDetectorTemplate = IngestUtils.getIngestModuleTemplate(new FileExtMismatchDetectorModuleFactory());
|
||||||
|
//TODO we need to figure out how to get ahold of these objects because they are required for properly filling the CR with test data
|
||||||
|
// final IngestModuleTemplate objectDetectorTemplate = IngestUtils.getIngestModuleTemplate(new org.sleuthkit.autopsy.experimental.objectdetection.ObjectDetectionModuleFactory());
|
||||||
|
// final IngestModuleTemplate emailParserTemplate = IngestUtils.getIngestModuleTemplate(new org.sleuthkit.autopsy.thunderbirdparser.EmailParserModuleFactory());
|
||||||
|
// final IngestModuleTemplate recentActivityTemplate = IngestUtils.getIngestModuleTemplate(new org.sleuthkit.autopsy.recentactivity.RecentActivityExtracterModuleFactory());
|
||||||
|
// final IngestModuleTemplate keywordSearchTemplate = IngestUtils.getIngestModuleTemplate(new org.sleuthkit.autopsy.keywordsearch.KeywordSearchModuleFactory());
|
||||||
|
|
||||||
|
//hash and mime
|
||||||
ArrayList<IngestModuleTemplate> hashAndMimeTemplate = new ArrayList<>(2);
|
ArrayList<IngestModuleTemplate> hashAndMimeTemplate = new ArrayList<>(2);
|
||||||
hashAndMimeTemplate.add(hashLookupTemplate);
|
hashAndMimeTemplate.add(hashLookupTemplate);
|
||||||
hashAndMimeTemplate.add(mimeTypeLookupTemplate);
|
hashAndMimeTemplate.add(mimeTypeLookupTemplate);
|
||||||
@ -150,13 +226,56 @@ class InterCaseTestUtils {
|
|||||||
|
|
||||||
this.hashAndFileType = new IngestJobSettings(InterCaseTestUtils.class.getCanonicalName(), IngestType.FILES_ONLY, hashAndMimeTemplate);
|
this.hashAndFileType = new IngestJobSettings(InterCaseTestUtils.class.getCanonicalName(), IngestType.FILES_ONLY, hashAndMimeTemplate);
|
||||||
|
|
||||||
|
//hash and no mime
|
||||||
ArrayList<IngestModuleTemplate> hashAndNoMimeTemplate = new ArrayList<>(1);
|
ArrayList<IngestModuleTemplate> hashAndNoMimeTemplate = new ArrayList<>(1);
|
||||||
hashAndNoMimeTemplate.add(hashLookupTemplate);
|
hashAndNoMimeTemplate.add(hashLookupTemplate);
|
||||||
hashAndMimeTemplate.add(eamDbTemplate);
|
hashAndMimeTemplate.add(eamDbTemplate);
|
||||||
|
|
||||||
this.hashAndNoFileType = new IngestJobSettings(InterCaseTestUtils.class.getCanonicalName(), IngestType.FILES_ONLY, hashAndNoMimeTemplate);
|
this.hashAndNoFileType = new IngestJobSettings(InterCaseTestUtils.class.getCanonicalName(), IngestType.FILES_ONLY, hashAndNoMimeTemplate);
|
||||||
|
|
||||||
|
//kitchen sink
|
||||||
|
ArrayList<IngestModuleTemplate> kitchenSink = new ArrayList<>();
|
||||||
|
kitchenSink.add(exifTemplate);
|
||||||
|
kitchenSink.add(iOsTemplate);
|
||||||
|
kitchenSink.add(embeddedFileExtractorTemplate);
|
||||||
|
kitchenSink.add(interestingItemsTemplate);
|
||||||
|
kitchenSink.add(mimeTypeLookupTemplate);
|
||||||
|
kitchenSink.add(hashLookupTemplate);
|
||||||
|
kitchenSink.add(vmExtractorTemplate);
|
||||||
|
kitchenSink.add(photoRecTemplate);
|
||||||
|
kitchenSink.add(e01VerifierTemplate);
|
||||||
|
kitchenSink.add(eamDbTemplate);
|
||||||
|
kitchenSink.add(fileExtMismatchDetectorTemplate);
|
||||||
|
//TODO this list should probably be populated by way of loading the appropriate modules based on finding all of the @ServiceProvider(service = IngestModuleFactory.class) types
|
||||||
|
// kitchenSink.add(objectDetectorTemplate);
|
||||||
|
// kitchenSink.add(emailParserTemplate);
|
||||||
|
// kitchenSink.add(recentActivityTemplate);
|
||||||
|
// kitchenSink.add(keywordSearchTemplate);
|
||||||
|
|
||||||
|
this.kitchenShink = new IngestJobSettings(InterCaseTestUtils.class.getCanonicalName(), IngestType.ALL_MODULES, kitchenSink);
|
||||||
|
|
||||||
this.dataSourceLoader = new DataSourceLoader();
|
this.dataSourceLoader = new DataSourceLoader();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Collection<CorrelationAttributeInstance.Type> types = CorrelationAttributeInstance.getDefaultCorrelationTypes();
|
||||||
|
|
||||||
|
//TODO use ids instead of strings
|
||||||
|
FILE_TYPE = types.stream().filter(type -> type.getDisplayName().equals("Files")).findAny().get();
|
||||||
|
DOMAIN_TYPE = types.stream().filter(type -> type.getDisplayName().equals("Domains")).findAny().get();
|
||||||
|
USB_ID_TYPE = types.stream().filter(type -> type.getDisplayName().equals("USB Devices")).findAny().get();
|
||||||
|
EMAIL_TYPE = types.stream().filter(type -> type.getDisplayName().equals("Email Addresses")).findAny().get();
|
||||||
|
PHONE_TYPE = types.stream().filter(type -> type.getDisplayName().equals("Phone Numbers")).findAny().get();
|
||||||
|
|
||||||
|
} catch (EamDbException ex) {
|
||||||
|
Assert.fail(ex.getMessage());
|
||||||
|
|
||||||
|
//none of this really matters but satisfies the compiler
|
||||||
|
FILE_TYPE = null;
|
||||||
|
DOMAIN_TYPE = null;
|
||||||
|
USB_ID_TYPE = null;
|
||||||
|
EMAIL_TYPE = null;
|
||||||
|
PHONE_TYPE = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearTestDir() {
|
void clearTestDir() {
|
||||||
@ -201,6 +320,10 @@ class InterCaseTestUtils {
|
|||||||
IngestJobSettings getIngestSettingsForHashAndNoFileType() {
|
IngestJobSettings getIngestSettingsForHashAndNoFileType() {
|
||||||
return this.hashAndNoFileType;
|
return this.hashAndNoFileType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IngestJobSettings getIngestSettingsForKitchenSink(){
|
||||||
|
return this.kitchenShink;
|
||||||
|
}
|
||||||
|
|
||||||
void enableCentralRepo() throws EamDbException {
|
void enableCentralRepo() throws EamDbException {
|
||||||
|
|
||||||
@ -214,7 +337,7 @@ class InterCaseTestUtils {
|
|||||||
crSettings.initializeDatabaseSchema();
|
crSettings.initializeDatabaseSchema();
|
||||||
crSettings.insertDefaultDatabaseContent();
|
crSettings.insertDefaultDatabaseContent();
|
||||||
|
|
||||||
crSettings.saveSettings();
|
crSettings.saveSettings();
|
||||||
|
|
||||||
EamDbUtil.setUseCentralRepo(true);
|
EamDbUtil.setUseCentralRepo(true);
|
||||||
EamDbPlatformEnum.setSelectedPlatform(EamDbPlatformEnum.SQLITE.name());
|
EamDbPlatformEnum.setSelectedPlatform(EamDbPlatformEnum.SQLITE.name());
|
||||||
@ -222,33 +345,33 @@ class InterCaseTestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create 3 cases and ingest each with the given settings. Null settings are
|
* Create the cases defined by caseNames and caseDataSourcePaths and ingest
|
||||||
* permitted but IngestUtils will not be run.
|
* each with the given settings. Null settings are permitted but
|
||||||
|
* IngestUtils will not be run.
|
||||||
|
*
|
||||||
|
* The length of caseNames and caseDataSourcePaths should be the same, and
|
||||||
|
* cases should appear in the same order.
|
||||||
*
|
*
|
||||||
|
* @param caseNames list case names
|
||||||
|
* @param caseDataSourcePaths two dimensional array listing the datasources in each case
|
||||||
* @param ingestJobSettings HashLookup FileType etc...
|
* @param ingestJobSettings HashLookup FileType etc...
|
||||||
* @param caseReferenceToStore
|
* @param caseReferenceToStore
|
||||||
*/
|
*/
|
||||||
Case createCases(IngestJobSettings ingestJobSettings, String caseReferenceToStore) throws TskCoreException {
|
Case createCases(String[] caseNames, Path[][] caseDataSourcePaths, IngestJobSettings ingestJobSettings, String caseReferenceToStore) throws TskCoreException {
|
||||||
|
|
||||||
Case currentCase = null;
|
Case currentCase = null;
|
||||||
|
|
||||||
String[] cases = new String[]{
|
if(caseNames.length != caseDataSourcePaths.length){
|
||||||
CASE1,
|
Assert.fail(new IllegalArgumentException("caseReferenceToStore should be one of the values given in the 'cases' parameter.").getMessage());
|
||||||
CASE2,
|
}
|
||||||
CASE3};
|
|
||||||
|
|
||||||
Path[][] paths = {
|
|
||||||
{this.case1DataSet1Path, this.case1DataSet2Path},
|
|
||||||
{this.case2DataSet1Path, this.case2DataSet2Path},
|
|
||||||
{this.case3DataSet1Path, this.case3DataSet2Path}};
|
|
||||||
|
|
||||||
String lastCaseName = null;
|
String lastCaseName = null;
|
||||||
Path[] lastPathsForCase = null;
|
Path[] lastPathsForCase = null;
|
||||||
//iterate over the collections above, creating cases, and storing
|
//iterate over the collections above, creating cases, and storing
|
||||||
// just one of them for future reference
|
// just one of them for future reference
|
||||||
for (int i = 0; i < cases.length; i++) {
|
for (int i = 0; i < caseNames.length; i++) {
|
||||||
String caseName = cases[i];
|
String caseName = caseNames[i];
|
||||||
Path[] pathsForCase = paths[i];
|
Path[] pathsForCase = caseDataSourcePaths[i];
|
||||||
|
|
||||||
if (caseName.equals(caseReferenceToStore)) {
|
if (caseName.equals(caseReferenceToStore)) {
|
||||||
//put aside and do this one last so we can hang onto the case
|
//put aside and do this one last so we can hang onto the case
|
||||||
@ -266,7 +389,7 @@ class InterCaseTestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (currentCase == null) {
|
if (currentCase == null) {
|
||||||
Assert.fail(new IllegalArgumentException("caseReferenceToStore should be one of: CASE1, CASE2, CASE3").getMessage());
|
Assert.fail(new IllegalArgumentException("caseReferenceToStore should be one of the values given in the 'cases' parameter.").getMessage());
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return currentCase;
|
return currentCase;
|
||||||
@ -289,6 +412,27 @@ class InterCaseTestUtils {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean verifyInstanceCount(CommonAttributeSearchResults searchDomain, int instanceCount){
|
||||||
|
try {
|
||||||
|
int tally = 0;
|
||||||
|
|
||||||
|
for (Map.Entry<Integer, CommonAttributeValueList> entry : searchDomain.getMetadata().entrySet()) {
|
||||||
|
entry.getValue().displayDelayedMetadata();
|
||||||
|
for (CommonAttributeValue value : entry.getValue().getMetadataList()) {
|
||||||
|
|
||||||
|
tally += value.getInstanceCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tally == instanceCount;
|
||||||
|
|
||||||
|
} catch (EamDbException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
Assert.fail(ex.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static boolean verifyInstanceExistanceAndCount(CommonAttributeSearchResults searchDomain, String fileName, String dataSource, String crCase, int instanceCount) {
|
static boolean verifyInstanceExistanceAndCount(CommonAttributeSearchResults searchDomain, String fileName, String dataSource, String crCase, int instanceCount) {
|
||||||
|
|
||||||
@ -381,4 +525,29 @@ class InterCaseTestUtils {
|
|||||||
Assert.fail(ex.getMessage());
|
Assert.fail(ex.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is everything in metadata a result of the given attribute type?
|
||||||
|
*
|
||||||
|
* @param metadata
|
||||||
|
* @param attributeType
|
||||||
|
* @return true if yes, else false
|
||||||
|
*/
|
||||||
|
boolean areAllResultsOfType(CommonAttributeSearchResults metadata, CorrelationAttributeInstance.Type attributeType) {
|
||||||
|
try {
|
||||||
|
for(CommonAttributeValueList matches : metadata.getMetadata().values()){
|
||||||
|
for(CommonAttributeValue value : matches.getMetadataList()){
|
||||||
|
return value
|
||||||
|
.getInstances()
|
||||||
|
.stream()
|
||||||
|
.allMatch(inst -> inst.getCorrelationAttributeInstanceType().equals(attributeType));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} catch (EamDbException ex) {
|
||||||
|
Assert.fail(ex.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ public class MatchesInAtLeastTwoSourcesIntraCaseTests extends NbTestCase {
|
|||||||
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
||||||
|
|
||||||
AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false, 0);
|
AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false, 0);
|
||||||
CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles();
|
CommonAttributeSearchResults metadata = allSourcesBuilder.findMatches();
|
||||||
|
|
||||||
Map<Long, String> objectIdToDataSource = IntraCaseTestUtils.mapFileInstancesToDataSources(metadata);
|
Map<Long, String> objectIdToDataSource = IntraCaseTestUtils.mapFileInstancesToDataSources(metadata);
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ public class UningestedCasesIntraCaseTests extends NbTestCase {
|
|||||||
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
Map<Long, String> dataSources = this.utils.getDataSourceMap();
|
||||||
|
|
||||||
IntraCaseCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false, 0);
|
IntraCaseCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false, 0);
|
||||||
CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles();
|
CommonAttributeSearchResults metadata = allSourcesBuilder.findMatches();
|
||||||
|
|
||||||
int resultCount = metadata.size();
|
int resultCount = metadata.size();
|
||||||
assertEquals(resultCount, 0);
|
assertEquals(resultCount, 0);
|
||||||
@ -101,7 +101,7 @@ public class UningestedCasesIntraCaseTests extends NbTestCase {
|
|||||||
Long first = getDataSourceIdByName(SET1, dataSources);
|
Long first = getDataSourceIdByName(SET1, dataSources);
|
||||||
|
|
||||||
IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, false, 0);
|
IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, false, 0);
|
||||||
CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles();
|
CommonAttributeSearchResults metadata = singleSourceBuilder.findMatches();
|
||||||
|
|
||||||
int resultCount = metadata.size();
|
int resultCount = metadata.size();
|
||||||
assertEquals(resultCount, 0);
|
assertEquals(resultCount, 0);
|
||||||
|
@ -39,7 +39,7 @@ public final class IngestJobRunner {
|
|||||||
* Runs an ingest job, blocking until the job is completed.
|
* Runs an ingest job, blocking until the job is completed.
|
||||||
*
|
*
|
||||||
* @param dataSources The data sources for the ingest job.
|
* @param dataSources The data sources for the ingest job.
|
||||||
* @param settings The settings for the ingst job
|
* @param settings The settings for the ingest job
|
||||||
*
|
*
|
||||||
* @return A list of ingest module start up error messages, empty if the job
|
* @return A list of ingest module start up error messages, empty if the job
|
||||||
* was started sucessfully.
|
* was started sucessfully.
|
||||||
@ -68,7 +68,7 @@ public final class IngestJobRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IngestRunner instances cannot be instatiated.
|
* IngestRunner instances cannot be instantiated.
|
||||||
*/
|
*/
|
||||||
private IngestJobRunner() {
|
private IngestJobRunner() {
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user