From 04cc3de2195767439acb6632e4117467ee575492 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Wed, 25 Jul 2018 15:52:57 -0400 Subject: [PATCH 1/8] Added code to prevent duplicate hash set hits; general cleanup. --- .../casemodule/services/Blackboard.java | 112 +++++++++- .../modules/hashdatabase/Bundle.properties | 19 -- .../modules/hashdatabase/Bundle_ja.properties | 23 --- .../hashdatabase/HashDbIngestModule.java | 192 ++++++++++++------ .../hashdatabase/HashLookupModuleFactory.java | 26 +-- 5 files changed, 250 insertions(+), 122 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java index 58b4f41d6e..ee4718e8d2 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java @@ -20,9 +20,15 @@ package org.sleuthkit.autopsy.casemodule.services; import java.io.Closeable; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService; +import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.SleuthkitCase; @@ -38,7 +44,7 @@ import org.sleuthkit.datamodel.TskDataException; public final class Blackboard implements Closeable { private SleuthkitCase caseDb; - + /** * Constructs a representation of the blackboard, a place where artifacts * and their attributes are posted. @@ -80,8 +86,8 @@ public final class Blackboard implements Closeable { * * @return A type object representing the artifact type. * - * @throws BlackboardBlackboardException If there is a problem getting or - * adding the artifact type. + * @throws BlackboardException If there is a problem getting or adding the + * artifact type. */ public synchronized BlackboardArtifact.Type getOrAddArtifactType(String typeName, String displayName) throws BlackboardException { if (null == caseDb) { @@ -110,8 +116,8 @@ public final class Blackboard implements Closeable { * * @return A type object representing the attribute type. * - * @throws BlackboardBlackboardException If there is a problem getting or - * adding the attribute type. + * @throws BlackboardException If there is a problem getting or adding the + * attribute type. */ public synchronized BlackboardAttribute.Type getOrAddAttributeType(String typeName, BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType, String displayName) throws BlackboardException { if (null == caseDb) { @@ -130,6 +136,101 @@ public final class Blackboard implements Closeable { } } + /** + * Determine if an artifact of a given type exists for a given file with a + * specific set of attributes. + * + * @param file The file whose artifacts need to be looked at. + * @param artifactType The type of artifact to look for. + * @param attributesMap The collection of attributes to look for. + * + * @return True if the specific artifact exists; otherwise false. + * + * @throws BlackboardException If there is a problem getting artifacts or + * attributes. + */ + public static boolean checkIfArtifactExists(AbstractFile file, BlackboardArtifact.ARTIFACT_TYPE artifactType, + Map attributesMap) throws BlackboardException { + + ArrayList artifactsList; + + /* + * Get the file's artifacts. + */ + try { + artifactsList = file.getArtifacts(artifactType); + if (artifactsList.isEmpty()) { + return false; + } + } catch (TskCoreException ex) { + throw new BlackboardException(String.format("Failed to get %s artifacts for file '%s' (id=%d).", + artifactType.getDisplayName(), file.getName(), file.getId()), ex); + } + + /* + * Get each artifact's attributes and analyze them for matches. + */ + for (BlackboardArtifact artifact : artifactsList) { + try { + if (checkIfAttributesMatch(artifact.getAttributes(), attributesMap)) { + /* + * The exact artifact exists, so we don't need to look at + * further. + */ + return true; + } + } catch (TskCoreException ex) { + throw new BlackboardException(String.format("Failed to get attributes from artifact '%s' (id=%d).", + artifact.getName(), artifact.getObjectID()), ex); + } + } + + /* + * None of the artifacts have the exact set of attribute type/value + * combinations. The provided file does not the artifact being sought. + */ + return false; + } + + /** + * Determine if a list of attributes all match a given set of values. + * + * @param attributesList The list of attributes to analyze. + * @param attributesMap The attribute values with which to compare. + * + * @return True if all attributes match; otherwise false. + */ + private static boolean checkIfAttributesMatch(List attributesList, Map attributesMap) { + for (Map.Entry mapEntry : attributesMap.entrySet()) { + boolean match = false; + for (BlackboardAttribute attribute : attributesList) { + BlackboardAttribute.Type attributeType = attribute.getAttributeType(); + String attributeValue = attribute.getValueString(); + if (attributeType.getTypeID() == mapEntry.getKey().getTypeID() && attributeValue.equals(mapEntry.getValue())) { + /* + * The exact attribute type/value combination was found. + * Mark this as a match to continue looping through the + * attributes map. + */ + match = true; + break; + } + } + if (!match) { + /* + * The exact attribute type/value combination was not found. + */ + return false; + } + }; + + /* + * All attribute type/value combinations were found in the provided + * attributes list. + */ + return true; + } + /** * Closes the blackboard. * @@ -140,7 +241,6 @@ public final class Blackboard implements Closeable { caseDb = null; } - /** * A blackboard exception. */ diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties index c5f6d82425..3ca6c162b6 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties @@ -87,23 +87,6 @@ HashDbImportDatabaseDialog.importHashDbErr=Import Hash Set Error HashDbImportDatabaseDialog.mustSelectHashDbFilePathMsg=A hash set file path must be selected. HashDbImportDatabaseDialog.hashDbDoesNotExistMsg=The selected hash set does not exist. HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg=Failed to open hash set at {0}. -HashDbIngestModule.moduleName=Hash Lookup -HashDbIngestModule.moduleDescription=Identifies known and notable files using supplied hash sets, such as a standard NSRL hash set. -HashDbIngestModule.fileReadErrorMsg=Read Error\: {0} -HashDbIngestModule.calcHashValueErr=Error encountered while calculating the hash value for {0}. -HashDbIngestModule.hashLookupErrorMsg=Hash Lookup Error\: {0} -HashDbIngestModule.settingKnownBadStateErr=Error encountered while setting notable state for {0}. -HashDbIngestModule.lookingUpKnownBadHashValueErr=Error encountered while looking up notable hash value for {0}. -HashDbIngestModule.lookingUpKnownHashValueErr=Error encountered while looking up known hash value for {0}. -HashDbIngestModule.postToBB.fileName=File Name -HashDbIngestModule.postToBB.md5Hash=MD5 Hash -HashDbIngestModule.postToBB.hashsetName=Hash Set Name -HashDbIngestModule.postToBB.knownBadMsg=Notable\: {0} -HashDbIngestModule.complete.knownBadsFound=Notables found\: -HashDbIngestModule.complete.totalCalcTime=Total Calculation Time -HashDbIngestModule.complete.totalLookupTime=Total Lookup Time -HashDbIngestModule.complete.databasesUsed=Hash Sets Used\: -HashDbIngestModule.complete.hashLookupResults=Hash Lookup Results HashDbManager.moduleErrorListeningToUpdatesMsg=A module caused an error listening to HashDbManager updates. See log to determine which module. Some data could be incomplete. HashDbManager.replacingDuplicateHashsetNameMsg=Duplicate hash set name {0} found.\nReplacing with {1}. HashDbManager.openHashDbErr=Open Hash Set Error @@ -165,8 +148,6 @@ AddContentToHashDbAction.addFilesToHashSet.files=files AddContentToHashDbAction.addFilesToHashSet.file=file HashDbManager.errCreatingIndex.title=Error creating index HashDbManager.errCreatingIndex.msg=Error creating index\: {0} -HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg=Expected settings argument to be instanceof HashLookupModuleSettings -HashLookupModuleFactory.createFileIngestModule.exception.msg=Expected settings argument to be instanceof HashLookupModuleSettings HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.toolTipText=Calculate MD5 even if no hash set is selected HashDbSearchPanel.hashTable.defaultModel.title.text=MD5 Hashes AddHashValuesToDatabaseDialog.JDialog.Title=Add Hashes to Hash Set diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties index 828b027bdb..3d2ab7a085 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties @@ -76,28 +76,7 @@ HashDbImportDatabaseDialog.importHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\ HashDbImportDatabaseDialog.mustSelectHashDbFilePathMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u306e\u9078\u629e\u304c\u5fc5\u8981\u3067\u3059\u3002 HashDbImportDatabaseDialog.hashDbDoesNotExistMsg=\u9078\u629e\u3055\u308c\u305f\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002 HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg={0}\u3067\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u304f\u306e\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002 -HashDbIngestModule.moduleName=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7 -HashDbIngestModule.moduleDescription=\u6a19\u6e96\u306eNSRL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306a\u3069\u3001\u63d0\u4f9b\u3055\u308c\u305f\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u5229\u7528\u3057\u3066\u3001\u65e2\u77e5\u307e\u305f\u306f\u7591\u308f\u3057\u3044\u3082\u306e\u3092\u691c\u77e5\u3057\u307e\u3059\u3002 -HashDbIngestModule.noKnownHashDbSetMsg=\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\u3002 -HashDbIngestModule.knownFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u304c\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002 -HashDbIngestModule.noKnownBadHashDbSetMsg=\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30bb\u30c3\u30c8\u306f\u3042\u308a\u307e\u305b\u3093\u3002 HashDbConfigPanel.dbNotIndexedMsg=\u6b21\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3057\u307e\u3059\u304b\uff1f\n{0} -HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u60aa\u8cea\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u306f\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002 -HashDbIngestModule.fileReadErrorMsg=\u8aad\u307f\u8fbc\u307f\u30a8\u30e9\u30fc\uff1a {0} -HashDbIngestModule.calcHashValueErr={0}\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u8a08\u7b97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 -HashDbIngestModule.hashLookupErrorMsg=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u30a8\u30e9\u30fc\uff1a {0} -HashDbIngestModule.settingKnownBadStateErr={0}\u306e\u65e2\u77e5\u306e\u60aa\u8cea\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u8a2d\u5b9a\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 -HashDbIngestModule.lookingUpKnownBadHashValueErr={0}\u306e\u65e2\u77e5\u306e\u60aa\u8cea\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 -HashDbIngestModule.lookingUpKnownHashValueErr={0}\u306e\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 -HashDbIngestModule.postToBB.fileName=\u30d5\u30a1\u30a4\u30eb\u540d -HashDbIngestModule.postToBB.md5Hash=MD5\u30cf\u30c3\u30b7\u30e5 -HashDbIngestModule.postToBB.hashsetName=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d -HashDbIngestModule.postToBB.knownBadMsg=\u65e2\u77e5\u306e\u60aa\u8cea\: {0} -HashDbIngestModule.complete.knownBadsFound=\u767a\u898b\u3055\u308c\u305f\u65e2\u77e5\u306e\u60aa\u8cea\uff1a -HashDbIngestModule.complete.totalCalcTime=\u8a08\u7b97\u6642\u9593\u306e\u5408\u8a08 -HashDbIngestModule.complete.totalLookupTime=\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u6642\u9593\u306e\u5408\u8a08 -HashDbIngestModule.complete.databasesUsed=\u5229\u7528\u3057\u305f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\uff1a -HashDbIngestModule.complete.hashLookupResults=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u7d50\u679c HashDbManager.moduleErrorListeningToUpdatesMsg=HashDbManager\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u78ba\u8a8d\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u8d77\u3053\u3057\u307e\u3057\u305f\u3002\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u539f\u56e0\u306a\u306e\u304b\u3092\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u5b8c\u5168\u3067\u306a\u3044\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002 HashDbManager.replacingDuplicateHashsetNameMsg=\u91cd\u8907\u306e\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d {0} \u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002\n {1}\u306b\u66f8\u304d\u63db\u3048\u307e\u3059\u3002 HashDbManager.openHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u304f\u30a8\u30e9\u30fc @@ -163,8 +142,6 @@ HashLookupSettingsPanel.jLabel2.text=\u540d\u524d\uff1a HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082\u3001MD5\u3092\u8a08\u7b97 HashLookupModuleSettingsPanel.knownHashDbsLabel.text=\u5229\u7528\u3059\u308b\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u9078\u629e\uff1a HashLookupModuleSettingsPanel.knownBadHashDbsLabel.text=\u51e6\u7406\u306b\u5229\u7528\u3059\u308b\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u9078\u629e\uff1a -HashLookupModuleFactory.createFileIngestModule.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof HashLookupModuleSettings\u3067\u3059\u3002 -HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof HashLookupModuleSettings\u3067\u3059\u3002 HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.toolTipText=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082\u3001MD5\u3092\u8a08\u7b97 HashDbSearchPanel.hashTable.defaultModel.title.text=MD5\u30cf\u30c3\u30b7\u30e5 AddContentToHashDbAction.addFilesToHashSet.unableToAddFileEmptyMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b{0}\u3092\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30d5\u30a1\u30a4\u30eb\u306b\u30b3\u30f3\u30c6\u30f3\u30c4\u304c\u3042\u308a\u307e\u305b\u3093\u3002 diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java index 74387840b5..2a134a7fe7 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011 - 2013 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,13 +24,14 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; -import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.services.Blackboard; +import org.sleuthkit.autopsy.casemodule.services.Blackboard.BlackboardException; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.healthmonitor.HealthMonitor; @@ -48,37 +49,35 @@ import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.HashHitInfo; import org.sleuthkit.datamodel.HashUtility; -import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskException; -@NbBundle.Messages({ - "HashDbIngestModule.noKnownBadHashDbSetMsg=No notable hash set.", - "HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=Notable file search will not be executed.", - "HashDbIngestModule.noKnownHashDbSetMsg=No known hash set.", - "HashDbIngestModule.knownFileSearchWillNotExecuteWarn=Known file search will not be executed." -}) +/** + * File ingest module to mark files based on hash values. + */ public class HashDbIngestModule implements FileIngestModule { private static final Logger logger = Logger.getLogger(HashDbIngestModule.class.getName()); private static final int MAX_COMMENT_SIZE = 500; private final IngestServices services = IngestServices.getInstance(); - private final SleuthkitCase skCase; private final HashDbManager hashDbManager = HashDbManager.getInstance(); private final HashLookupModuleSettings settings; - private List knownBadHashSets = new ArrayList<>(); - private List knownHashSets = new ArrayList<>(); + private final List knownBadHashSets = new ArrayList<>(); + private final List knownHashSets = new ArrayList<>(); private long jobId; private static final HashMap totalsForIngestJobs = new HashMap<>(); private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter(); private Blackboard blackboard; + /** + * A container of values for storing ingest metrics for the job. + */ private static class IngestJobTotals { - private AtomicLong totalKnownBadCount = new AtomicLong(0); - private AtomicLong totalCalctime = new AtomicLong(0); - private AtomicLong totalLookuptime = new AtomicLong(0); + private final AtomicLong totalKnownBadCount = new AtomicLong(0); + private final AtomicLong totalCalctime = new AtomicLong(0); + private final AtomicLong totalLookuptime = new AtomicLong(0); } private static synchronized IngestJobTotals getTotalsForIngestJobs(long ingestJobId) { @@ -90,11 +89,23 @@ public class HashDbIngestModule implements FileIngestModule { return totals; } - HashDbIngestModule(HashLookupModuleSettings settings) throws NoCurrentCaseException { + /** + * Create a HashDbIngestModule object that will mark files based on a + * supplied list of hash values. The supplied HashLookupModuleSettings + * object is used to configure the module. + * + * @param settings The module settings. + */ + HashDbIngestModule(HashLookupModuleSettings settings) { this.settings = settings; - skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); } + @Messages({ + "HashDbIngestModule.noKnownBadHashDbSetMsg=No notable hash set.", + "HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=Notable file search will not be executed.", + "HashDbIngestModule.noKnownHashDbSetMsg=No known hash set.", + "HashDbIngestModule.knownFileSearchWillNotExecuteWarn=Known file search will not be executed." + }) @Override public void startUp(org.sleuthkit.autopsy.ingest.IngestJobContext context) throws IngestModuleException { jobId = context.getJobId(); @@ -140,12 +151,34 @@ public class HashDbIngestModule implements FileIngestModule { enabledHashSets.add(db); } } catch (TskCoreException ex) { - logger.log(Level.WARNING, "Error getting index status for " + db.getDisplayName()+ " hash set", ex); //NON-NLS + logger.log(Level.WARNING, "Error getting index status for " + db.getDisplayName() + " hash set", ex); //NON-NLS } } } } + @Messages({ + "# {0} - File name", + "HashDbIngestModule.fileReadErrorMsg=Read Error: {0}", + + "# {0} - File name", + "HashDbIngestModule.calcHashValueErr=Error encountered while calculating the hash value for {0}.", + + "# {0} - File name", + "HashDbIngestModule.hashLookupErrorMsg=Hash Lookup Error: {0}", + + "# {0} - File name", + "HashDbIngestModule.lookingUpKnownBadHashValueErr=Error encountered while looking up notable hash value for {0}.", + + "# {0} - File name", + "HashDbIngestModule.lookingUpKnownHashValueErr=Error encountered while looking up known hash value for {0}.", + + "# {0} - File name", + "HashDbIngestModule.dialogTitle.errorFindingArtifacts=Error Finding Artifacts: {0}", + + "# {0} - File name", + "HashDbIngestModule.errorMessage.lookingForFileArtifacts=Error encountered while looking for existing artifacts for {0}." + }) @Override public ProcessResult process(AbstractFile file) { try { @@ -156,8 +189,8 @@ public class HashDbIngestModule implements FileIngestModule { } // Skip unallocated space files. - if ((file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) || - file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.SLACK))) { + if ((file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) + || file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.SLACK))) { return ProcessResult.OK; } @@ -181,6 +214,7 @@ public class HashDbIngestModule implements FileIngestModule { // calc hash value String name = file.getName(); + long fileId = file.getId(); String md5Hash = file.getMd5Hash(); if (md5Hash == null || md5Hash.isEmpty()) { try { @@ -203,15 +237,11 @@ public class HashDbIngestModule implements FileIngestModule { totals.totalCalctime.addAndGet(delta); } catch (IOException ex) { - logger.log(Level.WARNING, "Error calculating hash of file " + name, ex); //NON-NLS + logger.log(Level.WARNING, String.format("Error calculating hash of file '%s' (id=%d).", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( HashLookupModuleFactory.getModuleName(), - NbBundle.getMessage(this.getClass(), - "HashDbIngestModule.fileReadErrorMsg", - name), - NbBundle.getMessage(this.getClass(), - "HashDbIngestModule.calcHashValueErr", - name))); + Bundle.HashDbIngestModule_fileReadErrorMsg(name), + Bundle.HashDbIngestModule_calcHashValueErr(name))); return ProcessResult.ERROR; } } @@ -245,21 +275,34 @@ public class HashDbIngestModule implements FileIngestModule { } } - postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages()); + /* + * We have a match! Now create an artifact for it is + * determined that one hasn't been created yet. + */ + Map attributeMap = new HashMap<>(); + attributeMap.put(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME), hashSetName); + if (!Blackboard.checkIfArtifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributeMap)) { + postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages()); + } } long delta = (System.currentTimeMillis() - lookupstart); totals.totalLookuptime.addAndGet(delta); - } catch (TskException ex) { - logger.log(Level.WARNING, "Couldn't lookup notable hash for file " + name + " - see sleuthkit log for details", ex); //NON-NLS + } catch (BlackboardException ex) { + logger.log(Level.SEVERE, String.format( + "A problem occurred while trying checking for existing artifacts for file '%s' (id=%d).", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( HashLookupModuleFactory.getModuleName(), - NbBundle.getMessage(this.getClass(), - "HashDbIngestModule.hashLookupErrorMsg", - name), - NbBundle.getMessage(this.getClass(), - "HashDbIngestModule.lookingUpKnownBadHashValueErr", - name))); + Bundle.HashDbIngestModule_dialogTitle_errorFindingArtifacts(name), + Bundle.HashDbIngestModule_errorMessage_lookingForFileArtifacts(name))); + ret = ProcessResult.ERROR; + } catch (TskException ex) { + logger.log(Level.WARNING, String.format( + "Couldn't lookup notable hash for file '%s' (id=%d) - see sleuthkit log for details", name, fileId), ex); //NON-NLS + services.postMessage(IngestMessage.createErrorMessage( + HashLookupModuleFactory.getModuleName(), + Bundle.HashDbIngestModule_hashLookupErrorMsg(name), + Bundle.HashDbIngestModule_lookingUpKnownBadHashValueErr(name))); ret = ProcessResult.ERROR; } } @@ -279,15 +322,12 @@ public class HashDbIngestModule implements FileIngestModule { totals.totalLookuptime.addAndGet(delta); } catch (TskException ex) { - logger.log(Level.WARNING, "Couldn't lookup known hash for file " + name + " - see sleuthkit log for details", ex); //NON-NLS + logger.log(Level.WARNING, String.format( + "Couldn't lookup known hash for file '%s' (id=%d) - see sleuthkit log for details", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( HashLookupModuleFactory.getModuleName(), - NbBundle.getMessage(this.getClass(), - "HashDbIngestModule.hashLookupErrorMsg", - name), - NbBundle.getMessage(this.getClass(), - "HashDbIngestModule.lookingUpKnownHashValueErr", - name))); + Bundle.HashDbIngestModule_hashLookupErrorMsg(name), + Bundle.HashDbIngestModule_lookingUpKnownHashValueErr(name))); ret = ProcessResult.ERROR; } } @@ -296,18 +336,35 @@ public class HashDbIngestModule implements FileIngestModule { return ret; } - @Messages({"HashDbIngestModule.indexError.message=Failed to index hashset hit artifact for keyword search."}) + /** + * Post hash set hit to the blackboard. + * + * @param abstractFile The file to be processed. + * @param md5Hash The MD5 hash value of the file. + * @param hashSetName The name of the hash set with which to associate + * the hit. + * @param comment A comment to be attached to the artifact. + * @param showInboxMessage Show a message in the inbox? + */ + @Messages({ + "HashDbIngestModule.indexError.message=Failed to index hashset hit artifact for keyword search.", + "HashDbIngestModule.postToBB.fileName=File Name", + "HashDbIngestModule.postToBB.md5Hash=MD5 Hash", + "HashDbIngestModule.postToBB.hashsetName=Hash Set Name", + + "# {0} - File name", + "HashDbIngestModule.postToBB.knownBadMsg=Notable: {0}" + }) private void postHashSetHitToBlackboard(AbstractFile abstractFile, String md5Hash, String hashSetName, String comment, boolean showInboxMessage) { try { - String MODULE_NAME = NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.moduleName"); - + String moduleName = HashLookupModuleFactory.getModuleName(); BlackboardArtifact badFile = abstractFile.newArtifact(ARTIFACT_TYPE.TSK_HASHSET_HIT); Collection attributes = new ArrayList<>(); //TODO Revisit usage of deprecated constructor as per TSK-583 //BlackboardAttribute att2 = new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID(), MODULE_NAME, "Known Bad", hashSetName); - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, hashSetName)); - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_HASH_MD5, MODULE_NAME, md5Hash)); - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT, MODULE_NAME, comment)); + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, moduleName, hashSetName)); + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_HASH_MD5, moduleName, md5Hash)); + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT, moduleName, comment)); badFile.addAttributes(attributes); @@ -327,7 +384,7 @@ public class HashDbIngestModule implements FileIngestModule { //hit detailsSb.append(""); //NON-NLS detailsSb.append("") //NON-NLS - .append(NbBundle.getMessage(this.getClass(), "HashDbIngestModule.postToBB.fileName")) + .append(Bundle.HashDbIngestModule_postToBB_fileName()) .append(""); //NON-NLS detailsSb.append("") //NON-NLS .append(abstractFile.getName()) @@ -336,14 +393,14 @@ public class HashDbIngestModule implements FileIngestModule { detailsSb.append(""); //NON-NLS detailsSb.append("") //NON-NLS - .append(NbBundle.getMessage(this.getClass(), "HashDbIngestModule.postToBB.md5Hash")) + .append(Bundle.HashDbIngestModule_postToBB_md5Hash()) .append(""); //NON-NLS detailsSb.append("").append(md5Hash).append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append("") //NON-NLS - .append(NbBundle.getMessage(this.getClass(), "HashDbIngestModule.postToBB.hashsetName")) + .append(Bundle.HashDbIngestModule_postToBB_hashsetName()) .append(""); //NON-NLS detailsSb.append("").append(hashSetName).append(""); //NON-NLS detailsSb.append(""); //NON-NLS @@ -351,19 +408,31 @@ public class HashDbIngestModule implements FileIngestModule { detailsSb.append(""); //NON-NLS services.postMessage(IngestMessage.createDataMessage(HashLookupModuleFactory.getModuleName(), - NbBundle.getMessage(this.getClass(), - "HashDbIngestModule.postToBB.knownBadMsg", - abstractFile.getName()), + Bundle.HashDbIngestModule_postToBB_knownBadMsg(abstractFile.getName()), detailsSb.toString(), abstractFile.getName() + md5Hash, badFile)); } - services.fireModuleDataEvent(new ModuleDataEvent(MODULE_NAME, ARTIFACT_TYPE.TSK_HASHSET_HIT, Collections.singletonList(badFile))); + services.fireModuleDataEvent(new ModuleDataEvent(moduleName, ARTIFACT_TYPE.TSK_HASHSET_HIT, Collections.singletonList(badFile))); } catch (TskException ex) { logger.log(Level.WARNING, "Error creating blackboard artifact", ex); //NON-NLS } } + /** + * Post a message summarizing the results of the ingest. + * + * @param jobId The ID of the job. + * @param knownBadHashSets The list of hash sets for "known bad" files. + * @param knownHashSets The list of hash sets for "known" files. + */ + @Messages({ + "HashDbIngestModule.complete.knownBadsFound=Notables found:", + "HashDbIngestModule.complete.totalCalcTime=Total Calculation Time", + "HashDbIngestModule.complete.totalLookupTime=Total Lookup Time", + "HashDbIngestModule.complete.databasesUsed=Hash Sets Used:", + "HashDbIngestModule.complete.hashLookupResults=Hash Lookup Results" + }) private static synchronized void postSummary(long jobId, List knownBadHashSets, List knownHashSets) { IngestJobTotals jobTotals = getTotalsForIngestJobs(jobId); @@ -375,20 +444,20 @@ public class HashDbIngestModule implements FileIngestModule { detailsSb.append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append("\n"); //NON-NLS detailsSb.append("\n"); //NON-NLS detailsSb.append("
") //NON-NLS - .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.knownBadsFound")) + .append(Bundle.HashDbIngestModule_complete_knownBadsFound()) .append("").append(jobTotals.totalKnownBadCount.get()).append("
") //NON-NLS - .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.totalCalcTime")) + .append(Bundle.HashDbIngestModule_complete_totalCalcTime()) .append("").append(jobTotals.totalCalctime.get()).append("
") //NON-NLS - .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.totalLookupTime")) + .append(Bundle.HashDbIngestModule_complete_totalLookupTime()) .append("").append(jobTotals.totalLookuptime.get()).append("
"); //NON-NLS detailsSb.append("

") //NON-NLS - .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.databasesUsed")) + .append(Bundle.HashDbIngestModule_complete_databasesUsed()) .append("

\n
    "); //NON-NLS for (HashDb db : knownBadHashSets) { detailsSb.append("
  • ").append(db.getHashSetName()).append("
  • \n"); //NON-NLS @@ -399,8 +468,7 @@ public class HashDbIngestModule implements FileIngestModule { IngestServices.getInstance().postMessage(IngestMessage.createMessage( IngestMessage.MessageType.INFO, HashLookupModuleFactory.getModuleName(), - NbBundle.getMessage(HashDbIngestModule.class, - "HashDbIngestModule.complete.hashLookupResults"), + Bundle.HashDbIngestModule_complete_hashLookupResults(), detailsSb.toString())); } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java index 068c52cf5e..a327a659af 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.modules.hashdatabase; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter; import org.sleuthkit.autopsy.ingest.FileIngestModule; @@ -33,6 +32,10 @@ import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; * A factory that creates file ingest modules that do hash database lookups. */ @ServiceProvider(service = IngestModuleFactory.class) +@NbBundle.Messages({ + "HashLookupModuleFactory.moduleName.text=Hash Lookup", + "HashLookupModuleFactory.moduleDescription.text=Identifies known and notable files using supplied hash sets, such as a standard NSRL hash set." +}) public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { private HashLookupModuleSettingsPanel moduleSettingsPanel = null; @@ -42,13 +45,18 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { return getModuleName(); } + /** + * Get the name of the module. + * + * @return The module name. + */ static String getModuleName() { - return NbBundle.getMessage(HashLookupModuleFactory.class, "HashDbIngestModule.moduleName"); + return Bundle.HashLookupModuleFactory_moduleName_text(); } @Override public String getModuleDescription() { - return NbBundle.getMessage(HashLookupModuleFactory.class, "HashDbIngestModule.moduleDescription"); + return Bundle.HashLookupModuleFactory_moduleDescription_text(); } @Override @@ -70,8 +78,7 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { @Override public IngestModuleIngestJobSettingsPanel getIngestJobSettingsPanel(IngestModuleIngestJobSettings settings) { if (!(settings instanceof HashLookupModuleSettings)) { - throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), - "HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg")); + throw new IllegalArgumentException("Expected settings argument to be an instance of HashLookupModuleSettings."); } if (moduleSettingsPanel == null) { moduleSettingsPanel = new HashLookupModuleSettingsPanel((HashLookupModuleSettings) settings); @@ -101,13 +108,8 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { @Override public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) { if (!(settings instanceof HashLookupModuleSettings)) { - throw new IllegalArgumentException( - NbBundle.getMessage(this.getClass(), "HashLookupModuleFactory.createFileIngestModule.exception.msg")); - } - try { - return new HashDbIngestModule((HashLookupModuleSettings) settings); - } catch (NoCurrentCaseException ex) { - throw new IllegalArgumentException("Exception while getting open case.", ex); + throw new IllegalArgumentException("Expected settings argument to be an instance of HashLookupModuleSettings."); } + return new HashDbIngestModule((HashLookupModuleSettings) settings); } } From d11dbd7b3767c99800747568c52471b386a5182c Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Wed, 25 Jul 2018 16:17:19 -0400 Subject: [PATCH 2/8] Various typos fixed. --- .../autopsy/casemodule/services/Blackboard.java | 17 ++++++++--------- .../hashdatabase/HashDbIngestModule.java | 13 +++---------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java index ee4718e8d2..234df7564b 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java @@ -21,12 +21,9 @@ package org.sleuthkit.autopsy.casemodule.services; import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.Map; -import org.openide.util.Exceptions; import org.openide.util.Lookup; -import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -174,7 +171,7 @@ public final class Blackboard implements Closeable { try { if (checkIfAttributesMatch(artifact.getAttributes(), attributesMap)) { /* - * The exact artifact exists, so we don't need to look at + * The exact artifact exists, so we don't need to look any * further. */ return true; @@ -187,18 +184,20 @@ public final class Blackboard implements Closeable { /* * None of the artifacts have the exact set of attribute type/value - * combinations. The provided file does not the artifact being sought. + * combinations. The provided file does not have the artifact being + * sought. */ return false; } /** - * Determine if a list of attributes all match a given set of values. + * Determine if the supplied attribute type/value combinations can all be + * found in the supplied attributes list. * * @param attributesList The list of attributes to analyze. - * @param attributesMap The attribute values with which to compare. + * @param attributesMap The attribute type/value combinations to check for. * - * @return True if all attributes match; otherwise false. + * @return True if all attributes are found; otherwise false. */ private static boolean checkIfAttributesMatch(List attributesList, Map attributesMap) { for (Map.Entry mapEntry : attributesMap.entrySet()) { @@ -222,7 +221,7 @@ public final class Blackboard implements Closeable { */ return false; } - }; + } /* * All attribute type/value combinations were found in the provided diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java index 2a134a7fe7..d78713f23f 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java @@ -160,22 +160,16 @@ public class HashDbIngestModule implements FileIngestModule { @Messages({ "# {0} - File name", "HashDbIngestModule.fileReadErrorMsg=Read Error: {0}", - "# {0} - File name", "HashDbIngestModule.calcHashValueErr=Error encountered while calculating the hash value for {0}.", - "# {0} - File name", "HashDbIngestModule.hashLookupErrorMsg=Hash Lookup Error: {0}", - "# {0} - File name", "HashDbIngestModule.lookingUpKnownBadHashValueErr=Error encountered while looking up notable hash value for {0}.", - "# {0} - File name", "HashDbIngestModule.lookingUpKnownHashValueErr=Error encountered while looking up known hash value for {0}.", - "# {0} - File name", "HashDbIngestModule.dialogTitle.errorFindingArtifacts=Error Finding Artifacts: {0}", - "# {0} - File name", "HashDbIngestModule.errorMessage.lookingForFileArtifacts=Error encountered while looking for existing artifacts for {0}." }) @@ -276,7 +270,7 @@ public class HashDbIngestModule implements FileIngestModule { } /* - * We have a match! Now create an artifact for it is + * We have a match. Now create an artifact if it is * determined that one hasn't been created yet. */ Map attributeMap = new HashMap<>(); @@ -290,7 +284,7 @@ public class HashDbIngestModule implements FileIngestModule { } catch (BlackboardException ex) { logger.log(Level.SEVERE, String.format( - "A problem occurred while trying checking for existing artifacts for file '%s' (id=%d).", name, fileId), ex); //NON-NLS + "A problem occurred while checking for existing artifacts for file '%s' (id=%d).", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( HashLookupModuleFactory.getModuleName(), Bundle.HashDbIngestModule_dialogTitle_errorFindingArtifacts(name), @@ -337,7 +331,7 @@ public class HashDbIngestModule implements FileIngestModule { } /** - * Post hash set hit to the blackboard. + * Post a hash set hit to the blackboard. * * @param abstractFile The file to be processed. * @param md5Hash The MD5 hash value of the file. @@ -351,7 +345,6 @@ public class HashDbIngestModule implements FileIngestModule { "HashDbIngestModule.postToBB.fileName=File Name", "HashDbIngestModule.postToBB.md5Hash=MD5 Hash", "HashDbIngestModule.postToBB.hashsetName=Hash Set Name", - "# {0} - File name", "HashDbIngestModule.postToBB.knownBadMsg=Notable: {0}" }) From fa246542f6ab9691888b0344b7e2d8033ea9253a Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Wed, 25 Jul 2018 16:57:52 -0400 Subject: [PATCH 3/8] Further cleanup. --- .../casemodule/services/Blackboard.java | 101 ------------------ .../hashdatabase/HashDbIngestModule.java | 23 ++-- 2 files changed, 12 insertions(+), 112 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java index 234df7564b..6e954ce725 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java @@ -20,12 +20,8 @@ package org.sleuthkit.autopsy.casemodule.services; import java.io.Closeable; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; import org.openide.util.Lookup; import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService; -import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.SleuthkitCase; @@ -133,103 +129,6 @@ public final class Blackboard implements Closeable { } } - /** - * Determine if an artifact of a given type exists for a given file with a - * specific set of attributes. - * - * @param file The file whose artifacts need to be looked at. - * @param artifactType The type of artifact to look for. - * @param attributesMap The collection of attributes to look for. - * - * @return True if the specific artifact exists; otherwise false. - * - * @throws BlackboardException If there is a problem getting artifacts or - * attributes. - */ - public static boolean checkIfArtifactExists(AbstractFile file, BlackboardArtifact.ARTIFACT_TYPE artifactType, - Map attributesMap) throws BlackboardException { - - ArrayList artifactsList; - - /* - * Get the file's artifacts. - */ - try { - artifactsList = file.getArtifacts(artifactType); - if (artifactsList.isEmpty()) { - return false; - } - } catch (TskCoreException ex) { - throw new BlackboardException(String.format("Failed to get %s artifacts for file '%s' (id=%d).", - artifactType.getDisplayName(), file.getName(), file.getId()), ex); - } - - /* - * Get each artifact's attributes and analyze them for matches. - */ - for (BlackboardArtifact artifact : artifactsList) { - try { - if (checkIfAttributesMatch(artifact.getAttributes(), attributesMap)) { - /* - * The exact artifact exists, so we don't need to look any - * further. - */ - return true; - } - } catch (TskCoreException ex) { - throw new BlackboardException(String.format("Failed to get attributes from artifact '%s' (id=%d).", - artifact.getName(), artifact.getObjectID()), ex); - } - } - - /* - * None of the artifacts have the exact set of attribute type/value - * combinations. The provided file does not have the artifact being - * sought. - */ - return false; - } - - /** - * Determine if the supplied attribute type/value combinations can all be - * found in the supplied attributes list. - * - * @param attributesList The list of attributes to analyze. - * @param attributesMap The attribute type/value combinations to check for. - * - * @return True if all attributes are found; otherwise false. - */ - private static boolean checkIfAttributesMatch(List attributesList, Map attributesMap) { - for (Map.Entry mapEntry : attributesMap.entrySet()) { - boolean match = false; - for (BlackboardAttribute attribute : attributesList) { - BlackboardAttribute.Type attributeType = attribute.getAttributeType(); - String attributeValue = attribute.getValueString(); - if (attributeType.getTypeID() == mapEntry.getKey().getTypeID() && attributeValue.equals(mapEntry.getValue())) { - /* - * The exact attribute type/value combination was found. - * Mark this as a match to continue looping through the - * attributes map. - */ - match = true; - break; - } - } - if (!match) { - /* - * The exact attribute type/value combination was not found. - */ - return false; - } - } - - /* - * All attribute type/value combinations were found in the provided - * attributes list. - */ - return true; - } - /** * Closes the blackboard. * diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java index d78713f23f..66ecf89aea 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java @@ -31,7 +31,6 @@ import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.services.Blackboard; -import org.sleuthkit.autopsy.casemodule.services.Blackboard.BlackboardException; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.healthmonitor.HealthMonitor; @@ -275,21 +274,23 @@ public class HashDbIngestModule implements FileIngestModule { */ Map attributeMap = new HashMap<>(); attributeMap.put(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME), hashSetName); - if (!Blackboard.checkIfArtifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributeMap)) { - postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages()); + try { + if (!org.sleuthkit.datamodel.Blackboard.checkIfArtifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributeMap)) { + postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages()); + } + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, String.format( + "A problem occurred while checking for existing artifacts for file '%s' (id=%d).", name, fileId), ex); //NON-NLS + services.postMessage(IngestMessage.createErrorMessage( + HashLookupModuleFactory.getModuleName(), + Bundle.HashDbIngestModule_dialogTitle_errorFindingArtifacts(name), + Bundle.HashDbIngestModule_errorMessage_lookingForFileArtifacts(name))); + ret = ProcessResult.ERROR; } } long delta = (System.currentTimeMillis() - lookupstart); totals.totalLookuptime.addAndGet(delta); - } catch (BlackboardException ex) { - logger.log(Level.SEVERE, String.format( - "A problem occurred while checking for existing artifacts for file '%s' (id=%d).", name, fileId), ex); //NON-NLS - services.postMessage(IngestMessage.createErrorMessage( - HashLookupModuleFactory.getModuleName(), - Bundle.HashDbIngestModule_dialogTitle_errorFindingArtifacts(name), - Bundle.HashDbIngestModule_errorMessage_lookingForFileArtifacts(name))); - ret = ProcessResult.ERROR; } catch (TskException ex) { logger.log(Level.WARNING, String.format( "Couldn't lookup notable hash for file '%s' (id=%d) - see sleuthkit log for details", name, fileId), ex); //NON-NLS From 821b8ce04e4d269514e7519f73675ae0bcda9337 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 26 Jul 2018 14:36:36 -0400 Subject: [PATCH 4/8] Using new method signature. --- .../autopsy/modules/hashdatabase/HashDbIngestModule.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java index 66ecf89aea..e018a612e1 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java @@ -272,10 +272,10 @@ public class HashDbIngestModule implements FileIngestModule { * We have a match. Now create an artifact if it is * determined that one hasn't been created yet. */ - Map attributeMap = new HashMap<>(); - attributeMap.put(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME), hashSetName); + List attributesList = new ArrayList<>(); + attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, HashLookupModuleFactory.getModuleName(), hashSetName)); try { - if (!org.sleuthkit.datamodel.Blackboard.checkIfArtifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributeMap)) { + if (!org.sleuthkit.datamodel.Blackboard.artifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributesList)) { postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages()); } } catch (TskCoreException ex) { From 4ad2b2c8fb425fb780cdc6cf84dba0812dd850c8 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 26 Jul 2018 17:22:15 -0400 Subject: [PATCH 5/8] Cleanup. --- .../modules/hashdatabase/Bundle.properties | 2 ++ .../modules/hashdatabase/Bundle_ja.properties | 22 +++++++++++++++++++ .../hashdatabase/HashDbIngestModule.java | 6 ++--- .../hashdatabase/HashLookupModuleFactory.java | 6 +++-- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties index 3ca6c162b6..c18245d7c7 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties @@ -148,6 +148,8 @@ AddContentToHashDbAction.addFilesToHashSet.files=files AddContentToHashDbAction.addFilesToHashSet.file=file HashDbManager.errCreatingIndex.title=Error creating index HashDbManager.errCreatingIndex.msg=Error creating index\: {0} +HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg=Expected settings argument to be instanceof HashLookupModuleSettings +HashLookupModuleFactory.createFileIngestModule.exception.msg=Expected settings argument to be instanceof HashLookupModuleSettings HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.toolTipText=Calculate MD5 even if no hash set is selected HashDbSearchPanel.hashTable.defaultModel.title.text=MD5 Hashes AddHashValuesToDatabaseDialog.JDialog.Title=Add Hashes to Hash Set diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties index 3d2ab7a085..d3ffff1cfb 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties @@ -76,7 +76,27 @@ HashDbImportDatabaseDialog.importHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\ HashDbImportDatabaseDialog.mustSelectHashDbFilePathMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u306e\u9078\u629e\u304c\u5fc5\u8981\u3067\u3059\u3002 HashDbImportDatabaseDialog.hashDbDoesNotExistMsg=\u9078\u629e\u3055\u308c\u305f\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002 HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg={0}\u3067\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u304f\u306e\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002 +HashLookupModuleFactory.moduleName.text=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7 +HashLookupModuleFactory.moduleDescription.text=\u6a19\u6e96\u306eNSRL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306a\u3069\u3001\u63d0\u4f9b\u3055\u308c\u305f\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u5229\u7528\u3057\u3066\u3001\u65e2\u77e5\u307e\u305f\u306f\u7591\u308f\u3057\u3044\u3082\u306e\u3092\u691c\u77e5\u3057\u307e\u3059\u3002 +HashDbIngestModule.noKnownHashDbSetMsg=\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\u3002 +HashDbIngestModule.knownFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u304c\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002 +HashDbIngestModule.noKnownBadHashDbSetMsg=\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30bb\u30c3\u30c8\u306f\u3042\u308a\u307e\u305b\u3093\u3002 HashDbConfigPanel.dbNotIndexedMsg=\u6b21\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3057\u307e\u3059\u304b\uff1f\n{0} +HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u60aa\u8cea\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u306f\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002 +HashDbIngestModule.fileReadErrorMsg=\u8aad\u307f\u8fbc\u307f\u30a8\u30e9\u30fc\uff1a {0} +HashDbIngestModule.calcHashValueErr={0}\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u8a08\u7b97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 +HashDbIngestModule.hashLookupErrorMsg=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u30a8\u30e9\u30fc\uff1a {0} +HashDbIngestModule.lookingUpKnownBadHashValueErr={0}\u306e\u65e2\u77e5\u306e\u60aa\u8cea\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 +HashDbIngestModule.lookingUpKnownHashValueErr={0}\u306e\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 +HashDbIngestModule.postToBB.fileName=\u30d5\u30a1\u30a4\u30eb\u540d +HashDbIngestModule.postToBB.md5Hash=MD5\u30cf\u30c3\u30b7\u30e5 +HashDbIngestModule.postToBB.hashsetName=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d +HashDbIngestModule.postToBB.knownBadMsg=\u65e2\u77e5\u306e\u60aa\u8cea\: {0} +HashDbIngestModule.complete.knownBadsFound=\u767a\u898b\u3055\u308c\u305f\u65e2\u77e5\u306e\u60aa\u8cea\uff1a +HashDbIngestModule.complete.totalCalcTime=\u8a08\u7b97\u6642\u9593\u306e\u5408\u8a08 +HashDbIngestModule.complete.totalLookupTime=\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u6642\u9593\u306e\u5408\u8a08 +HashDbIngestModule.complete.databasesUsed=\u5229\u7528\u3057\u305f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\uff1a +HashDbIngestModule.complete.hashLookupResults=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u7d50\u679c HashDbManager.moduleErrorListeningToUpdatesMsg=HashDbManager\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u78ba\u8a8d\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u8d77\u3053\u3057\u307e\u3057\u305f\u3002\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u539f\u56e0\u306a\u306e\u304b\u3092\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u5b8c\u5168\u3067\u306a\u3044\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002 HashDbManager.replacingDuplicateHashsetNameMsg=\u91cd\u8907\u306e\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d {0} \u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002\n {1}\u306b\u66f8\u304d\u63db\u3048\u307e\u3059\u3002 HashDbManager.openHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u304f\u30a8\u30e9\u30fc @@ -142,6 +162,8 @@ HashLookupSettingsPanel.jLabel2.text=\u540d\u524d\uff1a HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082\u3001MD5\u3092\u8a08\u7b97 HashLookupModuleSettingsPanel.knownHashDbsLabel.text=\u5229\u7528\u3059\u308b\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u9078\u629e\uff1a HashLookupModuleSettingsPanel.knownBadHashDbsLabel.text=\u51e6\u7406\u306b\u5229\u7528\u3059\u308b\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u9078\u629e\uff1a +HashLookupModuleFactory.createFileIngestModule.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof HashLookupModuleSettings\u3067\u3059\u3002 +HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof HashLookupModuleSettings\u3067\u3059\u3002 HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.toolTipText=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082\u3001MD5\u3092\u8a08\u7b97 HashDbSearchPanel.hashTable.defaultModel.title.text=MD5\u30cf\u30c3\u30b7\u30e5 AddContentToHashDbAction.addFilesToHashSet.unableToAddFileEmptyMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b{0}\u3092\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30d5\u30a1\u30a4\u30eb\u306b\u30b3\u30f3\u30c6\u30f3\u30c4\u304c\u3042\u308a\u307e\u305b\u3093\u3002 diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java index e018a612e1..3067acff4a 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java @@ -24,7 +24,6 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import org.openide.util.NbBundle.Messages; @@ -275,10 +274,11 @@ public class HashDbIngestModule implements FileIngestModule { List attributesList = new ArrayList<>(); attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, HashLookupModuleFactory.getModuleName(), hashSetName)); try { - if (!org.sleuthkit.datamodel.Blackboard.artifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributesList)) { + org.sleuthkit.datamodel.Blackboard tskBlackboard = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard(); + if (tskBlackboard.artifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributesList) == false) { postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages()); } - } catch (TskCoreException ex) { + } catch (NoCurrentCaseException | TskCoreException ex) { logger.log(Level.SEVERE, String.format( "A problem occurred while checking for existing artifacts for file '%s' (id=%d).", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java index a327a659af..51995505c5 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java @@ -78,7 +78,8 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { @Override public IngestModuleIngestJobSettingsPanel getIngestJobSettingsPanel(IngestModuleIngestJobSettings settings) { if (!(settings instanceof HashLookupModuleSettings)) { - throw new IllegalArgumentException("Expected settings argument to be an instance of HashLookupModuleSettings."); + throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), + "HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg")); } if (moduleSettingsPanel == null) { moduleSettingsPanel = new HashLookupModuleSettingsPanel((HashLookupModuleSettings) settings); @@ -108,7 +109,8 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { @Override public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) { if (!(settings instanceof HashLookupModuleSettings)) { - throw new IllegalArgumentException("Expected settings argument to be an instance of HashLookupModuleSettings."); + throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), + "HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg")); } return new HashDbIngestModule((HashLookupModuleSettings) settings); } From 5f43a4fe52d76c0aa16d2c4f64bce2d9d040d0b1 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 26 Jul 2018 22:22:02 -0400 Subject: [PATCH 6/8] Reverted comments back to 'Bundle.properties'. --- .../modules/hashdatabase/Bundle.properties | 17 +++++ .../hashdatabase/HashDbIngestModule.java | 69 +++++++------------ .../hashdatabase/HashLookupModuleFactory.java | 8 +-- 3 files changed, 43 insertions(+), 51 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties index c18245d7c7..a3f75b9048 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties @@ -87,6 +87,23 @@ HashDbImportDatabaseDialog.importHashDbErr=Import Hash Set Error HashDbImportDatabaseDialog.mustSelectHashDbFilePathMsg=A hash set file path must be selected. HashDbImportDatabaseDialog.hashDbDoesNotExistMsg=The selected hash set does not exist. HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg=Failed to open hash set at {0}. +HashLookupModuleFactory.moduleName.text=Hash Lookup +HashLookupModuleFactory.moduleDescription.text=Identifies known and notable files using supplied hash sets, such as a standard NSRL hash set. +HashDbIngestModule.fileReadErrorMsg=Read Error\: {0} +HashDbIngestModule.calcHashValueErr=Error encountered while calculating the hash value for {0}. +HashDbIngestModule.hashLookupErrorMsg=Hash Lookup Error\: {0} +HashDbIngestModule.settingKnownBadStateErr=Error encountered while setting notable state for {0}. +HashDbIngestModule.lookingUpKnownBadHashValueErr=Error encountered while looking up notable hash value for {0}. +HashDbIngestModule.lookingUpKnownHashValueErr=Error encountered while looking up known hash value for {0}. +HashDbIngestModule.postToBB.fileName=File Name +HashDbIngestModule.postToBB.md5Hash=MD5 Hash +HashDbIngestModule.postToBB.hashsetName=Hash Set Name +HashDbIngestModule.postToBB.knownBadMsg=Notable\: {0} +HashDbIngestModule.complete.knownBadsFound=Notables found\: +HashDbIngestModule.complete.totalCalcTime=Total Calculation Time +HashDbIngestModule.complete.totalLookupTime=Total Lookup Time +HashDbIngestModule.complete.databasesUsed=Hash Sets Used\: +HashDbIngestModule.complete.hashLookupResults=Hash Lookup Results HashDbManager.moduleErrorListeningToUpdatesMsg=A module caused an error listening to HashDbManager updates. See log to determine which module. Some data could be incomplete. HashDbManager.replacingDuplicateHashsetNameMsg=Duplicate hash set name {0} found.\nReplacing with {1}. HashDbManager.openHashDbErr=Open Hash Set Error diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java index 3067acff4a..46165e34fa 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; +import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -54,6 +55,12 @@ import org.sleuthkit.datamodel.TskException; /** * File ingest module to mark files based on hash values. */ +@Messages({ + "HashDbIngestModule.noKnownBadHashDbSetMsg=No notable hash set.", + "HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=Notable file search will not be executed.", + "HashDbIngestModule.noKnownHashDbSetMsg=No known hash set.", + "HashDbIngestModule.knownFileSearchWillNotExecuteWarn=Known file search will not be executed." +}) public class HashDbIngestModule implements FileIngestModule { private static final Logger logger = Logger.getLogger(HashDbIngestModule.class.getName()); @@ -98,12 +105,6 @@ public class HashDbIngestModule implements FileIngestModule { this.settings = settings; } - @Messages({ - "HashDbIngestModule.noKnownBadHashDbSetMsg=No notable hash set.", - "HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=Notable file search will not be executed.", - "HashDbIngestModule.noKnownHashDbSetMsg=No known hash set.", - "HashDbIngestModule.knownFileSearchWillNotExecuteWarn=Known file search will not be executed." - }) @Override public void startUp(org.sleuthkit.autopsy.ingest.IngestJobContext context) throws IngestModuleException { jobId = context.getJobId(); @@ -121,7 +122,7 @@ public class HashDbIngestModule implements FileIngestModule { if (knownBadHashSets.isEmpty()) { services.postMessage(IngestMessage.createWarningMessage( HashLookupModuleFactory.getModuleName(), - Bundle.HashDbIngestModule_noKnownBadHashDbSetMsg(), + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.noKnownBadHashDbSetMsg"), Bundle.HashDbIngestModule_knownBadFileSearchWillNotExecuteWarn())); } @@ -156,16 +157,6 @@ public class HashDbIngestModule implements FileIngestModule { } @Messages({ - "# {0} - File name", - "HashDbIngestModule.fileReadErrorMsg=Read Error: {0}", - "# {0} - File name", - "HashDbIngestModule.calcHashValueErr=Error encountered while calculating the hash value for {0}.", - "# {0} - File name", - "HashDbIngestModule.hashLookupErrorMsg=Hash Lookup Error: {0}", - "# {0} - File name", - "HashDbIngestModule.lookingUpKnownBadHashValueErr=Error encountered while looking up notable hash value for {0}.", - "# {0} - File name", - "HashDbIngestModule.lookingUpKnownHashValueErr=Error encountered while looking up known hash value for {0}.", "# {0} - File name", "HashDbIngestModule.dialogTitle.errorFindingArtifacts=Error Finding Artifacts: {0}", "# {0} - File name", @@ -232,8 +223,8 @@ public class HashDbIngestModule implements FileIngestModule { logger.log(Level.WARNING, String.format("Error calculating hash of file '%s' (id=%d).", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( HashLookupModuleFactory.getModuleName(), - Bundle.HashDbIngestModule_fileReadErrorMsg(name), - Bundle.HashDbIngestModule_calcHashValueErr(name))); + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.fileReadErrorMsg", name), + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.calcHashValueErr", name))); return ProcessResult.ERROR; } } @@ -296,8 +287,8 @@ public class HashDbIngestModule implements FileIngestModule { "Couldn't lookup notable hash for file '%s' (id=%d) - see sleuthkit log for details", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( HashLookupModuleFactory.getModuleName(), - Bundle.HashDbIngestModule_hashLookupErrorMsg(name), - Bundle.HashDbIngestModule_lookingUpKnownBadHashValueErr(name))); + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.hashLookupErrorMsg", name), + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.lookingUpKnownBadHashValueErr", name))); ret = ProcessResult.ERROR; } } @@ -321,8 +312,8 @@ public class HashDbIngestModule implements FileIngestModule { "Couldn't lookup known hash for file '%s' (id=%d) - see sleuthkit log for details", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( HashLookupModuleFactory.getModuleName(), - Bundle.HashDbIngestModule_hashLookupErrorMsg(name), - Bundle.HashDbIngestModule_lookingUpKnownHashValueErr(name))); + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.hashLookupErrorMsg", name), + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.lookingUpKnownHashValueErr", name))); ret = ProcessResult.ERROR; } } @@ -342,12 +333,7 @@ public class HashDbIngestModule implements FileIngestModule { * @param showInboxMessage Show a message in the inbox? */ @Messages({ - "HashDbIngestModule.indexError.message=Failed to index hashset hit artifact for keyword search.", - "HashDbIngestModule.postToBB.fileName=File Name", - "HashDbIngestModule.postToBB.md5Hash=MD5 Hash", - "HashDbIngestModule.postToBB.hashsetName=Hash Set Name", - "# {0} - File name", - "HashDbIngestModule.postToBB.knownBadMsg=Notable: {0}" + "HashDbIngestModule.indexError.message=Failed to index hashset hit artifact for keyword search." }) private void postHashSetHitToBlackboard(AbstractFile abstractFile, String md5Hash, String hashSetName, String comment, boolean showInboxMessage) { try { @@ -378,7 +364,7 @@ public class HashDbIngestModule implements FileIngestModule { //hit detailsSb.append(""); //NON-NLS detailsSb.append("") //NON-NLS - .append(Bundle.HashDbIngestModule_postToBB_fileName()) + .append(NbBundle.getMessage(this.getClass(), "HashDbIngestModule.postToBB.fileName")) .append(""); //NON-NLS detailsSb.append("") //NON-NLS .append(abstractFile.getName()) @@ -387,14 +373,14 @@ public class HashDbIngestModule implements FileIngestModule { detailsSb.append(""); //NON-NLS detailsSb.append("") //NON-NLS - .append(Bundle.HashDbIngestModule_postToBB_md5Hash()) + .append(NbBundle.getMessage(this.getClass(), "HashDbIngestModule.postToBB.md5Hash")) .append(""); //NON-NLS detailsSb.append("").append(md5Hash).append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append("") //NON-NLS - .append(Bundle.HashDbIngestModule_postToBB_hashsetName()) + .append(NbBundle.getMessage(this.getClass(), "HashDbIngestModule.postToBB.hashsetName")) .append(""); //NON-NLS detailsSb.append("").append(hashSetName).append(""); //NON-NLS detailsSb.append(""); //NON-NLS @@ -402,7 +388,7 @@ public class HashDbIngestModule implements FileIngestModule { detailsSb.append(""); //NON-NLS services.postMessage(IngestMessage.createDataMessage(HashLookupModuleFactory.getModuleName(), - Bundle.HashDbIngestModule_postToBB_knownBadMsg(abstractFile.getName()), + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.postToBB.knownBadMsg", abstractFile.getName()), detailsSb.toString(), abstractFile.getName() + md5Hash, badFile)); @@ -420,13 +406,6 @@ public class HashDbIngestModule implements FileIngestModule { * @param knownBadHashSets The list of hash sets for "known bad" files. * @param knownHashSets The list of hash sets for "known" files. */ - @Messages({ - "HashDbIngestModule.complete.knownBadsFound=Notables found:", - "HashDbIngestModule.complete.totalCalcTime=Total Calculation Time", - "HashDbIngestModule.complete.totalLookupTime=Total Lookup Time", - "HashDbIngestModule.complete.databasesUsed=Hash Sets Used:", - "HashDbIngestModule.complete.hashLookupResults=Hash Lookup Results" - }) private static synchronized void postSummary(long jobId, List knownBadHashSets, List knownHashSets) { IngestJobTotals jobTotals = getTotalsForIngestJobs(jobId); @@ -438,20 +417,20 @@ public class HashDbIngestModule implements FileIngestModule { detailsSb.append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append("\n"); //NON-NLS detailsSb.append("\n"); //NON-NLS detailsSb.append("
    ") //NON-NLS - .append(Bundle.HashDbIngestModule_complete_knownBadsFound()) + .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.knownBadsFound")) .append("").append(jobTotals.totalKnownBadCount.get()).append("
    ") //NON-NLS - .append(Bundle.HashDbIngestModule_complete_totalCalcTime()) + .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.totalCalcTime")) .append("").append(jobTotals.totalCalctime.get()).append("
    ") //NON-NLS - .append(Bundle.HashDbIngestModule_complete_totalLookupTime()) + .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.totalLookupTime")) .append("").append(jobTotals.totalLookuptime.get()).append("
    "); //NON-NLS detailsSb.append("

    ") //NON-NLS - .append(Bundle.HashDbIngestModule_complete_databasesUsed()) + .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.databasesUsed")) .append("

    \n
      "); //NON-NLS for (HashDb db : knownBadHashSets) { detailsSb.append("
    • ").append(db.getHashSetName()).append("
    • \n"); //NON-NLS @@ -462,7 +441,7 @@ public class HashDbIngestModule implements FileIngestModule { IngestServices.getInstance().postMessage(IngestMessage.createMessage( IngestMessage.MessageType.INFO, HashLookupModuleFactory.getModuleName(), - Bundle.HashDbIngestModule_complete_hashLookupResults(), + NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.hashLookupResults"), detailsSb.toString())); } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java index 51995505c5..fc9ab24521 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java @@ -32,10 +32,6 @@ import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; * A factory that creates file ingest modules that do hash database lookups. */ @ServiceProvider(service = IngestModuleFactory.class) -@NbBundle.Messages({ - "HashLookupModuleFactory.moduleName.text=Hash Lookup", - "HashLookupModuleFactory.moduleDescription.text=Identifies known and notable files using supplied hash sets, such as a standard NSRL hash set." -}) public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { private HashLookupModuleSettingsPanel moduleSettingsPanel = null; @@ -51,12 +47,12 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { * @return The module name. */ static String getModuleName() { - return Bundle.HashLookupModuleFactory_moduleName_text(); + return NbBundle.getMessage(HashLookupModuleFactory.class, "HashLookupModuleFactory.moduleName.text"); } @Override public String getModuleDescription() { - return Bundle.HashLookupModuleFactory_moduleDescription_text(); + return NbBundle.getMessage(HashLookupModuleFactory.class, "HashLookupModuleFactory.moduleDescription.text"); } @Override From dfd97722f9e1d5d7d90b74c32a3d3401c2fc35b9 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 26 Jul 2018 23:08:46 -0400 Subject: [PATCH 7/8] Put SleuthkitCase object back in constructor. --- .../modules/hashdatabase/HashDbIngestModule.java | 13 +++++++++---- .../hashdatabase/HashLookupModuleFactory.java | 7 ++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java index 46165e34fa..ee3ba1c089 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java @@ -48,6 +48,7 @@ import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.HashHitInfo; import org.sleuthkit.datamodel.HashUtility; +import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskException; @@ -66,6 +67,7 @@ public class HashDbIngestModule implements FileIngestModule { private static final Logger logger = Logger.getLogger(HashDbIngestModule.class.getName()); private static final int MAX_COMMENT_SIZE = 500; private final IngestServices services = IngestServices.getInstance(); + private final SleuthkitCase skCase; private final HashDbManager hashDbManager = HashDbManager.getInstance(); private final HashLookupModuleSettings settings; private final List knownBadHashSets = new ArrayList<>(); @@ -100,9 +102,12 @@ public class HashDbIngestModule implements FileIngestModule { * object is used to configure the module. * * @param settings The module settings. + * + * @throws NoCurrentCaseException If there is no open case. */ - HashDbIngestModule(HashLookupModuleSettings settings) { + HashDbIngestModule(HashLookupModuleSettings settings) throws NoCurrentCaseException { this.settings = settings; + skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); } @Override @@ -122,7 +127,7 @@ public class HashDbIngestModule implements FileIngestModule { if (knownBadHashSets.isEmpty()) { services.postMessage(IngestMessage.createWarningMessage( HashLookupModuleFactory.getModuleName(), - NbBundle.getMessage(this.getClass(), "HashDbIngestModule.noKnownBadHashDbSetMsg"), + Bundle.HashDbIngestModule_noKnownBadHashDbSetMsg(), Bundle.HashDbIngestModule_knownBadFileSearchWillNotExecuteWarn())); } @@ -265,11 +270,11 @@ public class HashDbIngestModule implements FileIngestModule { List attributesList = new ArrayList<>(); attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, HashLookupModuleFactory.getModuleName(), hashSetName)); try { - org.sleuthkit.datamodel.Blackboard tskBlackboard = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard(); + org.sleuthkit.datamodel.Blackboard tskBlackboard = skCase.getBlackboard(); if (tskBlackboard.artifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributesList) == false) { postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages()); } - } catch (NoCurrentCaseException | TskCoreException ex) { + } catch (TskCoreException ex) { logger.log(Level.SEVERE, String.format( "A problem occurred while checking for existing artifacts for file '%s' (id=%d).", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java index fc9ab24521..2a20eb8900 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.modules.hashdatabase; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter; import org.sleuthkit.autopsy.ingest.FileIngestModule; @@ -108,6 +109,10 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), "HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg")); } - return new HashDbIngestModule((HashLookupModuleSettings) settings); + try { + return new HashDbIngestModule((HashLookupModuleSettings) settings); + } catch (NoCurrentCaseException ex) { + throw new IllegalArgumentException("Exception while getting open case.", ex); + } } } From d01f254d6bd58ce27aefa2e978f25405b9918dc6 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 26 Jul 2018 23:16:30 -0400 Subject: [PATCH 8/8] Typo fixed. --- .../autopsy/modules/hashdatabase/HashLookupModuleFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java index 2a20eb8900..af27157fd8 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java @@ -107,7 +107,7 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) { if (!(settings instanceof HashLookupModuleSettings)) { throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), - "HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg")); + "HashLookupModuleFactory.createFileIngestModule.exception.msg")); } try { return new HashDbIngestModule((HashLookupModuleSettings) settings);