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;
70 @NbBundle.Messages({
"IngestEventsListener.ingestmodule.name=Correlation Engine"})
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;
206 @NbBundle.Messages({
"IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository)",
207 "IngestEventsListener.prevCaseComment.text=Previous Case: "})
210 Collection<BlackboardAttribute> attributesForNewArtifact = Arrays.asList(
new BlackboardAttribute(
211 TSK_SET_NAME, MODULE_NAME,
212 Bundle.IngestEventsListener_prevTaggedSet_text()),
213 new BlackboardAttribute(
214 TSK_COMMENT, MODULE_NAME,
215 Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(
","))),
216 new BlackboardAttribute(
217 TSK_ASSOCIATED_ARTIFACT, MODULE_NAME,
218 originalArtifact.getArtifactID()));
219 makeAndPostInterestingArtifact(originalArtifact, attributesForNewArtifact);
229 @NbBundle.Messages({
"IngestEventsListener.prevExists.text=Previously Seen Devices (Central Repository)",
232 "IngestEventsListener.prevCount.text=Number of previous {0}: {1}"})
234 Collection<BlackboardAttribute> attributesForNewArtifact = Arrays.asList(
new BlackboardAttribute(
235 TSK_SET_NAME, MODULE_NAME,
236 Bundle.IngestEventsListener_prevExists_text()),
237 new BlackboardAttribute(
238 TSK_COMMENT, MODULE_NAME,
239 Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(
","))),
240 new BlackboardAttribute(
241 TSK_ASSOCIATED_ARTIFACT, MODULE_NAME,
242 originalArtifact.getArtifactID()));
243 makeAndPostInterestingArtifact(originalArtifact, attributesForNewArtifact);
253 SleuthkitCase tskCase = originalArtifact.getSleuthkitCase();
254 AbstractFile abstractFile = tskCase.getAbstractFileById(originalArtifact.getObjectID());
255 Blackboard blackboard = tskCase.getBlackboard();
257 if (!blackboard.artifactExists(abstractFile, TSK_INTERESTING_ARTIFACT_HIT, attributesForNewArtifact)) {
258 BlackboardArtifact newInterestingArtifact = abstractFile.newArtifact(TSK_INTERESTING_ARTIFACT_HIT);
259 newInterestingArtifact.addAttributes(attributesForNewArtifact);
263 blackboard.postArtifact(newInterestingArtifact, MODULE_NAME);
264 }
catch (Blackboard.BlackboardException ex) {
265 LOGGER.log(Level.SEVERE,
"Unable to index blackboard artifact " + newInterestingArtifact.getArtifactID(), ex);
268 }
catch (TskCoreException ex) {
269 LOGGER.log(Level.SEVERE,
"Failed to create BlackboardArtifact.", ex);
270 }
catch (IllegalStateException ex) {
271 LOGGER.log(Level.SEVERE,
"Failed to create BlackboardAttribute.", ex);
287 LOGGER.log(Level.SEVERE,
"Failed to connect to Central Repository database.", ex);
296 jobProcessingExecutor.submit(
new DataAddedTask(dbManager, evt, flagNotable, flagPrevious, createAttributes));
314 LOGGER.log(Level.SEVERE,
"Failed to connect to Central Repository database.", ex);
319 case DATA_SOURCE_ANALYSIS_COMPLETED: {
333 private final PropertyChangeEvent
event;
343 if (getCeModuleInstanceCount() == 0) {
344 recentlyAddedCeArtifacts.clear();
356 String dataSourceName =
"";
357 long dataSourceObjectId = -1;
364 if (!(dataSource instanceof Image)) {
368 dataSourceName = dataSource.getName();
369 dataSourceObjectId = dataSource.getId();
374 if (null == correlationCase) {
375 correlationCase = dbManager.
newCase(openCase);
379 if (correlationDataSource == null) {
384 if (dataSource instanceof Image) {
385 Image image = (Image) dataSource;
387 String imageMd5Hash = image.
getMd5();
388 if (imageMd5Hash == null) {
391 String crMd5Hash = correlationDataSource.
getMd5();
392 if (StringUtils.equals(imageMd5Hash, crMd5Hash) ==
false) {
393 correlationDataSource.
setMd5(imageMd5Hash);
396 String imageSha1Hash = image.getSha1();
397 if (imageSha1Hash == null) {
400 String crSha1Hash = correlationDataSource.
getSha1();
401 if (StringUtils.equals(imageSha1Hash, crSha1Hash) ==
false) {
402 correlationDataSource.
setSha1(imageSha1Hash);
405 String imageSha256Hash = image.getSha256();
406 if (imageSha256Hash == null) {
407 imageSha256Hash =
"";
409 String crSha256Hash = correlationDataSource.
getSha256();
410 if (StringUtils.equals(imageSha256Hash, crSha256Hash) ==
false) {
411 correlationDataSource.
setSha256(imageSha256Hash);
416 LOGGER.log(Level.SEVERE, String.format(
417 "Unable to fetch data from the Central Repository for data source '%s' (obj_id=%d)",
418 dataSourceName, dataSourceObjectId), ex);
420 LOGGER.log(Level.SEVERE,
"No current case opened.", ex);
421 }
catch (TskCoreException ex) {
422 LOGGER.log(Level.SEVERE, String.format(
423 "Unable to fetch data from the case database for data source '%s' (obj_id=%d)",
424 dataSourceName, dataSourceObjectId), ex);
432 private final PropertyChangeEvent
event;
437 private DataAddedTask(
CentralRepository db, PropertyChangeEvent evt,
boolean flagNotableItemsEnabled,
boolean flagPreviousItemsEnabled,
boolean createCorrelationAttributes) {
440 this.flagNotableItemsEnabled = flagNotableItemsEnabled;
441 this.flagPreviousItemsEnabled = flagPreviousItemsEnabled;
442 this.createCorrelationAttributes = createCorrelationAttributes;
451 Collection<BlackboardArtifact> bbArtifacts = mde.
getArtifacts();
452 if (null == bbArtifacts) {
455 List<CorrelationAttributeInstance> eamArtifacts =
new ArrayList<>();
457 for (BlackboardArtifact bbArtifact : bbArtifacts) {
463 if (recentlyAddedCeArtifacts.add(eamArtifact.toString())) {
468 if (flagNotableItemsEnabled) {
469 List<String> caseDisplayNames;
472 if (!caseDisplayNames.isEmpty()) {
473 makeAndPostPreviousNotableArtifact(bbArtifact,
477 LOGGER.log(Level.INFO, String.format(
"Unable to flag notable item: %s.", eamArtifact.toString()), ex);
480 if (flagPreviousItemsEnabled
488 List<CorrelationAttributeInstance> previousOccurences = dbManager.
getArtifactInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue());
489 List<String> caseDisplayNames;
491 if (!instance.getCorrelationCase().getCaseUUID().equals(eamArtifact.getCorrelationCase().getCaseUUID())) {
493 makeAndPostPreviousSeenArtifact(bbArtifact, caseDisplayNames);
498 LOGGER.log(Level.INFO, String.format(
"Unable to flag notable item: %s.", eamArtifact.toString()), ex);
501 if (createCorrelationAttributes) {
502 eamArtifacts.add(eamArtifact);
506 LOGGER.log(Level.SEVERE,
"Error counting notable artifacts.", ex);
510 if (FALSE == eamArtifacts.isEmpty()) {
515 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
static void makeAndPostInterestingArtifact(BlackboardArtifact originalArtifact, Collection< BlackboardAttribute > attributesForNewArtifact)
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()
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()