mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 18:17:43 +00:00
6711 add ResultDomain object
This commit is contained in:
parent
1b73edee7d
commit
e9b80d09a1
@ -61,7 +61,7 @@ public abstract class AbstractFilter {
|
|||||||
*
|
*
|
||||||
* @throws DiscoveryException
|
* @throws DiscoveryException
|
||||||
*/
|
*/
|
||||||
public List<ResultFile> applyAlternateFilter(List<ResultFile> currentResults, SleuthkitCase caseDb,
|
public List<Result> applyAlternateFilter(List<Result> currentResults, SleuthkitCase caseDb,
|
||||||
CentralRepository centralRepoDb) throws DiscoveryException {
|
CentralRepository centralRepoDb) throws DiscoveryException {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
@ -52,19 +52,19 @@ public class DiscoveryAttributes {
|
|||||||
*
|
*
|
||||||
* @return the key for the group this file goes in
|
* @return the key for the group this file goes in
|
||||||
*/
|
*/
|
||||||
public abstract DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file);
|
public abstract DiscoveryKeyUtils.GroupKey getGroupKey(Result file);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add any extra data to the ResultFile object from this attribute.
|
* Add any extra data to the ResultFile object from this attribute.
|
||||||
*
|
*
|
||||||
* @param files The list of files to enhance
|
* @param files The list of results to enhance
|
||||||
* @param caseDb The case database
|
* @param caseDb The case database
|
||||||
* @param centralRepoDb The central repository database. Can be null if
|
* @param centralRepoDb The central repository database. Can be null if
|
||||||
* not needed.
|
* not needed.
|
||||||
*
|
*
|
||||||
* @throws DiscoveryException
|
* @throws DiscoveryException
|
||||||
*/
|
*/
|
||||||
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
|
public void addAttributeToResultFiles(List<Result> results, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
|
||||||
// Default is to do nothing
|
// Default is to do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,8 +75,8 @@ public class DiscoveryAttributes {
|
|||||||
public static class FileSizeAttribute extends AttributeType {
|
public static class FileSizeAttribute extends AttributeType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
|
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
|
||||||
return new DiscoveryKeyUtils.FileSizeGroupKey(file);
|
return new DiscoveryKeyUtils.FileSizeGroupKey((ResultFile) file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,8 +86,8 @@ public class DiscoveryAttributes {
|
|||||||
public static class ParentPathAttribute extends AttributeType {
|
public static class ParentPathAttribute extends AttributeType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
|
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
|
||||||
return new DiscoveryKeyUtils.ParentPathGroupKey(file);
|
return new DiscoveryKeyUtils.ParentPathGroupKey((ResultFile) file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ public class DiscoveryAttributes {
|
|||||||
static class NoGroupingAttribute extends AttributeType {
|
static class NoGroupingAttribute extends AttributeType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
|
public DiscoveryKeyUtils.GroupKey getGroupKey(Result result) {
|
||||||
return new DiscoveryKeyUtils.NoGroupingGroupKey();
|
return new DiscoveryKeyUtils.NoGroupingGroupKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,8 +108,8 @@ public class DiscoveryAttributes {
|
|||||||
static class DataSourceAttribute extends AttributeType {
|
static class DataSourceAttribute extends AttributeType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
|
public DiscoveryKeyUtils.GroupKey getGroupKey(Result result) {
|
||||||
return new DiscoveryKeyUtils.DataSourceGroupKey(file);
|
return new DiscoveryKeyUtils.DataSourceGroupKey(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ public class DiscoveryAttributes {
|
|||||||
static class FileTypeAttribute extends AttributeType {
|
static class FileTypeAttribute extends AttributeType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
|
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
|
||||||
return new DiscoveryKeyUtils.FileTypeGroupKey(file);
|
return new DiscoveryKeyUtils.FileTypeGroupKey(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,20 +130,20 @@ public class DiscoveryAttributes {
|
|||||||
static class KeywordListAttribute extends AttributeType {
|
static class KeywordListAttribute extends AttributeType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
|
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
|
||||||
return new DiscoveryKeyUtils.KeywordListGroupKey(file);
|
return new DiscoveryKeyUtils.KeywordListGroupKey((ResultFile) file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
public void addAttributeToResultFiles(List<Result> results, SleuthkitCase caseDb,
|
||||||
CentralRepository centralRepoDb) throws DiscoveryException {
|
CentralRepository centralRepoDb) throws DiscoveryException {
|
||||||
|
|
||||||
// Get pairs of (object ID, keyword list name) for all files in the list of files that have
|
// Get pairs of (object ID, keyword list name) for all files in the list of files that have
|
||||||
// keyword list hits.
|
// keyword list hits.
|
||||||
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(),
|
String selectQuery = createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
|
||||||
|
|
||||||
SetKeywordListNamesCallback callback = new SetKeywordListNamesCallback(files);
|
SetKeywordListNamesCallback callback = new SetKeywordListNamesCallback(results);
|
||||||
try {
|
try {
|
||||||
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
|
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
@ -158,14 +158,14 @@ public class DiscoveryAttributes {
|
|||||||
*/
|
*/
|
||||||
private static class SetKeywordListNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
|
private static class SetKeywordListNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
|
||||||
|
|
||||||
List<ResultFile> resultFiles;
|
List<Result> resultFiles;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the callback.
|
* Create the callback.
|
||||||
*
|
*
|
||||||
* @param resultFiles List of files to add keyword list names to
|
* @param resultFiles List of files to add keyword list names to
|
||||||
*/
|
*/
|
||||||
SetKeywordListNamesCallback(List<ResultFile> resultFiles) {
|
SetKeywordListNamesCallback(List<Result> resultFiles) {
|
||||||
this.resultFiles = resultFiles;
|
this.resultFiles = resultFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +174,11 @@ public class DiscoveryAttributes {
|
|||||||
try {
|
try {
|
||||||
// Create a temporary map of object ID to ResultFile
|
// Create a temporary map of object ID to ResultFile
|
||||||
Map<Long, ResultFile> tempMap = new HashMap<>();
|
Map<Long, ResultFile> tempMap = new HashMap<>();
|
||||||
for (ResultFile file : resultFiles) {
|
for (Result result : resultFiles) {
|
||||||
|
if (result.getType() == SearchData.Type.DOMAIN) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ResultFile file = (ResultFile) result;
|
||||||
tempMap.put(file.getFirstInstance().getId(), file);
|
tempMap.put(file.getFirstInstance().getId(), file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,21 +208,21 @@ public class DiscoveryAttributes {
|
|||||||
static final int BATCH_SIZE = 50; // Number of hashes to look up at one time
|
static final int BATCH_SIZE = 50; // Number of hashes to look up at one time
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
|
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
|
||||||
return new DiscoveryKeyUtils.FrequencyGroupKey(file);
|
return new DiscoveryKeyUtils.FrequencyGroupKey(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
public void addAttributeToResultFiles(List<Result> results, SleuthkitCase caseDb,
|
||||||
CentralRepository centralRepoDb) throws DiscoveryException {
|
CentralRepository centralRepoDb) throws DiscoveryException {
|
||||||
if (centralRepoDb == null) {
|
if (centralRepoDb == null) {
|
||||||
for (ResultFile file : files) {
|
for (Result result : results) {
|
||||||
if (file.getFrequency() == SearchData.Frequency.UNKNOWN && file.getFirstInstance().getKnown() == TskData.FileKnown.KNOWN) {
|
if (result.getFrequency() == SearchData.Frequency.UNKNOWN && result.getKnown() == TskData.FileKnown.KNOWN) {
|
||||||
file.setFrequency(SearchData.Frequency.KNOWN);
|
result.setFrequency(SearchData.Frequency.KNOWN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
processResultFilesForCR(files, centralRepoDb);
|
processResultFilesForCR(results, centralRepoDb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,20 +234,23 @@ public class DiscoveryAttributes {
|
|||||||
* for.
|
* for.
|
||||||
* @param centralRepoDb The central repository currently in use.
|
* @param centralRepoDb The central repository currently in use.
|
||||||
*/
|
*/
|
||||||
private void processResultFilesForCR(List<ResultFile> files,
|
private void processResultFilesForCR(List<Result> results,
|
||||||
CentralRepository centralRepoDb) {
|
CentralRepository centralRepoDb) {
|
||||||
List<ResultFile> currentFiles = new ArrayList<>();
|
List<ResultFile> currentFiles = new ArrayList<>();
|
||||||
Set<String> hashesToLookUp = new HashSet<>();
|
Set<String> hashesToLookUp = new HashSet<>();
|
||||||
for (ResultFile file : files) {
|
for (Result result : results) {
|
||||||
if (file.getFirstInstance().getKnown() == TskData.FileKnown.KNOWN) {
|
if (result.getKnown() == TskData.FileKnown.KNOWN) {
|
||||||
file.setFrequency(SearchData.Frequency.KNOWN);
|
result.setFrequency(SearchData.Frequency.KNOWN);
|
||||||
}
|
}
|
||||||
|
if (result.getType() != SearchData.Type.DOMAIN) {
|
||||||
|
ResultFile file = (ResultFile) result;
|
||||||
if (file.getFrequency() == SearchData.Frequency.UNKNOWN
|
if (file.getFrequency() == SearchData.Frequency.UNKNOWN
|
||||||
&& file.getFirstInstance().getMd5Hash() != null
|
&& file.getFirstInstance().getMd5Hash() != null
|
||||||
&& !file.getFirstInstance().getMd5Hash().isEmpty()) {
|
&& !file.getFirstInstance().getMd5Hash().isEmpty()) {
|
||||||
hashesToLookUp.add(file.getFirstInstance().getMd5Hash());
|
hashesToLookUp.add(file.getFirstInstance().getMd5Hash());
|
||||||
currentFiles.add(file);
|
currentFiles.add(file);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (hashesToLookUp.size() >= BATCH_SIZE) {
|
if (hashesToLookUp.size() >= BATCH_SIZE) {
|
||||||
computeFrequency(hashesToLookUp, currentFiles, centralRepoDb);
|
computeFrequency(hashesToLookUp, currentFiles, centralRepoDb);
|
||||||
|
|
||||||
@ -299,20 +306,23 @@ public class DiscoveryAttributes {
|
|||||||
static class HashHitsAttribute extends AttributeType {
|
static class HashHitsAttribute extends AttributeType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
|
public DiscoveryKeyUtils.GroupKey getGroupKey(Result result) {
|
||||||
return new DiscoveryKeyUtils.HashHitsGroupKey(file);
|
if (result.getType() == SearchData.Type.DOMAIN) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new DiscoveryKeyUtils.HashHitsGroupKey((ResultFile) result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
public void addAttributeToResultFiles(List<Result> results, SleuthkitCase caseDb,
|
||||||
CentralRepository centralRepoDb) throws DiscoveryException {
|
CentralRepository centralRepoDb) throws DiscoveryException {
|
||||||
|
|
||||||
// Get pairs of (object ID, hash set name) for all files in the list of files that have
|
// Get pairs of (object ID, hash set name) for all files in the list of files that have
|
||||||
// hash set hits.
|
// hash set hits.
|
||||||
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(),
|
String selectQuery = createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
|
||||||
|
|
||||||
HashSetNamesCallback callback = new HashSetNamesCallback(files);
|
HashSetNamesCallback callback = new HashSetNamesCallback(results);
|
||||||
try {
|
try {
|
||||||
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
|
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
@ -326,15 +336,15 @@ public class DiscoveryAttributes {
|
|||||||
*/
|
*/
|
||||||
private static class HashSetNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
|
private static class HashSetNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
|
||||||
|
|
||||||
List<ResultFile> resultFiles;
|
List<Result> results;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the callback.
|
* Create the callback.
|
||||||
*
|
*
|
||||||
* @param resultFiles List of files to add hash set names to
|
* @param resultFiles List of files to add hash set names to
|
||||||
*/
|
*/
|
||||||
HashSetNamesCallback(List<ResultFile> resultFiles) {
|
HashSetNamesCallback(List<Result> results) {
|
||||||
this.resultFiles = resultFiles;
|
this.results = results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -342,7 +352,11 @@ public class DiscoveryAttributes {
|
|||||||
try {
|
try {
|
||||||
// Create a temporary map of object ID to ResultFile
|
// Create a temporary map of object ID to ResultFile
|
||||||
Map<Long, ResultFile> tempMap = new HashMap<>();
|
Map<Long, ResultFile> tempMap = new HashMap<>();
|
||||||
for (ResultFile file : resultFiles) {
|
for (Result result : results) {
|
||||||
|
if (result.getType() == SearchData.Type.DOMAIN) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ResultFile file = (ResultFile) result;
|
||||||
tempMap.put(file.getFirstInstance().getId(), file);
|
tempMap.put(file.getFirstInstance().getId(), file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,20 +384,20 @@ public class DiscoveryAttributes {
|
|||||||
static class InterestingItemAttribute extends AttributeType {
|
static class InterestingItemAttribute extends AttributeType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
|
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
|
||||||
return new DiscoveryKeyUtils.InterestingItemGroupKey(file);
|
return new DiscoveryKeyUtils.InterestingItemGroupKey((ResultFile) file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
public void addAttributeToResultFiles(List<Result> results, SleuthkitCase caseDb,
|
||||||
CentralRepository centralRepoDb) throws DiscoveryException {
|
CentralRepository centralRepoDb) throws DiscoveryException {
|
||||||
|
|
||||||
// Get pairs of (object ID, interesting item set name) for all files in the list of files that have
|
// Get pairs of (object ID, interesting item set name) for all files in the list of files that have
|
||||||
// interesting file set hits.
|
// interesting file set hits.
|
||||||
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),
|
String selectQuery = createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
|
||||||
|
|
||||||
InterestingFileSetNamesCallback callback = new InterestingFileSetNamesCallback(files);
|
InterestingFileSetNamesCallback callback = new InterestingFileSetNamesCallback(results);
|
||||||
try {
|
try {
|
||||||
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
|
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
@ -398,7 +412,7 @@ public class DiscoveryAttributes {
|
|||||||
*/
|
*/
|
||||||
private static class InterestingFileSetNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
|
private static class InterestingFileSetNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
|
||||||
|
|
||||||
List<ResultFile> resultFiles;
|
List<Result> results;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the callback.
|
* Create the callback.
|
||||||
@ -406,8 +420,8 @@ public class DiscoveryAttributes {
|
|||||||
* @param resultFiles List of files to add interesting file set
|
* @param resultFiles List of files to add interesting file set
|
||||||
* names to
|
* names to
|
||||||
*/
|
*/
|
||||||
InterestingFileSetNamesCallback(List<ResultFile> resultFiles) {
|
InterestingFileSetNamesCallback(List<Result> results) {
|
||||||
this.resultFiles = resultFiles;
|
this.results = results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -415,7 +429,11 @@ public class DiscoveryAttributes {
|
|||||||
try {
|
try {
|
||||||
// Create a temporary map of object ID to ResultFile
|
// Create a temporary map of object ID to ResultFile
|
||||||
Map<Long, ResultFile> tempMap = new HashMap<>();
|
Map<Long, ResultFile> tempMap = new HashMap<>();
|
||||||
for (ResultFile file : resultFiles) {
|
for (Result result : results) {
|
||||||
|
if (result.getType() == SearchData.Type.DOMAIN) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ResultFile file = (ResultFile) result;
|
||||||
tempMap.put(file.getFirstInstance().getId(), file);
|
tempMap.put(file.getFirstInstance().getId(), file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,20 +461,20 @@ public class DiscoveryAttributes {
|
|||||||
static class ObjectDetectedAttribute extends AttributeType {
|
static class ObjectDetectedAttribute extends AttributeType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
|
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
|
||||||
return new DiscoveryKeyUtils.ObjectDetectedGroupKey(file);
|
return new DiscoveryKeyUtils.ObjectDetectedGroupKey((ResultFile) file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
public void addAttributeToResultFiles(List<Result> results, SleuthkitCase caseDb,
|
||||||
CentralRepository centralRepoDb) throws DiscoveryException {
|
CentralRepository centralRepoDb) throws DiscoveryException {
|
||||||
|
|
||||||
// Get pairs of (object ID, object type name) for all files in the list of files that have
|
// Get pairs of (object ID, object type name) for all files in the list of files that have
|
||||||
// objects detected
|
// objects detected
|
||||||
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID(),
|
String selectQuery = createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID(),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID());
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID());
|
||||||
|
|
||||||
ObjectDetectedNamesCallback callback = new ObjectDetectedNamesCallback(files);
|
ObjectDetectedNamesCallback callback = new ObjectDetectedNamesCallback(results);
|
||||||
try {
|
try {
|
||||||
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
|
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
@ -471,15 +489,15 @@ public class DiscoveryAttributes {
|
|||||||
*/
|
*/
|
||||||
private static class ObjectDetectedNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
|
private static class ObjectDetectedNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
|
||||||
|
|
||||||
List<ResultFile> resultFiles;
|
List<Result> results;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the callback.
|
* Create the callback.
|
||||||
*
|
*
|
||||||
* @param resultFiles List of files to add object detected names to
|
* @param resultFiles List of files to add object detected names to
|
||||||
*/
|
*/
|
||||||
ObjectDetectedNamesCallback(List<ResultFile> resultFiles) {
|
ObjectDetectedNamesCallback(List<Result> results) {
|
||||||
this.resultFiles = resultFiles;
|
this.results = results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -487,7 +505,11 @@ public class DiscoveryAttributes {
|
|||||||
try {
|
try {
|
||||||
// Create a temporary map of object ID to ResultFile
|
// Create a temporary map of object ID to ResultFile
|
||||||
Map<Long, ResultFile> tempMap = new HashMap<>();
|
Map<Long, ResultFile> tempMap = new HashMap<>();
|
||||||
for (ResultFile file : resultFiles) {
|
for (Result result : results) {
|
||||||
|
if (result.getType() == SearchData.Type.DOMAIN) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ResultFile file = (ResultFile) result;
|
||||||
tempMap.put(file.getFirstInstance().getId(), file);
|
tempMap.put(file.getFirstInstance().getId(), file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,20 +537,24 @@ public class DiscoveryAttributes {
|
|||||||
static class FileTagAttribute extends AttributeType {
|
static class FileTagAttribute extends AttributeType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
|
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
|
||||||
return new DiscoveryKeyUtils.FileTagGroupKey(file);
|
return new DiscoveryKeyUtils.FileTagGroupKey((ResultFile) file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
public void addAttributeToResultFiles(List<Result> results, SleuthkitCase caseDb,
|
||||||
CentralRepository centralRepoDb) throws DiscoveryException {
|
CentralRepository centralRepoDb) throws DiscoveryException {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (ResultFile resultFile : files) {
|
for (Result result : results) {
|
||||||
List<ContentTag> contentTags = caseDb.getContentTagsByContent(resultFile.getFirstInstance());
|
if (result.getType() == SearchData.Type.DOMAIN) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ResultFile file = (ResultFile) result;
|
||||||
|
List<ContentTag> contentTags = caseDb.getContentTagsByContent(file.getFirstInstance());
|
||||||
|
|
||||||
for (ContentTag tag : contentTags) {
|
for (ContentTag tag : contentTags) {
|
||||||
resultFile.addTagName(tag.getName().getDisplayName());
|
result.addTagName(tag.getName().getDisplayName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
@ -625,12 +651,16 @@ public class DiscoveryAttributes {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String createSetNameClause(List<ResultFile> files,
|
private static String createSetNameClause(List<Result> results,
|
||||||
int artifactTypeID, int setNameAttrID) throws DiscoveryException {
|
int artifactTypeID, int setNameAttrID) throws DiscoveryException {
|
||||||
|
|
||||||
// Concatenate the object IDs in the list of files
|
// Concatenate the object IDs in the list of files
|
||||||
String objIdList = ""; // NON-NLS
|
String objIdList = ""; // NON-NLS
|
||||||
for (ResultFile file : files) {
|
for (Result result : results) {
|
||||||
|
if (result.getType() == SearchData.Type.DOMAIN) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ResultFile file = (ResultFile) result;
|
||||||
if (!objIdList.isEmpty()) {
|
if (!objIdList.isEmpty()) {
|
||||||
objIdList += ","; // NON-NLS
|
objIdList += ","; // NON-NLS
|
||||||
}
|
}
|
||||||
@ -644,7 +674,8 @@ public class DiscoveryAttributes {
|
|||||||
+ "INNER JOIN blackboard_attributes ON blackboard_artifacts.artifact_id=blackboard_attributes.artifact_id "
|
+ "INNER JOIN blackboard_attributes ON blackboard_artifacts.artifact_id=blackboard_attributes.artifact_id "
|
||||||
+ "WHERE blackboard_attributes.artifact_type_id=\'" + artifactTypeID + "\' "
|
+ "WHERE blackboard_attributes.artifact_type_id=\'" + artifactTypeID + "\' "
|
||||||
+ "AND blackboard_attributes.attribute_type_id=\'" + setNameAttrID + "\' "
|
+ "AND blackboard_attributes.attribute_type_id=\'" + setNameAttrID + "\' "
|
||||||
+ "AND blackboard_artifacts.obj_id IN (" + objIdList + ") "; // NON-NLS
|
+ "AND blackboard_artifacts.obj_id IN (" + objIdList
|
||||||
|
+ ") "; // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
private DiscoveryAttributes() {
|
private DiscoveryAttributes() {
|
||||||
|
@ -197,7 +197,7 @@ public final class DiscoveryEventUtils {
|
|||||||
*/
|
*/
|
||||||
public static final class PageRetrievedEvent {
|
public static final class PageRetrievedEvent {
|
||||||
|
|
||||||
private final List<ResultFile> results;
|
private final List<Result> results;
|
||||||
private final int page;
|
private final int page;
|
||||||
private final Type resultType;
|
private final Type resultType;
|
||||||
|
|
||||||
@ -208,7 +208,7 @@ public final class DiscoveryEventUtils {
|
|||||||
* @param page The number of the page which was retrieved.
|
* @param page The number of the page which was retrieved.
|
||||||
* @param results The list of files in the page retrieved.
|
* @param results The list of files in the page retrieved.
|
||||||
*/
|
*/
|
||||||
public PageRetrievedEvent(Type resultType, int page, List<ResultFile> results) {
|
public PageRetrievedEvent(Type resultType, int page, List<Result> results) {
|
||||||
this.results = results;
|
this.results = results;
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.resultType = resultType;
|
this.resultType = resultType;
|
||||||
@ -219,7 +219,7 @@ public final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The list of files in the page retrieved.
|
* @return The list of files in the page retrieved.
|
||||||
*/
|
*/
|
||||||
public List<ResultFile> getSearchResults() {
|
public List<Result> getSearchResults() {
|
||||||
return Collections.unmodifiableList(results);
|
return Collections.unmodifiableList(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,11 +155,12 @@ public class DiscoveryKeyUtils {
|
|||||||
|
|
||||||
private final SearchData.FileSize fileSize;
|
private final SearchData.FileSize fileSize;
|
||||||
|
|
||||||
FileSizeGroupKey(ResultFile file) {
|
FileSizeGroupKey(Result file) {
|
||||||
if (file.getFileType() == SearchData.Type.VIDEO) {
|
ResultFile resultFile = (ResultFile) file;
|
||||||
fileSize = SearchData.FileSize.fromVideoSize(file.getFirstInstance().getSize());
|
if (resultFile.getFileType() == SearchData.Type.VIDEO) {
|
||||||
|
fileSize = SearchData.FileSize.fromVideoSize(resultFile.getFirstInstance().getSize());
|
||||||
} else {
|
} else {
|
||||||
fileSize = SearchData.FileSize.fromImageSize(file.getFirstInstance().getSize());
|
fileSize = SearchData.FileSize.fromImageSize(resultFile.getFirstInstance().getSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,8 +213,8 @@ public class DiscoveryKeyUtils {
|
|||||||
|
|
||||||
private final SearchData.Type fileType;
|
private final SearchData.Type fileType;
|
||||||
|
|
||||||
FileTypeGroupKey(ResultFile file) {
|
FileTypeGroupKey(Result file) {
|
||||||
fileType = file.getFileType();
|
fileType = ((ResultFile) file).getFileType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -539,19 +540,19 @@ public class DiscoveryKeyUtils {
|
|||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"# {0} - Data source name",
|
"# {0} - Data source name",
|
||||||
"# {1} - Data source ID",
|
"# {1} - Data source ID",
|
||||||
"FileSearch.DataSourceGroupKey.datasourceAndID={0}(ID: {1})",
|
"DiscoveryKeyUtils.DataSourceGroupKey.datasourceAndID={0}(ID: {1})",
|
||||||
"# {0} - Data source ID",
|
"# {0} - Data source ID",
|
||||||
"FileSearch.DataSourceGroupKey.idOnly=Data source (ID: {0})"})
|
"DiscoveryKeyUtils.DataSourceGroupKey.idOnly=Data source (ID: {0})"})
|
||||||
DataSourceGroupKey(ResultFile file) {
|
DataSourceGroupKey(Result result) {
|
||||||
dataSourceID = file.getFirstInstance().getDataSourceObjectId();
|
//get the id first so that it can be used when logging if necessary
|
||||||
|
dataSourceID = result.getDataSourceObjectId();
|
||||||
try {
|
try {
|
||||||
// The data source should be cached so this won't actually be a database query.
|
// The data source should be cached so this won't actually be a database query.
|
||||||
Content ds = file.getFirstInstance().getDataSource();
|
Content ds = result.getDataSource();
|
||||||
displayName = Bundle.FileSearch_DataSourceGroupKey_datasourceAndID(ds.getName(), ds.getId());
|
displayName = Bundle.DiscoveryKeyUtils_DataSourceGroupKey_datasourceAndID(ds.getName(), ds.getId());
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.WARNING, "Error looking up data source with ID " + dataSourceID, ex); // NON-NLS
|
logger.log(Level.WARNING, "Error looking up data source with ID " + dataSourceID, ex); // NON-NLS
|
||||||
displayName = Bundle.FileSearch_DataSourceGroupKey_idOnly(dataSourceID);
|
displayName = Bundle.DiscoveryKeyUtils_DataSourceGroupKey_idOnly(dataSourceID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,7 +647,7 @@ public class DiscoveryKeyUtils {
|
|||||||
|
|
||||||
private final SearchData.Frequency frequency;
|
private final SearchData.Frequency frequency;
|
||||||
|
|
||||||
FrequencyGroupKey(ResultFile file) {
|
FrequencyGroupKey(Result file) {
|
||||||
frequency = file.getFrequency();
|
frequency = file.getFrequency();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ public class FileSearch {
|
|||||||
|
|
||||||
private final static Logger logger = Logger.getLogger(FileSearch.class.getName());
|
private final static Logger logger = Logger.getLogger(FileSearch.class.getName());
|
||||||
private static final int MAXIMUM_CACHE_SIZE = 10;
|
private static final int MAXIMUM_CACHE_SIZE = 10;
|
||||||
private static final Cache<SearchKey, Map<GroupKey, List<ResultFile>>> searchCache = CacheBuilder.newBuilder()
|
private static final Cache<SearchKey, Map<GroupKey, List<Result>>> searchCache = CacheBuilder.newBuilder()
|
||||||
.maximumSize(MAXIMUM_CACHE_SIZE)
|
.maximumSize(MAXIMUM_CACHE_SIZE)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@ -82,18 +82,18 @@ public class FileSearch {
|
|||||||
attributesNeededForGroupingOrSorting.addAll(fileSortingMethod.getRequiredAttributes());
|
attributesNeededForGroupingOrSorting.addAll(fileSortingMethod.getRequiredAttributes());
|
||||||
|
|
||||||
// Run the queries for each filter
|
// Run the queries for each filter
|
||||||
List<ResultFile> resultFiles = SearchFiltering.runQueries(filters, caseDb, centralRepoDb);
|
List<Result> results = SearchFiltering.runQueries(filters, caseDb, centralRepoDb);
|
||||||
|
|
||||||
// Add the data to resultFiles for any attributes needed for sorting and grouping
|
// Add the data to resultFiles for any attributes needed for sorting and grouping
|
||||||
addAttributes(attributesNeededForGroupingOrSorting, resultFiles, caseDb, centralRepoDb);
|
addAttributes(attributesNeededForGroupingOrSorting, results, caseDb, centralRepoDb);
|
||||||
|
|
||||||
// Collect everything in the search results
|
// Collect everything in the search results
|
||||||
SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod);
|
SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod);
|
||||||
searchResults.add(resultFiles);
|
searchResults.add(results);
|
||||||
|
|
||||||
// Sort and group the results
|
// Sort and group the results
|
||||||
searchResults.sortGroupsAndFiles();
|
searchResults.sortGroupsAndFiles();
|
||||||
Map<GroupKey, List<ResultFile>> resultHashMap = searchResults.toLinkedHashMap();
|
Map<GroupKey, List<Result>> resultHashMap = searchResults.toLinkedHashMap();
|
||||||
SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod);
|
SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod);
|
||||||
synchronized (searchCache) {
|
synchronized (searchCache) {
|
||||||
searchCache.put(searchKey, resultHashMap);
|
searchCache.put(searchKey, resultHashMap);
|
||||||
@ -125,7 +125,7 @@ public class FileSearch {
|
|||||||
Group.GroupSortingAlgorithm groupSortingType,
|
Group.GroupSortingAlgorithm groupSortingType,
|
||||||
FileSorter.SortingMethod fileSortingMethod,
|
FileSorter.SortingMethod fileSortingMethod,
|
||||||
SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
|
SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
|
||||||
Map<GroupKey, List<ResultFile>> searchResults = runFileSearch(userName, filters,
|
Map<GroupKey, List<Result>> searchResults = runFileSearch(userName, filters,
|
||||||
groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb);
|
groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb);
|
||||||
LinkedHashMap<GroupKey, Integer> groupSizes = new LinkedHashMap<>();
|
LinkedHashMap<GroupKey, Integer> groupSizes = new LinkedHashMap<>();
|
||||||
for (GroupKey groupKey : searchResults.keySet()) {
|
for (GroupKey groupKey : searchResults.keySet()) {
|
||||||
@ -156,7 +156,7 @@ public class FileSearch {
|
|||||||
*
|
*
|
||||||
* @throws DiscoveryException
|
* @throws DiscoveryException
|
||||||
*/
|
*/
|
||||||
public static List<ResultFile> getFilesInGroup(String userName,
|
public static List<Result> getFilesInGroup(String userName,
|
||||||
List<AbstractFilter> filters,
|
List<AbstractFilter> filters,
|
||||||
AttributeType groupAttributeType,
|
AttributeType groupAttributeType,
|
||||||
Group.GroupSortingAlgorithm groupSortingType,
|
Group.GroupSortingAlgorithm groupSortingType,
|
||||||
@ -166,16 +166,16 @@ public class FileSearch {
|
|||||||
int numberOfEntries,
|
int numberOfEntries,
|
||||||
SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
|
SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
|
||||||
//the group should be in the cache at this point
|
//the group should be in the cache at this point
|
||||||
List<ResultFile> filesInGroup = null;
|
List<Result> filesInGroup = null;
|
||||||
SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod);
|
SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod);
|
||||||
Map<GroupKey, List<ResultFile>> resultsMap;
|
Map<GroupKey, List<Result>> resultsMap;
|
||||||
synchronized (searchCache) {
|
synchronized (searchCache) {
|
||||||
resultsMap = searchCache.getIfPresent(searchKey);
|
resultsMap = searchCache.getIfPresent(searchKey);
|
||||||
}
|
}
|
||||||
if (resultsMap != null) {
|
if (resultsMap != null) {
|
||||||
filesInGroup = resultsMap.get(groupKey);
|
filesInGroup = resultsMap.get(groupKey);
|
||||||
}
|
}
|
||||||
List<ResultFile> page = new ArrayList<>();
|
List<Result> page = new ArrayList<>();
|
||||||
if (filesInGroup == null) {
|
if (filesInGroup == null) {
|
||||||
logger.log(Level.INFO, "Group {0} was not cached, performing search to cache all groups again", groupKey);
|
logger.log(Level.INFO, "Group {0} was not cached, performing search to cache all groups again", groupKey);
|
||||||
runFileSearch(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb);
|
runFileSearch(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb);
|
||||||
@ -252,7 +252,7 @@ public class FileSearch {
|
|||||||
*
|
*
|
||||||
* @throws DiscoveryException
|
* @throws DiscoveryException
|
||||||
*/
|
*/
|
||||||
private static Map<GroupKey, List<ResultFile>> runFileSearch(String userName,
|
private static Map<GroupKey, List<Result>> runFileSearch(String userName,
|
||||||
List<AbstractFilter> filters,
|
List<AbstractFilter> filters,
|
||||||
AttributeType groupAttributeType,
|
AttributeType groupAttributeType,
|
||||||
Group.GroupSortingAlgorithm groupSortingType,
|
Group.GroupSortingAlgorithm groupSortingType,
|
||||||
@ -268,15 +268,15 @@ public class FileSearch {
|
|||||||
attributesNeededForGroupingOrSorting.addAll(fileSortingMethod.getRequiredAttributes());
|
attributesNeededForGroupingOrSorting.addAll(fileSortingMethod.getRequiredAttributes());
|
||||||
|
|
||||||
// Run the queries for each filter
|
// Run the queries for each filter
|
||||||
List<ResultFile> resultFiles = SearchFiltering.runQueries(filters, caseDb, centralRepoDb);
|
List<Result> results = SearchFiltering.runQueries(filters, caseDb, centralRepoDb);
|
||||||
|
|
||||||
// Add the data to resultFiles for any attributes needed for sorting and grouping
|
// Add the data to resultFiles for any attributes needed for sorting and grouping
|
||||||
addAttributes(attributesNeededForGroupingOrSorting, resultFiles, caseDb, centralRepoDb);
|
addAttributes(attributesNeededForGroupingOrSorting, results, caseDb, centralRepoDb);
|
||||||
|
|
||||||
// Collect everything in the search results
|
// Collect everything in the search results
|
||||||
SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod);
|
SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod);
|
||||||
searchResults.add(resultFiles);
|
searchResults.add(results);
|
||||||
Map<GroupKey, List<ResultFile>> resultHashMap = searchResults.toLinkedHashMap();
|
Map<GroupKey, List<Result>> resultHashMap = searchResults.toLinkedHashMap();
|
||||||
SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod);
|
SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod);
|
||||||
synchronized (searchCache) {
|
synchronized (searchCache) {
|
||||||
searchCache.put(searchKey, resultHashMap);
|
searchCache.put(searchKey, resultHashMap);
|
||||||
@ -298,10 +298,10 @@ public class FileSearch {
|
|||||||
*
|
*
|
||||||
* @throws DiscoveryException
|
* @throws DiscoveryException
|
||||||
*/
|
*/
|
||||||
private static void addAttributes(List<AttributeType> attrs, List<ResultFile> resultFiles, SleuthkitCase caseDb, CentralRepository centralRepoDb)
|
private static void addAttributes(List<AttributeType> attrs, List<Result> results, SleuthkitCase caseDb, CentralRepository centralRepoDb)
|
||||||
throws DiscoveryException {
|
throws DiscoveryException {
|
||||||
for (AttributeType attr : attrs) {
|
for (AttributeType attr : attrs) {
|
||||||
attr.addAttributeToResultFiles(resultFiles, caseDb, centralRepoDb);
|
attr.addAttributeToResultFiles(results, caseDb, centralRepoDb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,9 +29,9 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
/**
|
/**
|
||||||
* Class used to sort ResultFiles using the supplied method.
|
* Class used to sort ResultFiles using the supplied method.
|
||||||
*/
|
*/
|
||||||
public class FileSorter implements Comparator<ResultFile> {
|
public class FileSorter implements Comparator<Result> {
|
||||||
|
|
||||||
private final List<Comparator<ResultFile>> comparators = new ArrayList<>();
|
private final List<Comparator<Result>> comparators = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up the sorter using the supplied sorting method. The sorting is
|
* Set up the sorter using the supplied sorting method. The sorting is
|
||||||
@ -51,7 +51,7 @@ public class FileSorter implements Comparator<ResultFile> {
|
|||||||
comparators.add(getFileSizeComparator());
|
comparators.add(getFileSizeComparator());
|
||||||
break;
|
break;
|
||||||
case BY_FILE_TYPE:
|
case BY_FILE_TYPE:
|
||||||
comparators.add(getFileTypeComparator());
|
comparators.add(getTypeComparator());
|
||||||
comparators.add(getMIMETypeComparator());
|
comparators.add(getMIMETypeComparator());
|
||||||
break;
|
break;
|
||||||
case BY_FREQUENCY:
|
case BY_FREQUENCY:
|
||||||
@ -77,11 +77,11 @@ public class FileSorter implements Comparator<ResultFile> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
public int compare(Result result1, Result result2) {
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
for (Comparator<ResultFile> comp : comparators) {
|
for (Comparator<Result> comp : comparators) {
|
||||||
result = comp.compare(file1, file2);
|
result = comp.compare(result1, result2);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -96,8 +96,8 @@ public class FileSorter implements Comparator<ResultFile> {
|
|||||||
*
|
*
|
||||||
* @return -1 if file1 has the lower data source ID, 0 if equal, 1 otherwise
|
* @return -1 if file1 has the lower data source ID, 0 if equal, 1 otherwise
|
||||||
*/
|
*/
|
||||||
private static Comparator<ResultFile> getDataSourceComparator() {
|
private static Comparator<Result> getDataSourceComparator() {
|
||||||
return (ResultFile file1, ResultFile file2) -> Long.compare(file1.getFirstInstance().getDataSourceObjectId(), file2.getFirstInstance().getDataSourceObjectId());
|
return (Result result1, Result result2) -> Long.compare(result1.getDataSourceObjectId(), result2.getDataSourceObjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,8 +106,8 @@ public class FileSorter implements Comparator<ResultFile> {
|
|||||||
*
|
*
|
||||||
* @return -1 if file1 has the lower FileType value, 0 if equal, 1 otherwise
|
* @return -1 if file1 has the lower FileType value, 0 if equal, 1 otherwise
|
||||||
*/
|
*/
|
||||||
private static Comparator<ResultFile> getFileTypeComparator() {
|
private static Comparator<Result> getTypeComparator() {
|
||||||
return (ResultFile file1, ResultFile file2) -> Integer.compare(file1.getFileType().getRanking(), file2.getFileType().getRanking());
|
return (Result result1, Result result2) -> Integer.compare(result1.getType().getRanking(), result2.getType().getRanking());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,9 +118,14 @@ public class FileSorter implements Comparator<ResultFile> {
|
|||||||
* @return -1 if file1 has the earliest combined keyword list name, 0 if
|
* @return -1 if file1 has the earliest combined keyword list name, 0 if
|
||||||
* equal, 1 otherwise
|
* equal, 1 otherwise
|
||||||
*/
|
*/
|
||||||
private static Comparator<ResultFile> getKeywordListNameComparator() {
|
private static Comparator<Result> getKeywordListNameComparator() {
|
||||||
return (ResultFile file1, ResultFile file2) -> {
|
return (Result result1, Result result2) -> {
|
||||||
// Put empty lists at the bottom
|
// Put empty lists at the bottom
|
||||||
|
if (result1.getType() == SearchData.Type.DOMAIN) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ResultFile file1 = (ResultFile) result1;
|
||||||
|
ResultFile file2 = (ResultFile) result2;
|
||||||
if (file1.getKeywordListNames().isEmpty()) {
|
if (file1.getKeywordListNames().isEmpty()) {
|
||||||
if (file2.getKeywordListNames().isEmpty()) {
|
if (file2.getKeywordListNames().isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -142,11 +147,16 @@ public class FileSorter implements Comparator<ResultFile> {
|
|||||||
* @return -1 if file1's path comes first alphabetically, 0 if equal, 1
|
* @return -1 if file1's path comes first alphabetically, 0 if equal, 1
|
||||||
* otherwise
|
* otherwise
|
||||||
*/
|
*/
|
||||||
private static Comparator<ResultFile> getParentPathComparator() {
|
private static Comparator<Result> getParentPathComparator() {
|
||||||
|
|
||||||
return new Comparator<ResultFile>() {
|
return new Comparator<Result>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
public int compare(Result result1, Result result2) {
|
||||||
|
if (result1.getType() == SearchData.Type.DOMAIN) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ResultFile file1 = (ResultFile) result1;
|
||||||
|
ResultFile file2 = (ResultFile) result2;
|
||||||
String file1ParentPath;
|
String file1ParentPath;
|
||||||
try {
|
try {
|
||||||
file1ParentPath = file1.getFirstInstance().getParent().getUniquePath();
|
file1ParentPath = file1.getFirstInstance().getParent().getUniquePath();
|
||||||
@ -170,8 +180,8 @@ public class FileSorter implements Comparator<ResultFile> {
|
|||||||
*
|
*
|
||||||
* @return -1 if file1's rarity is lower than file2, 0 if equal, 1 otherwise
|
* @return -1 if file1's rarity is lower than file2, 0 if equal, 1 otherwise
|
||||||
*/
|
*/
|
||||||
private static Comparator<ResultFile> getFrequencyComparator() {
|
private static Comparator<Result> getFrequencyComparator() {
|
||||||
return (ResultFile file1, ResultFile file2) -> Integer.compare(file1.getFrequency().getRanking(), file2.getFrequency().getRanking());
|
return (Result result1, Result result2) -> Integer.compare(result1.getFrequency().getRanking(), result2.getFrequency().getRanking());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -180,8 +190,13 @@ public class FileSorter implements Comparator<ResultFile> {
|
|||||||
* @return -1 if file1's MIME type comes before file2's, 0 if equal, 1
|
* @return -1 if file1's MIME type comes before file2's, 0 if equal, 1
|
||||||
* otherwise
|
* otherwise
|
||||||
*/
|
*/
|
||||||
private static Comparator<ResultFile> getMIMETypeComparator() {
|
private static Comparator<Result> getMIMETypeComparator() {
|
||||||
return (ResultFile file1, ResultFile file2) -> compareStrings(file1.getFirstInstance().getMIMEType(), file2.getFirstInstance().getMIMEType());
|
return (Result result1, Result result2) -> {
|
||||||
|
if (result1.getType() == SearchData.Type.DOMAIN) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return compareStrings(((ResultFile) result1).getFirstInstance().getMIMEType(), ((ResultFile) result2).getFirstInstance().getMIMEType());
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -189,9 +204,13 @@ public class FileSorter implements Comparator<ResultFile> {
|
|||||||
*
|
*
|
||||||
* @return -1 if file1 is larger than file2, 0 if equal, 1 otherwise
|
* @return -1 if file1 is larger than file2, 0 if equal, 1 otherwise
|
||||||
*/
|
*/
|
||||||
private static Comparator<ResultFile> getFileSizeComparator() {
|
private static Comparator<Result> getFileSizeComparator() {
|
||||||
return (ResultFile file1, ResultFile file2) -> -1 * Long.compare(file1.getFirstInstance().getSize(), file2.getFirstInstance().getSize()) // Sort large to small
|
return (Result result1, Result result2) -> {
|
||||||
;
|
if (result1.getType() == SearchData.Type.DOMAIN) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1 * Long.compare(((ResultFile) result1).getFirstInstance().getSize(), ((ResultFile) result2).getFirstInstance().getSize()); // Sort large to small
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -199,8 +218,13 @@ public class FileSorter implements Comparator<ResultFile> {
|
|||||||
*
|
*
|
||||||
* @return -1 if file1 comes before file2, 0 if equal, 1 otherwise
|
* @return -1 if file1 comes before file2, 0 if equal, 1 otherwise
|
||||||
*/
|
*/
|
||||||
private static Comparator<ResultFile> getFileNameComparator() {
|
private static Comparator<Result> getFileNameComparator() {
|
||||||
return (ResultFile file1, ResultFile file2) -> compareStrings(file1.getFirstInstance().getName().toLowerCase(), file2.getFirstInstance().getName().toLowerCase());
|
return (Result result1, Result result2) -> {
|
||||||
|
if (result1.getType() == SearchData.Type.DOMAIN) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return compareStrings(((ResultFile) result1).getFirstInstance().getName().toLowerCase(), (((ResultFile) result2).getFirstInstance().getName().toLowerCase()));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -211,14 +235,21 @@ public class FileSorter implements Comparator<ResultFile> {
|
|||||||
*
|
*
|
||||||
* @return -1 if file1 comes before file2, 0 if equal, 1 otherwise
|
* @return -1 if file1 comes before file2, 0 if equal, 1 otherwise
|
||||||
*/
|
*/
|
||||||
private static Comparator<ResultFile> getDefaultComparator() {
|
private static Comparator<Result> getDefaultComparator() {
|
||||||
return (ResultFile file1, ResultFile file2) -> {
|
return (Result result1, Result result2) -> {
|
||||||
// Compare file names and then object ID (to ensure a consistent sort)
|
// Compare file names and then object ID (to ensure a consistent sort)
|
||||||
|
if (result1.getType() == SearchData.Type.DOMAIN) {
|
||||||
|
return getFrequencyComparator().compare(result1, result2);
|
||||||
|
} else {
|
||||||
|
ResultFile file1 = (ResultFile) result1;
|
||||||
|
ResultFile file2 = (ResultFile) result2;
|
||||||
int result = getFileNameComparator().compare(file1, file2);
|
int result = getFileNameComparator().compare(file1, file2);
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
return Long.compare(file1.getFirstInstance().getId(), file2.getFirstInstance().getId());
|
return Long.compare(file1.getFirstInstance().getId(), file2.getFirstInstance().getId());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,6 +265,7 @@ public class FileSorter implements Comparator<ResultFile> {
|
|||||||
String string1 = s1 == null ? "" : s1;
|
String string1 = s1 == null ? "" : s1;
|
||||||
String string2 = s2 == null ? "" : s2;
|
String string2 = s2 == null ? "" : s2;
|
||||||
return string1.compareTo(string2);
|
return string1.compareTo(string2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,7 +30,7 @@ public class Group implements Comparable<Group> {
|
|||||||
|
|
||||||
private final Group.GroupSortingAlgorithm groupSortingType;
|
private final Group.GroupSortingAlgorithm groupSortingType;
|
||||||
private final DiscoveryKeyUtils.GroupKey groupKey;
|
private final DiscoveryKeyUtils.GroupKey groupKey;
|
||||||
private final List<ResultFile> files;
|
private final List<Result> results;
|
||||||
private final String displayName;
|
private final String displayName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,21 +42,23 @@ public class Group implements Comparable<Group> {
|
|||||||
public Group(Group.GroupSortingAlgorithm groupSortingType, DiscoveryKeyUtils.GroupKey groupKey) {
|
public Group(Group.GroupSortingAlgorithm groupSortingType, DiscoveryKeyUtils.GroupKey groupKey) {
|
||||||
this.groupSortingType = groupSortingType;
|
this.groupSortingType = groupSortingType;
|
||||||
this.groupKey = groupKey;
|
this.groupKey = groupKey;
|
||||||
files = new ArrayList<>();
|
results = new ArrayList<>();
|
||||||
this.displayName = groupKey.getDisplayName();
|
this.displayName = groupKey.getDisplayName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a ResultFile to the group. Will not be sorted at this time.
|
* Add a Result to the group. Will not be sorted at this time.
|
||||||
*
|
*
|
||||||
* @param file The ResultFile to add to the FileGroup
|
* @param result The Result to add to the FileGroup
|
||||||
*/
|
*/
|
||||||
void addFile(ResultFile file) {
|
void addResult(Result result) {
|
||||||
if (files.contains(file)) {
|
if (result.getType() != SearchData.Type.DOMAIN && results.contains(result)) {
|
||||||
ResultFile existingCopy = files.get(files.indexOf(file)); //get the copy of this which exists in the list
|
//dedupe files and show instances
|
||||||
existingCopy.addDuplicate(file.getFirstInstance());
|
ResultFile existingCopy = (ResultFile)results.get(results.indexOf(result)); //get the copy of this which exists in the list
|
||||||
|
existingCopy.addDuplicate(((ResultFile)result).getFirstInstance());
|
||||||
} else {
|
} else {
|
||||||
files.add(file);
|
//Domains and non files are not being deduped currently
|
||||||
|
results.add(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +84,7 @@ public class Group implements Comparable<Group> {
|
|||||||
* Sort all the files in the group
|
* Sort all the files in the group
|
||||||
*/
|
*/
|
||||||
public void sortFiles(FileSorter sorter) {
|
public void sortFiles(FileSorter sorter) {
|
||||||
Collections.sort(files, sorter);
|
Collections.sort(results, sorter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,8 +130,8 @@ public class Group implements Comparable<Group> {
|
|||||||
* @return -1 if group1 should be displayed before group2, 1 otherwise
|
* @return -1 if group1 should be displayed before group2, 1 otherwise
|
||||||
*/
|
*/
|
||||||
private static int compareGroupsBySize(Group group1, Group group2) {
|
private static int compareGroupsBySize(Group group1, Group group2) {
|
||||||
if (group1.getFiles().size() != group2.getFiles().size()) {
|
if (group1.getResults().size() != group2.getResults().size()) {
|
||||||
return -1 * Long.compare(group1.getFiles().size(), group2.getFiles().size()); // High to low
|
return -1 * Long.compare(group1.getResults().size(), group2.getResults().size()); // High to low
|
||||||
} else {
|
} else {
|
||||||
// If the groups have the same size, fall through to the BY_GROUP_NAME sorting
|
// If the groups have the same size, fall through to the BY_GROUP_NAME sorting
|
||||||
return compareGroupsByGroupKey(group1, group2);
|
return compareGroupsByGroupKey(group1, group2);
|
||||||
@ -168,8 +170,8 @@ public class Group implements Comparable<Group> {
|
|||||||
*
|
*
|
||||||
* @return List of ResultFile objects
|
* @return List of ResultFile objects
|
||||||
*/
|
*/
|
||||||
public List<ResultFile> getFiles() {
|
public List<Result> getResults() {
|
||||||
return Collections.unmodifiableList(files);
|
return Collections.unmodifiableList(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,67 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery.search;
|
package org.sleuthkit.autopsy.discovery.search;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
import org.sleuthkit.datamodel.TskData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface implemented by all types of results.
|
* Interface implemented by all types of results.
|
||||||
*/
|
*/
|
||||||
public interface Result {
|
public abstract class Result {
|
||||||
|
|
||||||
|
private SearchData.Frequency frequency;
|
||||||
|
private final List<String> tagNames = new ArrayList<>();
|
||||||
|
|
||||||
|
public abstract long getDataSourceObjectId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the frequency of this result in the central repository.
|
||||||
|
*
|
||||||
|
* @return The Frequency enum.
|
||||||
|
*/
|
||||||
|
public SearchData.Frequency getFrequency() {
|
||||||
|
return frequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract TskData.FileKnown getKnown();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the frequency of this result in the central repository.
|
||||||
|
*
|
||||||
|
* @param frequency The frequency of the result as an enum.
|
||||||
|
*/
|
||||||
|
final public void setFrequency(SearchData.Frequency frequency) {
|
||||||
|
this.frequency = frequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Content getDataSource() throws TskCoreException;
|
||||||
|
|
||||||
|
public abstract SearchData.Type getType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a tag name that matched this file.
|
||||||
|
*
|
||||||
|
* @param tagName
|
||||||
|
*/
|
||||||
|
public void addTagName(String tagName) {
|
||||||
|
if (!tagNames.contains(tagName)) {
|
||||||
|
tagNames.add(tagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the list so the getTagNames() will be consistent regardless of the order added
|
||||||
|
Collections.sort(tagNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the tag names for this file
|
||||||
|
*
|
||||||
|
* @return the tag names that matched this file.
|
||||||
|
*/
|
||||||
|
public List<String> getTagNames() {
|
||||||
|
return Collections.unmodifiableList(tagNames);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,34 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery.search;
|
package org.sleuthkit.autopsy.discovery.search;
|
||||||
|
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
import org.sleuthkit.datamodel.TskData;
|
||||||
|
|
||||||
public class ResultDomain implements Result {
|
public class ResultDomain extends Result {
|
||||||
|
|
||||||
|
ResultDomain() {
|
||||||
|
this.setFrequency(SearchData.Frequency.UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getDataSourceObjectId() {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Content getDataSource() throws TskCoreException {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TskData.FileKnown getKnown() {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SearchData.Type getType() {
|
||||||
|
return SearchData.Type.DOMAIN;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
|||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import static org.sleuthkit.autopsy.discovery.search.SearchData.Type.OTHER;
|
import static org.sleuthkit.autopsy.discovery.search.SearchData.Type.OTHER;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.ContentTag;
|
import org.sleuthkit.datamodel.ContentTag;
|
||||||
import org.sleuthkit.datamodel.HashUtility;
|
import org.sleuthkit.datamodel.HashUtility;
|
||||||
import org.sleuthkit.datamodel.Tag;
|
import org.sleuthkit.datamodel.Tag;
|
||||||
@ -40,13 +41,11 @@ import org.sleuthkit.datamodel.TskData;
|
|||||||
/**
|
/**
|
||||||
* Container for files that holds all necessary data for grouping and sorting.
|
* Container for files that holds all necessary data for grouping and sorting.
|
||||||
*/
|
*/
|
||||||
public class ResultFile implements Result{
|
public class ResultFile extends Result {
|
||||||
|
|
||||||
private final static Logger logger = Logger.getLogger(ResultFile.class.getName());
|
private final static Logger logger = Logger.getLogger(ResultFile.class.getName());
|
||||||
private SearchData.Frequency frequency;
|
|
||||||
private final List<String> keywordListNames;
|
private final List<String> keywordListNames;
|
||||||
private final List<String> hashSetNames;
|
private final List<String> hashSetNames;
|
||||||
private final List<String> tagNames;
|
|
||||||
private final List<String> interestingSetNames;
|
private final List<String> interestingSetNames;
|
||||||
private final List<String> objectDetectedNames;
|
private final List<String> objectDetectedNames;
|
||||||
private final List<AbstractFile> instances = new ArrayList<>();
|
private final List<AbstractFile> instances = new ArrayList<>();
|
||||||
@ -73,33 +72,13 @@ public class ResultFile implements Result{
|
|||||||
deleted = true;
|
deleted = true;
|
||||||
}
|
}
|
||||||
updateScoreAndDescription(abstractFile);
|
updateScoreAndDescription(abstractFile);
|
||||||
this.frequency = SearchData.Frequency.UNKNOWN;
|
|
||||||
keywordListNames = new ArrayList<>();
|
keywordListNames = new ArrayList<>();
|
||||||
hashSetNames = new ArrayList<>();
|
hashSetNames = new ArrayList<>();
|
||||||
tagNames = new ArrayList<>();
|
|
||||||
interestingSetNames = new ArrayList<>();
|
interestingSetNames = new ArrayList<>();
|
||||||
objectDetectedNames = new ArrayList<>();
|
objectDetectedNames = new ArrayList<>();
|
||||||
fileType = fromMIMEtype(abstractFile.getMIMEType());
|
fileType = fromMIMEtype(abstractFile.getMIMEType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the frequency of this file in the central repository
|
|
||||||
*
|
|
||||||
* @return The Frequency enum
|
|
||||||
*/
|
|
||||||
public SearchData.Frequency getFrequency() {
|
|
||||||
return frequency;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the frequency of this file from the central repository
|
|
||||||
*
|
|
||||||
* @param frequency The frequency of the file as an enum
|
|
||||||
*/
|
|
||||||
public void setFrequency(SearchData.Frequency frequency) {
|
|
||||||
this.frequency = frequency;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an AbstractFile to the list of files which are instances of this
|
* Add an AbstractFile to the list of files which are instances of this
|
||||||
* file.
|
* file.
|
||||||
@ -218,29 +197,6 @@ public class ResultFile implements Result{
|
|||||||
return Collections.unmodifiableList(hashSetNames);
|
return Collections.unmodifiableList(hashSetNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a tag name that matched this file.
|
|
||||||
*
|
|
||||||
* @param tagName
|
|
||||||
*/
|
|
||||||
public void addTagName(String tagName) {
|
|
||||||
if (!tagNames.contains(tagName)) {
|
|
||||||
tagNames.add(tagName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort the list so the getTagNames() will be consistent regardless of the order added
|
|
||||||
Collections.sort(tagNames);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the tag names for this file
|
|
||||||
*
|
|
||||||
* @return the tag names that matched this file.
|
|
||||||
*/
|
|
||||||
public List<String> getTagNames() {
|
|
||||||
return Collections.unmodifiableList(tagNames);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an interesting file set name that matched this file.
|
* Add an interesting file set name that matched this file.
|
||||||
*
|
*
|
||||||
@ -300,7 +256,7 @@ public class ResultFile implements Result{
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return getFirstInstance().getName() + "(" + getFirstInstance().getId() + ") - "
|
return getFirstInstance().getName() + "(" + getFirstInstance().getId() + ") - "
|
||||||
+ getFirstInstance().getSize() + ", " + getFirstInstance().getParentPath() + ", "
|
+ getFirstInstance().getSize() + ", " + getFirstInstance().getParentPath() + ", "
|
||||||
+ getFirstInstance().getDataSourceObjectId() + ", " + frequency.toString() + ", "
|
+ getFirstInstance().getDataSourceObjectId() + ", " + getFrequency().toString() + ", "
|
||||||
+ String.join(",", keywordListNames) + ", " + getFirstInstance().getMIMEType();
|
+ String.join(",", keywordListNames) + ", " + getFirstInstance().getMIMEType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,4 +353,24 @@ public class ResultFile implements Result{
|
|||||||
}
|
}
|
||||||
return OTHER;
|
return OTHER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getDataSourceObjectId() {
|
||||||
|
return getFirstInstance().getDataSourceObjectId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Content getDataSource() throws TskCoreException {
|
||||||
|
return getFirstInstance().getDataSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TskData.FileKnown getKnown() {
|
||||||
|
return getFirstInstance().getKnown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType() {
|
||||||
|
return fileType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ public class SearchFiltering {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static List<ResultFile> runQueries(List<AbstractFilter> filters, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
|
static List<Result> runQueries(List<AbstractFilter> filters, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
|
||||||
if (caseDb == null) {
|
if (caseDb == null) {
|
||||||
throw new DiscoveryException("Case DB parameter is null"); // NON-NLS
|
throw new DiscoveryException("Case DB parameter is null"); // NON-NLS
|
||||||
}
|
}
|
||||||
@ -94,9 +94,9 @@ public class SearchFiltering {
|
|||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
* @throws DiscoveryException
|
* @throws DiscoveryException
|
||||||
*/
|
*/
|
||||||
private static List<ResultFile> getResultList(List<AbstractFilter> filters, String combinedQuery, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws TskCoreException, DiscoveryException {
|
private static List<Result> getResultList(List<AbstractFilter> filters, String combinedQuery, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws TskCoreException, DiscoveryException {
|
||||||
// Get all matching abstract files
|
// Get all matching abstract files
|
||||||
List<ResultFile> resultList = new ArrayList<>();
|
List<Result> resultList = new ArrayList<>();
|
||||||
List<AbstractFile> sqlResults = caseDb.findAllFilesWhere(combinedQuery);
|
List<AbstractFile> sqlResults = caseDb.findAllFilesWhere(combinedQuery);
|
||||||
|
|
||||||
// If there are no results, return now
|
// If there are no results, return now
|
||||||
@ -514,7 +514,7 @@ public class SearchFiltering {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ResultFile> applyAlternateFilter(List<ResultFile> currentResults, SleuthkitCase caseDb,
|
public List<Result> applyAlternateFilter(List<Result> currentResults, SleuthkitCase caseDb,
|
||||||
CentralRepository centralRepoDb) throws DiscoveryException {
|
CentralRepository centralRepoDb) throws DiscoveryException {
|
||||||
|
|
||||||
// We have to have run some kind of SQL filter before getting to this point,
|
// We have to have run some kind of SQL filter before getting to this point,
|
||||||
@ -528,8 +528,8 @@ public class SearchFiltering {
|
|||||||
freqAttr.addAttributeToResultFiles(currentResults, caseDb, centralRepoDb);
|
freqAttr.addAttributeToResultFiles(currentResults, caseDb, centralRepoDb);
|
||||||
|
|
||||||
// If the frequency matches the filter, add the file to the results
|
// If the frequency matches the filter, add the file to the results
|
||||||
List<ResultFile> frequencyResults = new ArrayList<>();
|
List<Result> frequencyResults = new ArrayList<>();
|
||||||
for (ResultFile file : currentResults) {
|
for (Result file : currentResults) {
|
||||||
if (frequencies.contains(file.getFrequency())) {
|
if (frequencies.contains(file.getFrequency())) {
|
||||||
frequencyResults.add(file);
|
frequencyResults.add(file);
|
||||||
}
|
}
|
||||||
@ -834,7 +834,7 @@ public class SearchFiltering {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ResultFile> applyAlternateFilter(List<ResultFile> currentResults, SleuthkitCase caseDb,
|
public List<Result> applyAlternateFilter(List<Result> currentResults, SleuthkitCase caseDb,
|
||||||
CentralRepository centralRepoDb) throws DiscoveryException {
|
CentralRepository centralRepoDb) throws DiscoveryException {
|
||||||
|
|
||||||
if (centralRepoDb == null) {
|
if (centralRepoDb == null) {
|
||||||
@ -848,18 +848,21 @@ public class SearchFiltering {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The matching files
|
// The matching files
|
||||||
List<ResultFile> notableResults = new ArrayList<>();
|
List<Result> notableResults = new ArrayList<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
CorrelationAttributeInstance.Type type = CorrelationAttributeInstance.getDefaultCorrelationTypes().get(CorrelationAttributeInstance.FILES_TYPE_ID);
|
CorrelationAttributeInstance.Type type = CorrelationAttributeInstance.getDefaultCorrelationTypes().get(CorrelationAttributeInstance.FILES_TYPE_ID);
|
||||||
|
|
||||||
for (ResultFile file : currentResults) {
|
for (Result result : currentResults) {
|
||||||
|
ResultFile file = (ResultFile) result;
|
||||||
|
if (result.getType() == SearchData.Type.DOMAIN) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (file.getFirstInstance().getMd5Hash() != null && !file.getFirstInstance().getMd5Hash().isEmpty()) {
|
if (file.getFirstInstance().getMd5Hash() != null && !file.getFirstInstance().getMd5Hash().isEmpty()) {
|
||||||
|
|
||||||
// Check if this file hash is marked as notable in the CR
|
// Check if this file hash is marked as notable in the CR
|
||||||
String value = file.getFirstInstance().getMd5Hash();
|
String value = file.getFirstInstance().getMd5Hash();
|
||||||
if (centralRepoDb.getCountArtifactInstancesKnownBad(type, value) > 0) {
|
if (centralRepoDb.getCountArtifactInstancesKnownBad(type, value) > 0) {
|
||||||
notableResults.add(file);
|
notableResults.add(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,15 +72,15 @@ class SearchResults {
|
|||||||
*
|
*
|
||||||
* @param files The list of ResultFiles to add.
|
* @param files The list of ResultFiles to add.
|
||||||
*/
|
*/
|
||||||
void add(List<ResultFile> files) {
|
void add(List<Result> results) {
|
||||||
for (ResultFile file : files) {
|
for (Result result : results) {
|
||||||
// Add the file to the appropriate group, creating it if necessary
|
// Add the file to the appropriate group, creating it if necessary
|
||||||
GroupKey groupKey = attrType.getGroupKey(file);
|
GroupKey groupKey = attrType.getGroupKey(result);
|
||||||
|
|
||||||
if (!groupMap.containsKey(groupKey)) {
|
if (!groupMap.containsKey(groupKey)) {
|
||||||
groupMap.put(groupKey, new Group(groupSortingType, groupKey));
|
groupMap.put(groupKey, new Group(groupSortingType, groupKey));
|
||||||
}
|
}
|
||||||
groupMap.get(groupKey).addFile(file);
|
groupMap.get(groupKey).addResult(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,25 +102,25 @@ class SearchResults {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String result = "";
|
String resultString = "";
|
||||||
if (groupList == null) {
|
if (groupList == null) {
|
||||||
return result;
|
return resultString;
|
||||||
}
|
}
|
||||||
|
|
||||||
long count = 0;
|
long count = 0;
|
||||||
for (Group group : groupList) {
|
for (Group group : groupList) {
|
||||||
result += group.getDisplayName() + "\n";
|
resultString += group.getDisplayName() + "\n";
|
||||||
|
|
||||||
for (ResultFile file : group.getFiles()) {
|
for (Result result : group.getResults()) {
|
||||||
result += " " + file.toString() + "\n";
|
resultString += " " + result.toString() + "\n";
|
||||||
count++;
|
count++;
|
||||||
if (count > MAX_OUTPUT_FILES) {
|
if (count > MAX_OUTPUT_FILES) {
|
||||||
result += "(truncated)";
|
resultString += "(truncated)";
|
||||||
return result;
|
return resultString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return resultString;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -129,7 +129,7 @@ class SearchResults {
|
|||||||
* @return The list of group names.
|
* @return The list of group names.
|
||||||
*/
|
*/
|
||||||
List<String> getGroupNamesWithCounts() {
|
List<String> getGroupNamesWithCounts() {
|
||||||
return groupList.stream().map(p -> p.getDisplayName() + " (" + p.getFiles().size() + ")").collect(Collectors.toList());
|
return groupList.stream().map(p -> p.getDisplayName() + " (" + p.getResults().size() + ")").collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,13 +139,13 @@ class SearchResults {
|
|||||||
*
|
*
|
||||||
* @return The list of result files.
|
* @return The list of result files.
|
||||||
*/
|
*/
|
||||||
List<ResultFile> getResultFilesInGroup(String groupName) {
|
List<Result> getResultFilesInGroup(String groupName) {
|
||||||
if (groupName != null) {
|
if (groupName != null) {
|
||||||
final String modifiedGroupName = groupName.replaceAll(" \\([0-9]+\\)$", "");
|
final String modifiedGroupName = groupName.replaceAll(" \\([0-9]+\\)$", "");
|
||||||
|
|
||||||
java.util.Optional<Group> fileGroup = groupList.stream().filter(p -> p.getDisplayName().equals(modifiedGroupName)).findFirst();
|
java.util.Optional<Group> group = groupList.stream().filter(p -> p.getDisplayName().equals(modifiedGroupName)).findFirst();
|
||||||
if (fileGroup.isPresent()) {
|
if (group.isPresent()) {
|
||||||
return fileGroup.get().getFiles();
|
return group.get().getResults();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
@ -156,15 +156,15 @@ class SearchResults {
|
|||||||
*
|
*
|
||||||
* @return The grouped and sorted results.
|
* @return The grouped and sorted results.
|
||||||
*/
|
*/
|
||||||
Map<GroupKey, List<ResultFile>> toLinkedHashMap() throws DiscoveryException {
|
Map<GroupKey, List<Result>> toLinkedHashMap() throws DiscoveryException {
|
||||||
Map<GroupKey, List<ResultFile>> map = new LinkedHashMap<>();
|
Map<GroupKey, List<Result>> map = new LinkedHashMap<>();
|
||||||
|
|
||||||
// Sort the groups and files
|
// Sort the groups and files
|
||||||
sortGroupsAndFiles();
|
sortGroupsAndFiles();
|
||||||
|
|
||||||
// groupList is sorted and a LinkedHashMap will preserve that order.
|
// groupList is sorted and a LinkedHashMap will preserve that order.
|
||||||
for (Group group : groupList) {
|
for (Group group : groupList) {
|
||||||
map.put(group.getGroupKey(), group.getFiles());
|
map.put(group.getGroupKey(), group.getResults());
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
|
@ -232,6 +232,7 @@ final class DiscoveryUiUtils {
|
|||||||
* Helper method to display an error message when the results of the
|
* Helper method to display an error message when the results of the
|
||||||
* Discovery Top component may be incomplete.
|
* Discovery Top component may be incomplete.
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"DiscoveryUiUtils.resultsIncomplete.text=Discovery results may be incomplete"})
|
||||||
static void displayErrorMessage(DiscoveryDialog dialog) {
|
static void displayErrorMessage(DiscoveryDialog dialog) {
|
||||||
//check if modules run and assemble message
|
//check if modules run and assemble message
|
||||||
try {
|
try {
|
||||||
@ -258,7 +259,7 @@ final class DiscoveryUiUtils {
|
|||||||
messageScrollPane.setMaximumSize(new Dimension(600, 100));
|
messageScrollPane.setMaximumSize(new Dimension(600, 100));
|
||||||
messageScrollPane.setPreferredSize(new Dimension(600, 100));
|
messageScrollPane.setPreferredSize(new Dimension(600, 100));
|
||||||
messageScrollPane.setViewportView(messageTextPane);
|
messageScrollPane.setViewportView(messageTextPane);
|
||||||
JOptionPane.showMessageDialog(dialog, messageScrollPane, Bundle.OpenDiscoveryAction_resultsIncomplete_text(), JOptionPane.PLAIN_MESSAGE);
|
JOptionPane.showMessageDialog(dialog, messageScrollPane, Bundle.DiscoveryUiUtils_resultsIncomplete_text(), JOptionPane.PLAIN_MESSAGE);
|
||||||
}
|
}
|
||||||
} catch (NoCurrentCaseException | TskCoreException ex) {
|
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||||
logger.log(Level.WARNING, "Exception while determining which modules have been run for Discovery", ex);
|
logger.log(Level.WARNING, "Exception while determining which modules have been run for Discovery", ex);
|
||||||
|
@ -62,8 +62,6 @@ public final class OpenDiscoveryAction extends CallableSystemAction implements P
|
|||||||
return Case.isCaseOpen();
|
return Case.isCaseOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NbBundle.Messages({"OpenDiscoveryAction.resultsIncomplete.text=Discovery results may be incomplete"})
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void performAction() {
|
public void performAction() {
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
@ -34,7 +34,7 @@ import org.sleuthkit.autopsy.discovery.search.FileSearch;
|
|||||||
import org.sleuthkit.autopsy.discovery.search.SearchData;
|
import org.sleuthkit.autopsy.discovery.search.SearchData;
|
||||||
import org.sleuthkit.autopsy.discovery.search.DiscoveryException;
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryException;
|
||||||
import org.sleuthkit.autopsy.discovery.search.FileSorter;
|
import org.sleuthkit.autopsy.discovery.search.FileSorter;
|
||||||
import org.sleuthkit.autopsy.discovery.search.ResultFile;
|
import org.sleuthkit.autopsy.discovery.search.Result;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SwingWorker to retrieve the contents of a page.
|
* SwingWorker to retrieve the contents of a page.
|
||||||
@ -52,7 +52,7 @@ final class PageWorker extends SwingWorker<Void, Void> {
|
|||||||
private final int pageSize;
|
private final int pageSize;
|
||||||
private final SearchData.Type resultType;
|
private final SearchData.Type resultType;
|
||||||
private final CentralRepository centralRepo;
|
private final CentralRepository centralRepo;
|
||||||
private final List<ResultFile> results = new ArrayList<>();
|
private final List<Result> results = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new PageWorker.
|
* Construct a new PageWorker.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user