7895 CR data artifact ingest module

This commit is contained in:
Richard Cordovano 2021-11-01 16:10:23 -04:00
parent 5d600f9475
commit f2f3c98f51
7 changed files with 203 additions and 128 deletions

View File

@ -12,6 +12,7 @@ CentralRepoDbChoice.PostgreSQL.Text=Custom PostgreSQL
CentralRepoDbChoice.PostgreSQL_Multiuser.Text=PostgreSQL using multi-user settings CentralRepoDbChoice.PostgreSQL_Multiuser.Text=PostgreSQL using multi-user settings
CentralRepoDbChoice.Sqlite.Text=SQLite CentralRepoDbChoice.Sqlite.Text=SQLite
CentralRepoDbManager.connectionErrorMsg.text=Failed to connect to central repository database. CentralRepoDbManager.connectionErrorMsg.text=Failed to connect to central repository database.
CentralRepositoryService.progressMsg.startingListener=Starting events listener...
CentralRepositoryService.progressMsg.updatingSchema=Checking for schema updates... CentralRepositoryService.progressMsg.updatingSchema=Checking for schema updates...
CentralRepositoryService.progressMsg.waitingForListeners=Finishing adding data to central repository database.... CentralRepositoryService.progressMsg.waitingForListeners=Finishing adding data to central repository database....
CentralRepositoryService.serviceName=Central Repository Service CentralRepositoryService.serviceName=Central Repository Service

View File

