7673 Allow helpers to call correct Blackboard.postArtifacts() API

This commit is contained in:
Richard Cordovano 2021-10-25 14:38:07 -04:00
parent 8e4b86d5e7
commit 97574463ed
7 changed files with 140 additions and 131 deletions

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2019-2020 Basis Technology Corp.
* Copyright 2019-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -24,7 +24,6 @@ import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Account;
import org.sleuthkit.datamodel.Blackboard.BlackboardException;
import org.sleuthkit.datamodel.BlackboardArtifact;
@ -301,7 +300,7 @@ final class XRYCallsFileParser extends AbstractSingleEntityParser {
for (String phone : calleeList) {
try {
currentCase.getCommunicationsManager().createAccountFileInstance(
Account.Type.PHONE, phone, PARSER_NAME, parent);
Account.Type.PHONE, phone, PARSER_NAME, parent, null);
} catch (InvalidAccountIDException ex) {
logger.log(Level.WARNING, String.format("Invalid account identifier %s", phone), ex);
}
@ -314,13 +313,13 @@ final class XRYCallsFileParser extends AbstractSingleEntityParser {
if (!otherAttributes.isEmpty()) {
BlackboardArtifact artifact = parent.newDataArtifact(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG), otherAttributes);
currentCase.getBlackboard().postArtifact(artifact, PARSER_NAME);
currentCase.getBlackboard().postArtifact(artifact, PARSER_NAME, null);
}
} else {
// Otherwise we can safely use the helper.
CommunicationArtifactsHelper helper = new CommunicationArtifactsHelper(
currentCase, PARSER_NAME, parent, Account.Type.PHONE);
currentCase, PARSER_NAME, parent, Account.Type.PHONE, null);
helper.addCalllog(direction, callerId, calleeList, startTime,
endTime, callType, otherAttributes);

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2019-2020 Basis Technology Corp.
* Copyright 2019-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -24,7 +24,6 @@ import java.util.List;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import static org.sleuthkit.autopsy.datasourceprocessors.xry.AbstractSingleEntityParser.PARSER_NAME;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Account;
import org.sleuthkit.datamodel.Blackboard;
import org.sleuthkit.datamodel.BlackboardArtifact;
@ -136,7 +135,7 @@ final class XRYContactsFileParser extends AbstractSingleEntityParser {
// complain about illegal arguments.
if (phoneNumber != null || homePhoneNumber != null || mobilePhoneNumber != null || hasAnEmail) {
CommunicationArtifactsHelper helper = new CommunicationArtifactsHelper(
currentCase, PARSER_NAME, parent, Account.Type.DEVICE);
currentCase, PARSER_NAME, parent, Account.Type.DEVICE, null);
helper.addContact(contactName, phoneNumber, homePhoneNumber,
mobilePhoneNumber, emailAddr, additionalAttributes);
@ -145,7 +144,7 @@ final class XRYContactsFileParser extends AbstractSingleEntityParser {
if (!additionalAttributes.isEmpty()) {
BlackboardArtifact artifact = parent.newDataArtifact(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT), additionalAttributes);
currentCase.getBlackboard().postArtifact(artifact, PARSER_NAME);
currentCase.getBlackboard().postArtifact(artifact, PARSER_NAME, null);
}
}
}

View File

@ -318,7 +318,7 @@ final class XRYMessagesFileParser implements XRYFileParser {
} else {
try {
currentCase.getCommunicationsManager().createAccountFileInstance(
Account.Type.PHONE, pair.getValue(), PARSER_NAME, parent);
Account.Type.PHONE, pair.getValue(), PARSER_NAME, parent, null);
} catch (InvalidAccountIDException ex) {
logger.log(Level.WARNING, String.format("Invalid account identifier %s", pair.getValue()), ex);
}
@ -437,7 +437,7 @@ final class XRYMessagesFileParser implements XRYFileParser {
}
CommunicationArtifactsHelper helper = new CommunicationArtifactsHelper(
currentCase, PARSER_NAME, parent, Account.Type.PHONE);
currentCase, PARSER_NAME, parent, Account.Type.PHONE, null);
helper.addMessage(messageType, direction, senderId, recipientIdsList,
dateTime, readStatus, subject, text, threadId, otherAttributes);

