19 package org.sleuthkit.autopsy.centralrepository.eventlisteners;
21 import com.google.common.util.concurrent.ThreadFactoryBuilder;
22 import java.beans.PropertyChangeEvent;
23 import java.beans.PropertyChangeListener;
24 import static java.lang.Boolean.FALSE;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Collection;
28 import java.util.EnumSet;
29 import java.util.LinkedHashSet;
30 import java.util.List;
32 import java.util.concurrent.ExecutorService;
33 import java.util.concurrent.Executors;
34 import java.util.logging.Level;
35 import java.util.stream.Collectors;
36 import org.apache.commons.lang3.StringUtils;
37 import org.openide.util.NbBundle;
52 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT;
56 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
57 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT;
58 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME;
71 @NbBundle.Messages({
"IngestEventsListener.ingestmodule.name=Central Repository"})
76 private static final String MODULE_NAME = Bundle.IngestEventsListener_ingestmodule_name();
81 private static final String INGEST_EVENT_THREAD_NAME =
"Ingest-Event-Listener-%d";
85 final Collection<String> recentlyAddedCeArtifacts =
new LinkedHashSet<>();
88 jobProcessingExecutor = Executors.newSingleThreadExecutor(
new ThreadFactoryBuilder().setNameFormat(INGEST_EVENT_THREAD_NAME).build());
116 correlationModuleInstanceCount++;
124 if (getCeModuleInstanceCount() > 0) {
125 correlationModuleInstanceCount--;
133 synchronized static void resetCeModuleInstanceCount() {
134 correlationModuleInstanceCount = 0;
144 return correlationModuleInstanceCount;
153 return flagNotableItems;
162 return flagSeenDevices;
171 return createCrProperties;
180 flagNotableItems = value;
189 flagSeenDevices = value;
198 createCrProperties = value;
209 @NbBundle.Messages({
"IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository)",
210 "IngestEventsListener.prevCaseComment.text=Previous Case: "})
212 Collection<BlackboardAttribute> attributesForNewArtifact = Arrays.asList(
213 new BlackboardAttribute(
214 TSK_SET_NAME, MODULE_NAME,
215 Bundle.IngestEventsListener_prevTaggedSet_text()),
216 new BlackboardAttribute(
217 TSK_COMMENT, MODULE_NAME,
218 Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(
","))),
219 new BlackboardAttribute(
220 TSK_ASSOCIATED_ARTIFACT, MODULE_NAME,
221 originalArtifact.getArtifactID()));
222 makeAndPostInterestingArtifact(originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevTaggedSet_text());
233 @NbBundle.Messages({
"IngestEventsListener.prevExists.text=Previously Seen Devices (Central Repository)",
236 "IngestEventsListener.prevCount.text=Number of previous {0}: {1}"})
238 Collection<BlackboardAttribute> attributesForNewArtifact = Arrays.asList(
new BlackboardAttribute(
239 TSK_SET_NAME, MODULE_NAME,
240 Bundle.IngestEventsListener_prevExists_text()),
241 new BlackboardAttribute(
242 TSK_COMMENT, MODULE_NAME,
243 Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(
","))),
244 new BlackboardAttribute(
245 TSK_ASSOCIATED_ARTIFACT, MODULE_NAME,
246 originalArtifact.getArtifactID()));
247 makeAndPostInterestingArtifact(originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text());
259 private static void makeAndPostInterestingArtifact(BlackboardArtifact originalArtifact, Collection<BlackboardAttribute> attributesForNewArtifact, String configuration) {
261 SleuthkitCase tskCase = originalArtifact.getSleuthkitCase();
262 AbstractFile abstractFile = tskCase.getAbstractFileById(originalArtifact.getObjectID());
263 Blackboard blackboard = tskCase.getBlackboard();
265 if (!blackboard.artifactExists(abstractFile, TSK_INTERESTING_ARTIFACT_HIT, attributesForNewArtifact)) {
266 BlackboardArtifact newInterestingArtifact = abstractFile.newAnalysisResult(
267 BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT, Score.SCORE_LIKELY_NOTABLE,
268 null, configuration, null, attributesForNewArtifact)
269 .getAnalysisResult();
273 blackboard.postArtifact(newInterestingArtifact, MODULE_NAME);
274 }
catch (Blackboard.BlackboardException ex) {
275 LOGGER.log(Level.SEVERE,
"Unable to index blackboard artifact " + newInterestingArtifact.getArtifactID(), ex);
278 }
catch (TskCoreException ex) {
279 LOGGER.log(Level.SEVERE,
"Failed to create BlackboardArtifact.", ex);
280 }
catch (IllegalStateException ex) {
281 LOGGER.log(Level.SEVERE,
"Failed to create BlackboardAttribute.", ex);
297 LOGGER.log(Level.SEVERE,
"Failed to connect to Central Repository database.", ex);
306 jobProcessingExecutor.submit(
new DataAddedTask(dbManager, evt, flagNotable, flagPrevious, createAttributes));
324 LOGGER.log(Level.SEVERE,
"Failed to connect to Central Repository database.", ex);
329 case DATA_SOURCE_ANALYSIS_COMPLETED: {
343 private final PropertyChangeEvent
event;
353 if (getCeModuleInstanceCount() == 0) {
354 recentlyAddedCeArtifacts.clear();
366 String dataSourceName =
"";
367 long dataSourceObjectId = -1;
374 if (!(dataSource instanceof Image)) {
378 dataSourceName = dataSource.getName();
379 dataSourceObjectId = dataSource.getId();
384 if (null == correlationCase) {
385 correlationCase = dbManager.
newCase(openCase);
389 if (correlationDataSource == null) {
394 if (dataSource instanceof Image) {
395 Image image = (Image) dataSource;
397 String imageMd5Hash = image.
getMd5();
398 if (imageMd5Hash == null) {
401 String crMd5Hash = correlationDataSource.
getMd5();
402 if (StringUtils.equals(imageMd5Hash, crMd5Hash) ==
false) {
403 correlationDataSource.
setMd5(imageMd5Hash);
406 String imageSha1Hash = image.getSha1();
407 if (imageSha1Hash == null) {
410 String crSha1Hash = correlationDataSource.
getSha1();
411 if (StringUtils.equals(imageSha1Hash, crSha1Hash) ==
false) {
412 correlationDataSource.
setSha1(imageSha1Hash);
415 String imageSha256Hash = image.getSha256();
416 if (imageSha256Hash == null) {
417 imageSha256Hash =
"";
419 String crSha256Hash = correlationDataSource.
getSha256();
420 if (StringUtils.equals(imageSha256Hash, crSha256Hash) ==
false) {
421 correlationDataSource.
setSha256(imageSha256Hash);
426 LOGGER.log(Level.SEVERE, String.format(
427 "Unable to fetch data from the Central Repository for data source '%s' (obj_id=%d)",
428 dataSourceName, dataSourceObjectId), ex);
430 LOGGER.log(Level.SEVERE,
"No current case opened.", ex);
431 }
catch (TskCoreException ex) {
432 LOGGER.log(Level.SEVERE, String.format(
433 "Unable to fetch data from the case database for data source '%s' (obj_id=%d)",
434 dataSourceName, dataSourceObjectId), ex);
442 private final PropertyChangeEvent
event;
447 private DataAddedTask(
CentralRepository db, PropertyChangeEvent evt,
boolean flagNotableItemsEnabled,
boolean flagPreviousItemsEnabled,
boolean createCorrelationAttributes) {
450 this.flagNotableItemsEnabled = flagNotableItemsEnabled;
451 this.flagPreviousItemsEnabled = flagPreviousItemsEnabled;
452 this.createCorrelationAttributes = createCorrelationAttributes;
461 Collection<BlackboardArtifact> bbArtifacts = mde.
getArtifacts();
462 if (null == bbArtifacts) {
465 List<CorrelationAttributeInstance> eamArtifacts =
new ArrayList<>();
467 for (BlackboardArtifact bbArtifact : bbArtifacts) {
473 if (recentlyAddedCeArtifacts.add(eamArtifact.toString())) {
478 if (flagNotableItemsEnabled) {
479 List<String> caseDisplayNames;
482 if (!caseDisplayNames.isEmpty()) {
483 makeAndPostPreviousNotableArtifact(bbArtifact,
487 LOGGER.log(Level.INFO, String.format(
"Unable to flag notable item: %s.", eamArtifact.toString()), ex);
490 if (flagPreviousItemsEnabled
498 List<CorrelationAttributeInstance> previousOccurences = dbManager.
getArtifactInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue());
499 List<String> caseDisplayNames;
501 if (!instance.getCorrelationCase().getCaseUUID().equals(eamArtifact.getCorrelationCase().getCaseUUID())) {
503 makeAndPostPreviousSeenArtifact(bbArtifact, caseDisplayNames);
508 LOGGER.log(Level.INFO, String.format(
"Unable to flag notable item: %s.", eamArtifact.toString()), ex);
511 if (createCorrelationAttributes) {
512 eamArtifacts.add(eamArtifact);
516 LOGGER.log(Level.SEVERE,
"Error counting notable artifacts.", ex);
520 if (FALSE == eamArtifacts.isEmpty()) {
525 LOGGER.log(Level.SEVERE,
"Error adding artifact to database.", ex);
Collection< BlackboardArtifact > getArtifacts()
void removeIngestModuleEventListener(final PropertyChangeListener listener)
static boolean flagSeenDevices
final ExecutorService jobProcessingExecutor
static final int USBID_TYPE_ID
void setMd5(String md5Hash)
static synchronized IngestManager getInstance()
final CentralRepository dbManager
static synchronized int getCeModuleInstanceCount()
List< String > getListCasesHavingArtifactInstances(CorrelationAttributeInstance.Type aType, String value)
static final int ICCID_TYPE_ID
static synchronized boolean isFlagSeenDevices()
static synchronized void setCreateCrProperties(boolean value)
static void makeAndPostPreviousSeenArtifact(BlackboardArtifact originalArtifact, List< String > caseDisplayNames)
List< CorrelationAttributeInstance > getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
static CorrelationDataSource fromTSKDataSource(CorrelationCase correlationCase, Content dataSource)
boolean isIngestRunning()
CorrelationCase getCase(Case autopsyCase)
DATA_SOURCE_ANALYSIS_COMPLETED
static final int IMEI_TYPE_ID
List< String > getListCasesHavingArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value)
static boolean createCrProperties
static synchronized boolean isFlagNotableItems()
void removeIngestJobEventListener(final PropertyChangeListener listener)
void addArtifactInstance(CorrelationAttributeInstance eamArtifact)
final boolean createCorrelationAttributes
static void shutDownTaskExecutor(ExecutorService executor)
void uninstallListeners()
static void makeAndPostInterestingArtifact(BlackboardArtifact originalArtifact, Collection< BlackboardAttribute > attributesForNewArtifact, String configuration)
final PropertyChangeEvent event
void addIngestJobEventListener(final PropertyChangeListener listener)
final boolean flagNotableItemsEnabled
void setSha256(String sha256Hash)
CorrelationCase newCase(CorrelationCase eamCase)
static synchronized void setFlagSeenDevices(boolean value)
AnalysisCompleteTask(CentralRepository db, PropertyChangeEvent evt)
void propertyChange(PropertyChangeEvent evt)
void setSha1(String sha1Hash)
void propertyChange(PropertyChangeEvent evt)
static int correlationModuleInstanceCount
static synchronized void setFlagNotableItems(boolean value)
static final int MAC_TYPE_ID
static void makeAndPostPreviousNotableArtifact(BlackboardArtifact originalArtifact, List< String > caseDisplayNames)
static List< CorrelationAttributeInstance > makeCorrAttrsToSave(BlackboardArtifact artifact)
final CentralRepository dbManager
static final int IMSI_TYPE_ID
void addIngestModuleEventListener(final PropertyChangeListener listener)
CorrelationDataSource getDataSource(CorrelationCase correlationCase, Long caseDbDataSourceId)
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
static boolean flagNotableItems
static synchronized boolean shouldCreateCrProperties()
final boolean flagPreviousItemsEnabled
DataAddedTask(CentralRepository db, PropertyChangeEvent evt, boolean flagNotableItemsEnabled, boolean flagPreviousItemsEnabled, boolean createCorrelationAttributes)
final PropertyChangeEvent event
static synchronized void incrementCorrelationEngineModuleCount()
static synchronized void decrementCorrelationEngineModuleCount()
static CentralRepository getInstance()
static boolean isEnabled()