mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 09:17:42 +00:00
7895 CR data artifact ingest module
This commit is contained in:
parent
5d600f9475
commit
f2f3c98f51
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
jobProcessingExecutor.submit(new DataSourceAddedTask(centralRepo, evt));
|
||||||
case DATA_SOURCE_ADDED: {
|
break;
|
||||||
jobProcessingExecutor.submit(new DataSourceAddedTask(dbManager, evt));
|
case TAG_DEFINITION_CHANGED:
|
||||||
}
|
|
||||||
break;
|
|
||||||
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(centralRepo, evt));
|
||||||
jobProcessingExecutor.submit(new CurrentCaseTask(dbManager, evt));
|
break;
|
||||||
}
|
case DATA_SOURCE_NAME_CHANGED:
|
||||||
break;
|
jobProcessingExecutor.submit(new DataSourceNameChangedTask(centralRepo, evt));
|
||||||
case DATA_SOURCE_NAME_CHANGED: {
|
break;
|
||||||
jobProcessingExecutor.submit(new DataSourceNameChangedTask(dbManager, evt));
|
|
||||||
}
|
|
||||||
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
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user