View File

@ -34,6 +34,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
@ -308,32 +309,37 @@ public class IngestManager implements IngestProgressSnapshotProvider {
}
if (!newDataArtifacts.isEmpty()) {
IngestJob ingestJob = null;
Long ingestJobId = tskEvent.getIngestJobId();
if (ingestJobId != null) {
Optional<Long> ingestJobId = tskEvent.getIngestJobId();
if (ingestJobId.isPresent()) {
synchronized (ingestJobsById) {
ingestJob = ingestJobsById.get(ingestJobId);
ingestJob = ingestJobsById.get(ingestJobId.get());
}
} else {
/*
* Cases where the ingest job ID returned by the event will be
* null:
* There are two cases where the ingest job ID returned by the
* event is expected be null:
*
* 1. The artifacts are being posted by a data source proccessor
* (DSP) that runs before the ingest job is created, i.e., a DSP
* that does not support streaming ingest. In this use case, the
* event is handled synchronously before the ingest job is
* (DSP) module that runs before the ingest job is created,
* i.e., a DSP that does not support streaming ingest and has no
* noton of an ingest job ID. In this use case, the event is
* handled synchronously (the DSP calls
* Blackboard.postArtifacts(), which puts the event on the event
* bus to which this method subscribes) before the ingest job is
* created, so the code below will not find an ingest job to
* which to add the artifacts. However, the artifacts will be
* analyzed when the ingest job executor, working in batch mode,
* schedules ingest tasks for all of the data artifacts in the
* case database.
*
* 2. The artifacts were posted by a third party ingest module
* that either has not been updated to use the current
* Blackboard.postartifacts() API, or is using it incorrectly.
* 2. The artifacts were posted by an ingest module that either
* has not been updated to use the current
* Blackboard.postArtifacts() API, or is using it incorrectly.
* In this use case, the code below should be able to find the
* ingest job to which to add the artifacts via their data
* source. However, there is a slight risk here that the wrong
* source.
*
* In both use cases, there is a slight risk that the wrong
* ingest job will be selected if multiple ingests of the same
* data source are in progress.
*/

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2020 Basis Technology Corp.
* Copyright 2020-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -101,7 +101,7 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule {
}
try {
aLeappFileProcessor = new LeappFileProcessor(XMLFILE, ALeappAnalyzerModuleFactory.getModuleName());
aLeappFileProcessor = new LeappFileProcessor(XMLFILE, ALeappAnalyzerModuleFactory.getModuleName(), context);
} catch (IOException | IngestModuleException | NoCurrentCaseException ex) {
throw new IngestModuleException(Bundle.ALeappAnalyzerIngestModule_error_ileapp_file_processor_init(), ex);
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2020 Basis Technology Corp.
* Copyright 2020-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -101,7 +101,7 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
}
try {
iLeappFileProcessor = new LeappFileProcessor(XMLFILE, ILeappAnalyzerModuleFactory.getModuleName());
iLeappFileProcessor = new LeappFileProcessor(XMLFILE, ILeappAnalyzerModuleFactory.getModuleName(), context);
} catch (IOException | IngestModuleException | NoCurrentCaseException ex) {
throw new IngestModuleException(Bundle.ILeappAnalyzerIngestModule_error_ileapp_file_processor_init(), ex);
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2020 Basis Technology Corp.
* Copyright 2020-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -61,6 +61,7 @@ import org.sleuthkit.autopsy.casemodule.services.FileManager;
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException;
import org.sleuthkit.autopsy.ingest.IngestModule.ProcessResult;
import org.sleuthkit.datamodel.AbstractFile;
@ -144,6 +145,7 @@ public final class LeappFileProcessor {
private static final Logger logger = Logger.getLogger(LeappFileProcessor.class.getName());
private final String xmlFile; //NON-NLS
private final String moduleName;
private final IngestJobContext context;
private final Map<String, String> tsvFiles;
private final Map<String, BlackboardArtifact.Type> tsvFileArtifacts;
@ -194,13 +196,14 @@ public final class LeappFileProcessor {
Blackboard blkBoard;
public LeappFileProcessor(String xmlFile, String moduleName) throws IOException, IngestModuleException, NoCurrentCaseException {
public LeappFileProcessor(String xmlFile, String moduleName, IngestJobContext context) throws IOException, IngestModuleException, NoCurrentCaseException {
this.tsvFiles = new HashMap<>();
this.tsvFileArtifacts = new HashMap<>();
this.tsvFileArtifactComments = new HashMap<>();
this.tsvFileAttributes = new HashMap<>();
this.xmlFile = xmlFile;
this.moduleName = moduleName;
this.context = context;
blkBoard = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard();
@ -249,7 +252,7 @@ public final class LeappFileProcessor {
* we know we want to process and return the list to process those files.
*/
private List<String> findTsvFiles(Path LeappOutputDir) throws IngestModuleException {
List<String> allTsvFiles = new ArrayList<>();
List<String> allTsvFiles;
List<String> foundTsvFiles = new ArrayList<>();
try (Stream<Path> walk = Files.walk(LeappOutputDir)) {
@ -407,7 +410,7 @@ public final class LeappFileProcessor {
}
try {
if (ACCOUNT_RELATIONSHIPS.getOrDefault(fileName.toLowerCase(), "norelationship").toLowerCase() == "trackpoint") {
if (ACCOUNT_RELATIONSHIPS.getOrDefault(fileName.toLowerCase(), "norelationship").toLowerCase().equals("trackpoint")) {
(new GeoArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), moduleName, "", geoAbstractFile)).addTrack(trackpointSegmentName, pointList, new ArrayList<>());
}
@ -418,8 +421,7 @@ public final class LeappFileProcessor {
}
@NbBundle.Messages({
"LeappFileProcessor.cannot.create.waypoint.relationship=Cannot create TSK_WAYPOINT artifact.",
})
"LeappFileProcessor.cannot.create.waypoint.relationship=Cannot create TSK_WAYPOINT artifact.",})
private void createRoute(Collection<BlackboardAttribute> bbattributes, Content dataSource, String fileName) throws IngestModuleException {
@ -484,12 +486,10 @@ public final class LeappFileProcessor {
throw new IngestModuleException(Bundle.LeappFileProcessor_cannot_create_waypoint_relationship() + ex.getLocalizedMessage(), ex); //NON-NLS
}
}
@NbBundle.Messages({
"LeappFileProcessor.cannot.create.trackpoint.relationship=Cannot create TSK_TRACK_POINT artifact.",
})
"LeappFileProcessor.cannot.create.trackpoint.relationship=Cannot create TSK_TRACK_POINT artifact.",})
private AbstractFile createTrackpoint(Collection<BlackboardAttribute> bbattributes, Content dataSource, String fileName, String trackpointSegmentName, GeoTrackPoints pointList) throws IngestModuleException {
@ -556,10 +556,8 @@ public final class LeappFileProcessor {
}
@NbBundle.Messages({
"LeappFileProcessor.cannot.create.message.relationship=Cannot create TSK_MESSAGE Relationship.",
})
"LeappFileProcessor.cannot.create.message.relationship=Cannot create TSK_MESSAGE Relationship.",})
private void createMessageRelationship(Collection<BlackboardAttribute> bbattributes, Content dataSource, String fileName) throws IngestModuleException {
@ -662,8 +660,7 @@ public final class LeappFileProcessor {
}
@NbBundle.Messages({
"LeappFileProcessor.cannot.create.contact.relationship=Cannot create TSK_CONTACT Relationship.",
})
"LeappFileProcessor.cannot.create.contact.relationship=Cannot create TSK_CONTACT Relationship.",})
private void createContactRelationship(Collection<BlackboardAttribute> bbattributes, Content dataSource, String fileName) throws IngestModuleException {
String alternateId = null;
@ -732,8 +729,7 @@ public final class LeappFileProcessor {
}
@NbBundle.Messages({
"LeappFileProcessor.cannot.create.calllog.relationship=Cannot create TSK_CALLLOG Relationship.",
})
"LeappFileProcessor.cannot.create.calllog.relationship=Cannot create TSK_CALLLOG Relationship.",})
private void createCalllogRelationship(Collection<BlackboardAttribute> bbattributes, Content dataSource, String fileName) throws IngestModuleException {
@ -886,14 +882,16 @@ public final class LeappFileProcessor {
*
* @param lineValues List of column values.
* @param columnIndexes Mapping of column headers (trimmed; to lower case)
* to column index. All header columns and only all header columns should be
* present.
* @param attrList The list of attributes as specified for the schema of
* this file.
* to column index. All header columns and only all
* header columns should be present.
* @param attrList The list of attributes as specified for the schema
* of this file.
* @param fileName The name of the file being processed.
* @param lineNum The line number in the file.
*
* @return The collection of blackboard attributes for the artifact created
* from this line.
*
* @throws IngestModuleException
*/
private Collection<BlackboardAttribute> processReadLine(List<String> lineValues, Map<String, Integer> columnIndexes,
@ -950,6 +948,7 @@ public final class LeappFileProcessor {
*
* @param colAttr Column Attribute information
* @param value string to be formatted
*
* @return formatted string based on attribute type if no attribute type
* found then return original string
*/
@ -974,6 +973,7 @@ public final class LeappFileProcessor {
* @param value The string value to be converted to the appropriate data
* type for the attribute type.
* @param fileName The file name that the value comes from.
*
* @return The generated blackboard attribute.
*/
private BlackboardAttribute getAttribute(BlackboardAttribute.Type attrType, String value, String fileName) {
@ -1022,7 +1022,9 @@ public final class LeappFileProcessor {
* Handles converting a string value to a blackboard attribute.
*
* @param orig The original string value.
*
* @return The generated blackboard attribute.
*
* @throws ParseException
* @throws NumberFormatException
*/
@ -1037,9 +1039,11 @@ public final class LeappFileProcessor {
* @param attrType The blackboard attribute type.
* @param fileName The name of the file from which the value comes.
* @param blankIsNull If string is blank return null attribute.
* @param zeroIsNull If string is some version of 0, return null attribute.
* @param zeroIsNull If string is some version of 0, return null
* attribute.
* @param valueConverter The means of converting the string value to an
* appropriate blackboard attribute.
*
* @return The generated blackboard attribute or null if not determined.
*/
private BlackboardAttribute parseAttrValue(String value, BlackboardAttribute.Type attrType, String fileName, boolean blankIsNull, boolean zeroIsNull, ParseExceptionFunction valueConverter) {
@ -1213,7 +1217,8 @@ public final class LeappFileProcessor {
* @param dataSource is the Content object that needs to have the artifact
* added for it
* @param bbattributes is the collection of blackboard attributes that need
* to be added to the artifact after the artifact has been created
* to be added to the artifact after the artifact has
* been created
*
* @return The newly-created artifact, or null on error
*/
@ -1246,7 +1251,7 @@ public final class LeappFileProcessor {
}
try {
Case.getCurrentCase().getSleuthkitCase().getBlackboard().postArtifacts(artifacts, moduleName);
Case.getCurrentCase().getSleuthkitCase().getBlackboard().postArtifacts(artifacts, moduleName, context.getJobId());
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, Bundle.LeappFileProcessor_postartifacts_error(), ex); //NON-NLS
}