@ -1,7 +1,7 @@
/* /*
* Central Repository * Central Repository
* *
* Copyright 2018-2020 Basis Technology Corp. * Copyright 2018-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -45,7 +45,8 @@ public class CentralRepositoryService implements AutopsyService {
} }
@NbBundle.Messages({ @NbBundle.Messages({
"CentralRepositoryService.progressMsg.updatingSchema=Checking for schema updates..." "CentralRepositoryService.progressMsg.updatingSchema=Checking for schema updates...",
"CentralRepositoryService.progressMsg.startingListener=Starting events listener..."
}) })
@Override @Override
public void openCaseResources(CaseContext context) throws AutopsyServiceException { public void openCaseResources(CaseContext context) throws AutopsyServiceException {
@ -56,15 +57,18 @@ public class CentralRepositoryService implements AutopsyService {
ProgressIndicator progress = context.getProgressIndicator(); ProgressIndicator progress = context.getProgressIndicator();
progress.progress(Bundle.CentralRepositoryService_progressMsg_updatingSchema()); progress.progress(Bundle.CentralRepositoryService_progressMsg_updatingSchema());
updateSchema(); updateSchema();
if (context.cancelRequested()) { if (context.cancelRequested()) {
return; return;
} }
dataUpgradeForVersion1dot2(context.getCase()); dataUpgradeForVersion1dot2(context.getCase());
if (context.cancelRequested()) {
return;
}
progress.progress(Bundle.CentralRepositoryService_progressMsg_startingListener());
caseEventListener = new CaseEventListener(); caseEventListener = new CaseEventListener();
caseEventListener.installListeners(); caseEventListener.startUp();
} }
@NbBundle.Messages({ @NbBundle.Messages({
@ -74,18 +78,16 @@ public class CentralRepositoryService implements AutopsyService {
public void closeCaseResources(CaseContext context) throws AutopsyServiceException { public void closeCaseResources(CaseContext context) throws AutopsyServiceException {
ProgressIndicator progress = context.getProgressIndicator(); ProgressIndicator progress = context.getProgressIndicator();
progress.progress(Bundle.CentralRepositoryService_progressMsg_waitingForListeners()); progress.progress(Bundle.CentralRepositoryService_progressMsg_waitingForListeners());
if (caseEventListener != null) { if (caseEventListener != null) {
caseEventListener.uninstallListeners();
caseEventListener.shutdown(); caseEventListener.shutdown();
} }
} }
/** /**
* Updates the central repository schema to the latest version. * Updates the central repository database schema to the latest version.
* *
* @throws AutopsyServiceException * @throws AutopsyServiceException The exception is thrown if there is an
* error updating the database schema.
*/ */
private void updateSchema() throws AutopsyServiceException { private void updateSchema() throws AutopsyServiceException {
try { try {
@ -97,10 +99,11 @@ public class CentralRepositoryService implements AutopsyService {
/** /**
* Adds missing data source object IDs from data sources in this case to the * Adds missing data source object IDs from data sources in this case to the
* corresponding records in the central repository. This is a data update to * corresponding records in the central repository database. This is a data
* go with the v1.2 schema update. * update to go with the v1.2 schema update.
* *
* @throws AutopsyServiceException * @throws AutopsyServiceException The exception is thrown if there is an
* error updating the database.
*/ */
private void dataUpgradeForVersion1dot2(Case currentCase) throws AutopsyServiceException { private void dataUpgradeForVersion1dot2(Case currentCase) throws AutopsyServiceException {
try { try {

View File

@ -8,11 +8,4 @@ CentralRepositoryNotificationDialog.bulletThree=Create personas that group accou
CentralRepositoryNotificationDialog.bulletTwo=Identify where an item was previously seen CentralRepositoryNotificationDialog.bulletTwo=Identify where an item was previously seen
CentralRepositoryNotificationDialog.finalRemarks=To limit what is stored, use the Central Repository options panel. CentralRepositoryNotificationDialog.finalRemarks=To limit what is stored, use the Central Repository options panel.
CentralRepositoryNotificationDialog.header=Autopsy stores data about each case in its Central Repository. CentralRepositoryNotificationDialog.header=Autopsy stores data about each case in its Central Repository.
IngestEventsListener.ingestmodule.name=Central Repository
IngestEventsListener.prevCaseComment.text=Previous Case:
# {0} - typeName
# {1} - count
IngestEventsListener.prevCount.text=Number of previous {0}: {1}
IngestEventsListener.prevExists.text=Previously Seen Devices (Central Repository)
IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository)
Installer.centralRepoUpgradeFailed.title=Central repository disabled Installer.centralRepoUpgradeFailed.title=Central repository disabled

View File

@ -30,6 +30,7 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
@ -64,7 +65,6 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.Tag;
import org.sleuthkit.autopsy.events.AutopsyEvent; import org.sleuthkit.autopsy.events.AutopsyEvent;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.AnalysisResult;
import org.sleuthkit.datamodel.Blackboard; import org.sleuthkit.datamodel.Blackboard;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
@ -79,16 +79,14 @@ import org.sleuthkit.datamodel.Score;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
/** /**
* Listen for case events and update entries in the Central Repository database * An Autopsy events listener for case events relevant to the central
* accordingly * repository.
*/ */
@Messages({"caseeventlistener.evidencetag=Evidence"}) @Messages({"caseeventlistener.evidencetag=Evidence"})
public final class CaseEventListener implements PropertyChangeListener { public final class CaseEventListener implements PropertyChangeListener {
private static final Logger LOGGER = Logger.getLogger(CaseEventListener.class.getName()); private static final Logger LOGGER = Logger.getLogger(CaseEventListener.class.getName());
private final ExecutorService jobProcessingExecutor; private static final String CASE_EVENT_THREAD_NAME = "CR-Case-Event-Listener-%d";
private static final String CASE_EVENT_THREAD_NAME = "Case-Event-Listener-%d";
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of( private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(
Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED, Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED,
Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED, Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED, Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED,
@ -98,12 +96,72 @@ public final class CaseEventListener implements PropertyChangeListener {
Case.Events.CURRENT_CASE, Case.Events.CURRENT_CASE,
Case.Events.DATA_SOURCE_NAME_CHANGED, Case.Events.DATA_SOURCE_NAME_CHANGED,
Case.Events.OS_ACCT_INSTANCES_ADDED); Case.Events.OS_ACCT_INSTANCES_ADDED);
private static final int MAX_PREV_CASES_FOR_NOTABLE_SCORE = 10;
private static final int MAX_PREV_CASES_FOR_PREV_SEEN = 20;
private static final AtomicBoolean createOSAcctCorrAttrs = new AtomicBoolean();
private static final AtomicBoolean flagPreviouslySeenOSAccts = new AtomicBoolean();
private final ExecutorService jobProcessingExecutor;
/**
* Set whether or not central repository case event listeners should create
* correlation attributes for new OS Accounts.
*
* @param flag True or false.
*/
public static void setCreateOsAcctCorrAttrs(boolean flag) {
createOSAcctCorrAttrs.set(flag);
}
/**
* Gets whether or not central repository case event listeners should create
* correlation attributes for new OS Accounts.
*
* @return flag True or false.
*/
public static boolean createOsAcctCorrAttrs() {
return createOSAcctCorrAttrs.get();
}
/**
* Sets whether or not central repository case event listeners should create
* previously seen analyis results for OS accounts.
*
* @param flag True or false.
*/
public static void setFlagPrevSeenOsAccts(boolean flag) {
flagPreviouslySeenOSAccts.set(flag);
}
/**
* Gets whether or not central repository case event listeners should create
* previously seen analyis results for OS accounts.
*
* @return flag True or false.
*/
public static boolean flagPrevSeenOsAccts() {
return flagPreviouslySeenOSAccts.get();
}
/**
* Contructs an Autopsy events listener for case events relevant to the
* central repository.
*/
public CaseEventListener() { public CaseEventListener() {
jobProcessingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(CASE_EVENT_THREAD_NAME).build()); jobProcessingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(CASE_EVENT_THREAD_NAME).build());
} }
/**
* Starts up the listener.
*/
public void startUp() {
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this);
}
/**
* Shuts down the listener.
*/
public void shutdown() { public void shutdown() {
Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this);
ThreadUtils.shutDownTaskExecutor(jobProcessingExecutor); ThreadUtils.shutDownTaskExecutor(jobProcessingExecutor);
} }
@ -113,92 +171,75 @@ public final class CaseEventListener implements PropertyChangeListener {
return; return;
} }
CentralRepository dbManager; if (!CentralRepository.isEnabled()) {
try {
dbManager = CentralRepository.getInstance();
} catch (CentralRepoException ex) {
LOGGER.log(Level.SEVERE, "Failed to get instance of db manager.", ex);
return; return;
} }
// If any changes are made to which event types are handled the change CentralRepository centralRepo;
// must also be made to CASE_EVENTS_OF_INTEREST. try {
centralRepo = CentralRepository.getInstance();
} catch (CentralRepoException ex) {
LOGGER.log(Level.SEVERE, "Failed to access central repository", ex);
return;
}
/*
* IMPORTANT: If any changes are made to which event types are handled,
* the change must also be made to the contents of the
* CASE_EVENTS_OF_INTEREST set.
*/
switch (Case.Events.valueOf(evt.getPropertyName())) { switch (Case.Events.valueOf(evt.getPropertyName())) {
case CONTENT_TAG_ADDED: case CONTENT_TAG_ADDED:
case CONTENT_TAG_DELETED: { case CONTENT_TAG_DELETED:
jobProcessingExecutor.submit(new ContentTagTask(dbManager, evt)); jobProcessingExecutor.submit(new ContentTagTask(centralRepo, evt));
}
break; break;
case BLACKBOARD_ARTIFACT_TAG_DELETED: case BLACKBOARD_ARTIFACT_TAG_DELETED:
case BLACKBOARD_ARTIFACT_TAG_ADDED: { case BLACKBOARD_ARTIFACT_TAG_ADDED:
jobProcessingExecutor.submit(new BlackboardTagTask(dbManager, evt)); jobProcessingExecutor.submit(new ArtifactTagTask(centralRepo, evt));
}
break; break;
case DATA_SOURCE_ADDED:
case DATA_SOURCE_ADDED: { jobProcessingExecutor.submit(new DataSourceAddedTask(centralRepo, evt));
jobProcessingExecutor.submit(new DataSourceAddedTask(dbManager, evt));
}
break; break;
case TAG_DEFINITION_CHANGED: { case TAG_DEFINITION_CHANGED:
jobProcessingExecutor.submit(new TagDefinitionChangeTask(evt)); jobProcessingExecutor.submit(new TagDefinitionChangeTask(evt));
}
break; break;
case CURRENT_CASE: { case CURRENT_CASE:
jobProcessingExecutor.submit(new CurrentCaseTask(dbManager, evt)); jobProcessingExecutor.submit(new CurrentCaseTask(centralRepo, evt));
}
break; break;
case DATA_SOURCE_NAME_CHANGED: { case DATA_SOURCE_NAME_CHANGED:
jobProcessingExecutor.submit(new DataSourceNameChangedTask(dbManager, evt)); jobProcessingExecutor.submit(new DataSourceNameChangedTask(centralRepo, evt));
}
break; break;
case OS_ACCT_INSTANCES_ADDED: { case OS_ACCT_INSTANCES_ADDED: {
if (((AutopsyEvent) evt).getSourceType() == AutopsyEvent.SourceType.LOCAL) { jobProcessingExecutor.submit(new OsAccountInstancesAddedTask(centralRepo, evt));
jobProcessingExecutor.submit(new OsAccountInstancesAddedTask(dbManager, evt));
}
} }
break; break;
} }
} }
/* /**
* Add all of our Case Event Listeners to the case. * Determines whether or not a tag has notable status.
*
* @param tag The tag.
*
* @return True or false.
*/ */
public void installListeners() { private static boolean isNotableTag(Tag tag) {
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this); return (tag != null && isNotableTagDefinition(tag.getName()));
}
/*
* Remove all of our Case Event Listeners from the case.
*/
public void uninstallListeners() {
Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this);
} }
/** /**
* Returns true if the tag has a notable status. * Determines whether or not a tag definition has notable status.
* *
* @param t The tag to use in determination. * @param tagDef The tag definition.
* *
* @return Whether or not it is a notable tag. * @return True or false.
*/ */
private static boolean isNotableTag(Tag t) { private static boolean isNotableTagDefinition(TagName tagDef) {
return (t != null && isNotableTagName(t.getName())); return (tagDef != null && TagsManager.getNotableTagDisplayNames().contains(tagDef.getDisplayName()));
} }
/** /**
* Returns true if the tag name has a notable status. * Searches a list of tags for a tag with notable status.
*
* @param t The tag name to use in determination.
*
* @return Whether or not it is a notable tag name.
*/
private static boolean isNotableTagName(TagName t) {
return (t != null && TagsManager.getNotableTagDisplayNames().contains(t.getDisplayName()));
}
/**
* Searches a list of tags for a tag with a notable status.
* *
* @param tags The tags to search. * @param tags The tags to search.
* *
@ -208,7 +249,6 @@ public final class CaseEventListener implements PropertyChangeListener {
if (tags == null) { if (tags == null) {
return false; return false;
} }
return tags.stream() return tags.stream()
.filter(CaseEventListener::isNotableTag) .filter(CaseEventListener::isNotableTag)
.findFirst() .findFirst()
@ -216,28 +256,32 @@ public final class CaseEventListener implements PropertyChangeListener {
} }
/** /**
* Sets the known status of a blackboard artifact in the central repository. * Sets the notable (known) status of a central repository correlation
* attribute corresponding to an artifact.
* *
* @param dbManager The central repo database. * @param centralRepo The central repository.
* @param bbArtifact The blackboard artifact to set known status. * @param artifact The artifact.
* @param knownStatus The new known status. * @param knownStatus The new notable status.
*/ */
private static void setArtifactKnownStatus(CentralRepository dbManager, BlackboardArtifact bbArtifact, TskData.FileKnown knownStatus) { private static void setArtifactKnownStatus(CentralRepository centralRepo, BlackboardArtifact artifact, TskData.FileKnown knownStatus) {
List<CorrelationAttributeInstance> convertedArtifacts = new ArrayList<>(); List<CorrelationAttributeInstance> corrAttrInstances = new ArrayList<>();
if (bbArtifact instanceof DataArtifact) { if (artifact instanceof DataArtifact) {
convertedArtifacts.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((DataArtifact) bbArtifact)); corrAttrInstances.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((DataArtifact) artifact));
} else if (bbArtifact instanceof AnalysisResult) { } else if (artifact instanceof AnalysisResult) {
convertedArtifacts.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((AnalysisResult) bbArtifact)); corrAttrInstances.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((AnalysisResult) artifact));
} }
for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) { for (CorrelationAttributeInstance corrAttrInstance : corrAttrInstances) {
try { try {
dbManager.setAttributeInstanceKnownStatus(eamArtifact, knownStatus); centralRepo.setAttributeInstanceKnownStatus(corrAttrInstance, knownStatus);
} catch (CentralRepoException ex) { } catch (CentralRepoException ex) {
LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database while setting artifact known status.", ex); //NON-NLS LOGGER.log(Level.SEVERE, String.format("Error setting correlation attribute instance known status", corrAttrInstance), ex); //NON-NLS
} }
} }
} }
/**
* A task RJCTODO
*/
private final class ContentTagTask implements Runnable { private final class ContentTagTask implements Runnable {
private final CentralRepository dbManager; private final CentralRepository dbManager;
@ -359,12 +403,15 @@ public final class CaseEventListener implements PropertyChangeListener {
} }
} }
private final class BlackboardTagTask implements Runnable { /**
* A task RJCTODO
*/
private final class ArtifactTagTask implements Runnable {
private final CentralRepository dbManager; private final CentralRepository dbManager;
private final PropertyChangeEvent event; private final PropertyChangeEvent event;
private BlackboardTagTask(CentralRepository db, PropertyChangeEvent evt) { private ArtifactTagTask(CentralRepository db, PropertyChangeEvent evt) {
dbManager = db; dbManager = db;
event = evt; event = evt;
} }
@ -478,6 +525,9 @@ public final class CaseEventListener implements PropertyChangeListener {
} }
/**
* A task RJCTODO
*/
private final class TagDefinitionChangeTask implements Runnable { private final class TagDefinitionChangeTask implements Runnable {
private final PropertyChangeEvent event; private final PropertyChangeEvent event;
@ -589,6 +639,9 @@ public final class CaseEventListener implements PropertyChangeListener {
} //TAG_STATUS_CHANGED } //TAG_STATUS_CHANGED
} }
/**
* A task RJCTODO
*/
private final class DataSourceAddedTask implements Runnable { private final class DataSourceAddedTask implements Runnable {
private final CentralRepository dbManager; private final CentralRepository dbManager;
@ -626,6 +679,9 @@ public final class CaseEventListener implements PropertyChangeListener {
} // DATA_SOURCE_ADDED } // DATA_SOURCE_ADDED
} }
/**
* A task RJCTODO
*/
private final class CurrentCaseTask implements Runnable { private final class CurrentCaseTask implements Runnable {
private final CentralRepository dbManager; private final CentralRepository dbManager;
@ -662,13 +718,15 @@ public final class CaseEventListener implements PropertyChangeListener {
} // CURRENT_CASE } // CURRENT_CASE
} }
@NbBundle.Messages({"CaseEventsListener.module.name=Central Repository",
"CaseEventsListener.prevCaseComment.text=Users seen in previous cases",
"CaseEventsListener.prevExists.text=Previously Seen Users (Central Repository)"})
/** /**
* A task RJCTODO
*
* Add OsAccount Instance to CR and find interesting items based on the * Add OsAccount Instance to CR and find interesting items based on the
* OsAccount * OsAccount
*/ */
@NbBundle.Messages({"CaseEventsListener.module.name=Central Repository",
"CaseEventsListener.prevCaseComment.text=Users seen in previous cases",
"CaseEventsListener.prevExists.text=Previously Seen Users (Central Repository)"})
private final class OsAccountInstancesAddedTask implements Runnable { private final class OsAccountInstancesAddedTask implements Runnable {
private final CentralRepository dbManager; private final CentralRepository dbManager;
@ -682,12 +740,9 @@ public final class CaseEventListener implements PropertyChangeListener {
@Override @Override
public void run() { public void run() {
//Nothing to do here if the central repo is not enabled or if ingest is running but is set to not save data/make artifacts if (!createOsAcctCorrAttrs() && !flagPrevSeenOsAccts()) {
if (!CentralRepository.isEnabled()
|| (IngestManager.getInstance().isIngestRunning() && !(IngestEventsListener.isFlagSeenDevices() || IngestEventsListener.shouldCreateCrProperties()))) {
return; return;
} }
final OsAcctInstancesAddedEvent osAcctInstancesAddedEvent = (OsAcctInstancesAddedEvent) event; final OsAcctInstancesAddedEvent osAcctInstancesAddedEvent = (OsAcctInstancesAddedEvent) event;
List<OsAccountInstance> addedOsAccountNew = osAcctInstancesAddedEvent.getOsAccountInstances(); List<OsAccountInstance> addedOsAccountNew = osAcctInstancesAddedEvent.getOsAccountInstances();
for (OsAccountInstance osAccountInstance : addedOsAccountNew) { for (OsAccountInstance osAccountInstance : addedOsAccountNew) {
@ -700,16 +755,13 @@ public final class CaseEventListener implements PropertyChangeListener {
Optional<String> accountAddr = osAccount.getAddr(); Optional<String> accountAddr = osAccount.getAddr();
try { try {
// Save to the database if requested if (createOsAcctCorrAttrs()) {
if (IngestEventsListener.shouldCreateCrProperties()) {
for (CorrelationAttributeInstance correlationAttributeInstance : correlationAttributeInstances) { for (CorrelationAttributeInstance correlationAttributeInstance : correlationAttributeInstances) {
dbManager.addArtifactInstance(correlationAttributeInstance); dbManager.addArtifactInstance(correlationAttributeInstance);
} }
} }
// Look up and create artifacts for previously seen accounts if requested if (flagPrevSeenOsAccts()) {
if (IngestEventsListener.isFlagSeenDevices()) {
CorrelationAttributeInstance instanceWithTypeValue = null; CorrelationAttributeInstance instanceWithTypeValue = null;
for (CorrelationAttributeInstance instance : correlationAttributeInstances) { for (CorrelationAttributeInstance instance : correlationAttributeInstances) {
if (instance.getCorrelationType().getId() == CorrelationAttributeInstance.OSACCOUNT_TYPE_ID) { if (instance.getCorrelationType().getId() == CorrelationAttributeInstance.OSACCOUNT_TYPE_ID) {
@ -732,9 +784,10 @@ public final class CaseEventListener implements PropertyChangeListener {
// calculate score // calculate score
Score score; Score score;
int numCases = caseDisplayNames.size(); int numCases = caseDisplayNames.size();
if (numCases <= IngestEventsListener.MAX_NUM_PREVIOUS_CASES_FOR_LIKELY_NOTABLE_SCORE) { // RJCTODO: Centralize constants (consider)
if (numCases <= MAX_PREV_CASES_FOR_NOTABLE_SCORE) {
score = Score.SCORE_LIKELY_NOTABLE; score = Score.SCORE_LIKELY_NOTABLE;
} else if (numCases > IngestEventsListener.MAX_NUM_PREVIOUS_CASES_FOR_LIKELY_NOTABLE_SCORE && numCases <= IngestEventsListener.MAX_NUM_PREVIOUS_CASES_FOR_PREV_SEEN_ARTIFACT_CREATION) { } else if (numCases > MAX_PREV_CASES_FOR_NOTABLE_SCORE && numCases <= MAX_PREV_CASES_FOR_PREV_SEEN) {
score = Score.SCORE_NONE; score = Score.SCORE_NONE;
} else { } else {
// don't make an Analysis Result, the artifact is too common. // don't make an Analysis Result, the artifact is too common.
@ -769,7 +822,6 @@ public final class CaseEventListener implements PropertyChangeListener {
} }
} }
} }
} catch (CorrelationAttributeNormalizationException ex) { } catch (CorrelationAttributeNormalizationException ex) {
LOGGER.log(Level.SEVERE, "Exception with Correlation Attribute Normalization.", ex); //NON-NLS LOGGER.log(Level.SEVERE, "Exception with Correlation Attribute Normalization.", ex); //NON-NLS
} catch (CentralRepoException ex) { } catch (CentralRepoException ex) {
@ -782,6 +834,9 @@ public final class CaseEventListener implements PropertyChangeListener {
} }
} }
/**
* RJCTODO
*/
private final class DataSourceNameChangedTask implements Runnable { private final class DataSourceNameChangedTask implements Runnable {
private final CentralRepository dbManager; private final CentralRepository dbManager;
@ -815,6 +870,7 @@ public final class CaseEventListener implements PropertyChangeListener {
LOGGER.log(Level.SEVERE, "No open case", ex); LOGGER.log(Level.SEVERE, "No open case", ex);
} }
} }
} // DATA_SOURCE_NAME_CHANGED
} }
} }
}

View File

@ -9,6 +9,13 @@ CentralRepoIngestModule_notable_message_header=<html>A file in this data source
CentralRepoIngestModule_postToBB_knownBadMsg=Notable: {0} CentralRepoIngestModule_postToBB_knownBadMsg=Notable: {0}
CentralRepoIngestModuleFactory.ingestmodule.desc=Saves properties to the central repository for later correlation CentralRepoIngestModuleFactory.ingestmodule.desc=Saves properties to the central repository for later correlation
CentralRepoIngestModuleFactory.ingestmodule.name=Central Repository CentralRepoIngestModuleFactory.ingestmodule.name=Central Repository
# {0} - list of cases
CrDataArtifactIngestModule_notableJustification=Previously marked as notable in cases {0}
CrDataArtifactIngestModule_notableSetName=Previously Tagged As Notable (Central Repository)
# {0} - list of cases
CrDataArtifactIngestModule_prevSeenJustification=Previously seen in cases {0}
CrDataArtifactIngestModule_prevSeenSetName=Previously Seen (Central Repository)
CrDataArtifactIngestModule_prevUnseenJustification=Previously seen in zero cases
IngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings IngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings
IngestSettingsPanel.flagTaggedNotableItemsCheckbox.text=Flag items previously tagged as notable IngestSettingsPanel.flagTaggedNotableItemsCheckbox.text=Flag items previously tagged as notable
IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=Flag devices and users previously seen in other cases IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=Flag devices and users previously seen in other cases

View File

@ -38,6 +38,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNor
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource;
import org.sleuthkit.autopsy.centralrepository.eventlisteners.CaseEventListener;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.DataArtifactIngestModule; import org.sleuthkit.autopsy.ingest.DataArtifactIngestModule;
import org.sleuthkit.autopsy.ingest.IngestJobContext; import org.sleuthkit.autopsy.ingest.IngestJobContext;
@ -112,6 +113,15 @@ public class CentralRepoDataArtifactIngestModule implements DataArtifactIngestMo
} catch (CentralRepoException ex) { } catch (CentralRepoException ex) {
throw new IngestModuleException("Error accessing central repository", ex); throw new IngestModuleException("Error accessing central repository", ex);
} }
/*
* Pass the relevant ingest job settings on to the case events listener
* for the central repository. Note that the listener's dependency on
* these settings currently means that it can only react to new OS
* account instances events when an ingest job with this module enabled
* is running.
*/
CaseEventListener.setCreateOsAcctCorrAttrs(saveCorrelationAttrs);
CaseEventListener.setFlagPrevSeenOsAccts(flagSeenDevices);
} }
@Override @Override
@ -307,7 +317,7 @@ public class CentralRepoDataArtifactIngestModule implements DataArtifactIngestMo
new BlackboardAttribute( new BlackboardAttribute(
TSK_CORRELATION_VALUE, MODULE_NAME, TSK_CORRELATION_VALUE, MODULE_NAME,
corrAttrValue)); corrAttrValue));
makeAndPostAnalysisResult(artifact, BlackboardArtifact.Type.TSK_PREVIOUSLY_UNSEEN, attributesForNewArtifact, "", Score.SCORE_LIKELY_NOTABLE, Bundle.CrDataArtifactIngestModule_prevUnseenJustification); makeAndPostAnalysisResult(artifact, BlackboardArtifact.Type.TSK_PREVIOUSLY_UNSEEN, attributesForNewArtifact, "", Score.SCORE_LIKELY_NOTABLE, Bundle.CrDataArtifactIngestModule_prevUnseenJustification());
} }
/** /**
@ -350,6 +360,15 @@ public class CentralRepoDataArtifactIngestModule implements DataArtifactIngestMo
* job has hash values that match those in the case database. * job has hash values that match those in the case database.
*/ */
syncDataSourceHashes(); syncDataSourceHashes();
/*
* Clear the relevant ingest job settings that were passed on to the
* case events listener for the central repository. Note that the
* listener's dependency on these settings currently means that it can
* only react to new OS account instances events when an ingest job with
* this module enabled is running.
*/
CaseEventListener.setCreateOsAcctCorrAttrs(saveCorrelationAttrs);
CaseEventListener.setFlagPrevSeenOsAccts(flagSeenDevices);
} }
/** /**

View File

@ -190,8 +190,6 @@ final class CentralRepoFileIngestModule implements FileIngestModule {
@Override @Override
public void shutDown() { public void shutDown() {
IngestEventsListener.decrementCorrelationEngineModuleCount();
if ((CentralRepository.isEnabled() == false) || (eamCase == null) || (eamDataSource == null)) { if ((CentralRepository.isEnabled() == false) || (eamCase == null) || (eamDataSource == null)) {
return; return;
} }
@ -227,8 +225,6 @@ final class CentralRepoFileIngestModule implements FileIngestModule {
public void startUp(IngestJobContext context) throws IngestModuleException { public void startUp(IngestJobContext context) throws IngestModuleException {
this.context = context; this.context = context;
IngestEventsListener.incrementCorrelationEngineModuleCount();
if (CentralRepository.isEnabled() == false) { if (CentralRepository.isEnabled() == false) {
/* /*
* Not throwing the customary exception for now. This is a * Not throwing the customary exception for now. This is a