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;
53 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT;
57 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
58 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT;
59 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME;
69 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT;
76 @NbBundle.Messages({
"IngestEventsListener.ingestmodule.name=Central Repository"})
82 private static final String MODULE_NAME = Bundle.IngestEventsListener_ingestmodule_name();
87 private static final String INGEST_EVENT_THREAD_NAME =
"Ingest-Event-Listener-%d";
91 final Collection<String> recentlyAddedCeArtifacts =
new LinkedHashSet<>();
94 jobProcessingExecutor = Executors.newSingleThreadExecutor(
new ThreadFactoryBuilder().setNameFormat(INGEST_EVENT_THREAD_NAME).build());
122 correlationModuleInstanceCount++;
130 if (getCeModuleInstanceCount() > 0) {
131 correlationModuleInstanceCount--;
139 synchronized static void resetCeModuleInstanceCount() {
140 correlationModuleInstanceCount = 0;
150 return correlationModuleInstanceCount;
159 return flagNotableItems;
168 return flagSeenDevices;
177 return createCrProperties;
186 flagNotableItems = value;
195 flagSeenDevices = value;
204 createCrProperties = value;
212 @NbBundle.Messages({
"IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository)",
213 "IngestEventsListener.prevCaseComment.text=Previous Case: "})
216 Collection<BlackboardAttribute> attributesForNewArtifact = Arrays.asList(
new BlackboardAttribute(
217 TSK_SET_NAME, MODULE_NAME,
218 Bundle.IngestEventsListener_prevTaggedSet_text()),
219 new BlackboardAttribute(
220 TSK_COMMENT, MODULE_NAME,
221 Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(
","))),
222 new BlackboardAttribute(
223 TSK_ASSOCIATED_ARTIFACT, MODULE_NAME,
224 originalArtifact.getArtifactID()));
225 makeAndPostInterestingArtifact(originalArtifact, attributesForNewArtifact);
235 @NbBundle.Messages({
"IngestEventsListener.prevExists.text=Previously Seen Devices (Central Repository)",
238 "IngestEventsListener.prevCount.text=Number of previous {0}: {1}"})
240 Collection<BlackboardAttribute> attributesForNewArtifact = Arrays.asList(
new BlackboardAttribute(
241 TSK_SET_NAME, MODULE_NAME,
242 Bundle.IngestEventsListener_prevExists_text()),
243 new BlackboardAttribute(
244 TSK_COMMENT, MODULE_NAME,
245 Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(
","))),
246 new BlackboardAttribute(
247 TSK_ASSOCIATED_ARTIFACT, MODULE_NAME,
248 originalArtifact.getArtifactID()));
249 makeAndPostInterestingArtifact(originalArtifact, attributesForNewArtifact);
259 SleuthkitCase tskCase = originalArtifact.getSleuthkitCase();
260 AbstractFile abstractFile = tskCase.getAbstractFileById(originalArtifact.getObjectID());
261 Blackboard blackboard = tskCase.getBlackboard();
263 if (!blackboard.artifactExists(abstractFile, TSK_INTERESTING_ARTIFACT_HIT, attributesForNewArtifact)) {
264 BlackboardArtifact newInterestingArtifact = abstractFile.newArtifact(TSK_INTERESTING_ARTIFACT_HIT);
265 newInterestingArtifact.addAttributes(attributesForNewArtifact);
269 blackboard.postArtifact(newInterestingArtifact, MODULE_NAME);
270 }
catch (Blackboard.BlackboardException ex) {
271 LOGGER.log(Level.SEVERE,
"Unable to index blackboard artifact " + newInterestingArtifact.getArtifactID(), ex);
274 }
catch (TskCoreException ex) {
275 LOGGER.log(Level.SEVERE,
"Failed to create BlackboardArtifact.", ex);
276 }
catch (IllegalStateException ex) {
277 LOGGER.log(Level.SEVERE,
"Failed to create BlackboardAttribute.", ex);
293 LOGGER.log(Level.SEVERE,
"Failed to connect to Central Repository database.", ex);
302 jobProcessingExecutor.submit(
new DataAddedTask(dbManager, evt, flagNotable, flagPrevious, createAttributes));
320 LOGGER.log(Level.SEVERE,
"Failed to connect to Central Repository database.", ex);
325 case DATA_SOURCE_ANALYSIS_COMPLETED: {
339 private final PropertyChangeEvent
event;
349 if (getCeModuleInstanceCount() == 0) {
350 recentlyAddedCeArtifacts.clear();
362 String dataSourceName =
"";
363 long dataSourceObjectId = -1;
370 if (!(dataSource instanceof Image)) {
374 dataSourceName = dataSource.getName();
375 dataSourceObjectId = dataSource.getId();
380 if (null == correlationCase) {
381 correlationCase = dbManager.
newCase(openCase);
385 if (correlationDataSource == null) {
390 if (dataSource instanceof Image) {
391 Image image = (Image) dataSource;
393 String imageMd5Hash = image.
getMd5();
394 if (imageMd5Hash == null) {
397 String crMd5Hash = correlationDataSource.
getMd5();
398 if (StringUtils.equals(imageMd5Hash, crMd5Hash) ==
false) {
399 correlationDataSource.
setMd5(imageMd5Hash);
402 String imageSha1Hash = image.getSha1();
403 if (imageSha1Hash == null) {
406 String crSha1Hash = correlationDataSource.
getSha1();
407 if (StringUtils.equals(imageSha1Hash, crSha1Hash) ==
false) {
408 correlationDataSource.
setSha1(imageSha1Hash);
411 String imageSha256Hash = image.getSha256();
412 if (imageSha256Hash == null) {
413 imageSha256Hash =
"";
415 String crSha256Hash = correlationDataSource.
getSha256();
416 if (StringUtils.equals(imageSha256Hash, crSha256Hash) ==
false) {
417 correlationDataSource.
setSha256(imageSha256Hash);
422 LOGGER.log(Level.SEVERE, String.format(
423 "Unable to fetch data from the Central Repository for data source '%s' (obj_id=%d)",
424 dataSourceName, dataSourceObjectId), ex);
426 LOGGER.log(Level.SEVERE,
"No current case opened.", ex);
427 }
catch (TskCoreException ex) {
428 LOGGER.log(Level.SEVERE, String.format(
429 "Unable to fetch data from the case database for data source '%s' (obj_id=%d)",
430 dataSourceName, dataSourceObjectId), ex);
438 private final PropertyChangeEvent
event;
443 private DataAddedTask(
CentralRepository db, PropertyChangeEvent evt,
boolean flagNotableItemsEnabled,
boolean flagPreviousItemsEnabled,
boolean createCorrelationAttributes) {
446 this.flagNotableItemsEnabled = flagNotableItemsEnabled;
447 this.flagPreviousItemsEnabled = flagPreviousItemsEnabled;
448 this.createCorrelationAttributes = createCorrelationAttributes;
457 Collection<BlackboardArtifact> bbArtifacts = mde.
getArtifacts();
458 if (null == bbArtifacts) {
461 List<CorrelationAttributeInstance> eamArtifacts =
new ArrayList<>();
463 for (BlackboardArtifact bbArtifact : bbArtifacts) {
469 if (recentlyAddedCeArtifacts.add(eamArtifact.toString())) {
474 if (flagNotableItemsEnabled) {
475 List<String> caseDisplayNames;
478 if (!caseDisplayNames.isEmpty()) {
479 makeAndPostPreviousNotableArtifact(bbArtifact,
483 LOGGER.log(Level.INFO, String.format(
"Unable to flag notable item: %s.", eamArtifact.toString()), ex);
486 if (flagPreviousItemsEnabled
494 List<CorrelationAttributeInstance> previousOccurences = dbManager.
getArtifactInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue());
495 List<String> caseDisplayNames;
497 if (!instance.getCorrelationCase().getCaseUUID().equals(eamArtifact.getCorrelationCase().getCaseUUID())) {
499 makeAndPostPreviousSeenArtifact(bbArtifact, caseDisplayNames);
504 LOGGER.log(Level.INFO, String.format(
"Unable to flag notable item: %s.", eamArtifact.toString()), ex);
507 if (createCorrelationAttributes) {
508 eamArtifacts.add(eamArtifact);
512 LOGGER.log(Level.SEVERE,
"Error counting notable artifacts.", ex);
516 if (FALSE == eamArtifacts.isEmpty()) {
521 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()