custom attr cache

This commit is contained in:
Greg DiCristofaro 2022-01-24 20:17:12 -05:00
parent dcc6674c44
commit 23eb75b12b
2 changed files with 64 additions and 43 deletions

View File

@ -30,6 +30,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -82,6 +83,9 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
private IngestJobContext context; private IngestJobContext context;
private Blackboard blackboard; private Blackboard blackboard;
private CommunicationArtifactsHelper communicationArtifactsHelper; private CommunicationArtifactsHelper communicationArtifactsHelper;
// A cache of custom attributes for the VcardParser unique to each ingest run.
private Map<String, BlackboardAttribute.Type> customAttributeCache;
private static final int MBOX_SIZE_TO_SPLIT = 1048576000; private static final int MBOX_SIZE_TO_SPLIT = 1048576000;
private Case currentCase; private Case currentCase;
@ -96,6 +100,7 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
@Messages({"ThunderbirdMboxFileIngestModule.noOpenCase.errMsg=Exception while getting open case."}) @Messages({"ThunderbirdMboxFileIngestModule.noOpenCase.errMsg=Exception while getting open case."})
public void startUp(IngestJobContext context) throws IngestModuleException { public void startUp(IngestJobContext context) throws IngestModuleException {
this.context = context; this.context = context;
this.customAttributeCache = new ConcurrentHashMap<>();
try { try {
currentCase = Case.getCurrentCaseThrows(); currentCase = Case.getCurrentCaseThrows();
fileManager = Case.getCurrentCaseThrows().getServices().getFileManager(); fileManager = Case.getCurrentCaseThrows().getServices().getFileManager();
@ -441,7 +446,7 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
}) })
private ProcessResult processVcard(AbstractFile abstractFile) { private ProcessResult processVcard(AbstractFile abstractFile) {
try { try {
VcardParser parser = new VcardParser(currentCase, context); VcardParser parser = new VcardParser(currentCase, context, customAttributeCache);
parser.parse(abstractFile); parser.parse(abstractFile);
} catch (IOException | NoCurrentCaseException ex) { } catch (IOException | NoCurrentCaseException ex) {
logger.log(Level.WARNING, String.format("Exception while parsing the file '%s' (id=%d).", abstractFile.getName(), abstractFile.getId()), ex); //NON-NLS logger.log(Level.WARNING, String.format("Exception while parsing the file '%s' (id=%d).", abstractFile.getName(), abstractFile.getId()), ex); //NON-NLS

View File

@ -98,16 +98,22 @@ final class VcardParser {
private final Blackboard blackboard; private final Blackboard blackboard;
private final Case currentCase; private final Case currentCase;
private final SleuthkitCase tskCase; private final SleuthkitCase tskCase;
/**
* A custom attribute cache provided to every VcardParser from the
* ThunderbirdMboxFileIngestModule, but unique to one ingest run.
*/
private final Map<String, BlackboardAttribute.Type> customAttributeCache;
/** /**
* Create a VcardParser object. * Create a VcardParser object.
*/ */
VcardParser(Case currentCase, IngestJobContext context) { VcardParser(Case currentCase, IngestJobContext context, Map<String, BlackboardAttribute.Type> customAttributeCache) {
this.context = context; this.context = context;
this.currentCase = currentCase; this.currentCase = currentCase;
tskCase = currentCase.getSleuthkitCase(); tskCase = currentCase.getSleuthkitCase();
blackboard = tskCase.getBlackboard(); blackboard = tskCase.getBlackboard();
fileManager = currentCase.getServices().getFileManager(); fileManager = currentCase.getServices().getFileManager();
this.customAttributeCache = customAttributeCache;
} }
/** /**
@ -421,26 +427,29 @@ final class VcardParser {
if (splitType != null && !splitType.isEmpty()) { if (splitType != null && !splitType.isEmpty()) {
attributeTypeName = "TSK_PHONE_NUMBER_" + splitType; attributeTypeName = "TSK_PHONE_NUMBER_" + splitType;
} }
final String finalAttrTypeName = attributeTypeName;
try { // handled in computeIfAbsent to remove concurrency issues when adding to this concurrent hashmap.
BlackboardAttribute.Type attributeType = tskCase.getBlackboard().getAttributeType(attributeTypeName); BlackboardAttribute.Type attributeType
if (attributeType == null) { = this.customAttributeCache.computeIfAbsent(finalAttrTypeName, k -> {
try{ try {
// Add this attribute type to the case database. // Add this attribute type to the case database.
attributeType = tskCase.getBlackboard().getOrAddAttributeType(attributeTypeName, return tskCase.getBlackboard().getOrAddAttributeType(finalAttrTypeName,
BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING, BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
String.format("Phone Number (%s)", StringUtils.capitalize(splitType.toLowerCase()))); String.format("Phone Number (%s)", StringUtils.capitalize(splitType.toLowerCase())));
ThunderbirdMboxFileIngestModule.addArtifactAttribute(telephoneText, attributeType, attributes); } catch (BlackboardException ex) {
}catch (BlackboardException ex) { VcardParser.logger.log(Level.WARNING, String.format("Unable to retrieve attribute type '%s' for file '%s' (id=%d).",
logger.log(Level.WARNING, String.format("Unable to retrieve attribute type '%s' for file '%s' (id=%d).", attributeTypeName, abstractFile.getName(), abstractFile.getId()), ex); finalAttrTypeName, abstractFile.getName(), abstractFile.getId()), ex);
} return null;
} }
});
} catch (TskCoreException ex) {
logger.log(Level.WARNING, String.format("Unable to retrieve attribute type '%s' for file '%s' (id=%d).", attributeTypeName, abstractFile.getName(), abstractFile.getId()), ex); if (attributeType != null) {
ThunderbirdMboxFileIngestModule.addArtifactAttribute(telephoneText, attributeType, attributes);
} }
} }
} }
} }
@ -469,30 +478,37 @@ final class VcardParser {
* ez-vcard. Therefore, we must read them manually * ez-vcard. Therefore, we must read them manually
* ourselves. * ourselves.
*/ */
List<String> splitEmailTypes = Arrays.asList( List<String> splitEmailTypes = Arrays.asList(
type.getValue().toUpperCase().replaceAll("\\s+","").split(",")); type.getValue().toUpperCase().replaceAll("\\s+", "").split(","));
if (splitEmailTypes.size() > 0) { if (splitEmailTypes.size() > 0) {
String splitType = splitEmailTypes.get(0); String splitType = splitEmailTypes.get(0);
String attributeTypeName = "TSK_EMAIL_" + splitType; String attributeTypeName = "TSK_EMAIL_" + splitType;
if(splitType.isEmpty()) { if (splitType.isEmpty()) {
attributeTypeName = "TSK_EMAIL"; attributeTypeName = "TSK_EMAIL";
} }
try {
BlackboardAttribute.Type attributeType = tskCase.getBlackboard().getAttributeType(attributeTypeName); final String finalAttributeTypeName = attributeTypeName;
if (attributeType == null) {
// Add this attribute type to the case database. BlackboardAttribute.Type attributeType
attributeType = tskCase.getBlackboard().getOrAddAttributeType(attributeTypeName, = this.customAttributeCache.computeIfAbsent(finalAttributeTypeName, k -> {
BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING, try {
String.format("Email (%s)", StringUtils.capitalize(splitType.toLowerCase()))); // Add this attribute type to the case database.
} return tskCase.getBlackboard().getOrAddAttributeType(finalAttributeTypeName,
ThunderbirdMboxFileIngestModule.addArtifactAttribute(email.getValue(), attributeType, attributes); BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
} catch (TskCoreException ex) { String.format("Email (%s)", StringUtils.capitalize(splitType.toLowerCase())));
logger.log(Level.SEVERE, String.format("Unable to retrieve attribute type '%s' for file '%s' (id=%d).", attributeTypeName, abstractFile.getName(), abstractFile.getId()), ex); } catch (BlackboardException ex) {
} catch (BlackboardException ex) { logger.log(Level.SEVERE, String.format("Unable to add custom attribute type '%s' for file '%s' (id=%d).",
logger.log(Level.SEVERE, String.format("Unable to add custom attribute type '%s' for file '%s' (id=%d).", attributeTypeName, abstractFile.getName(), abstractFile.getId()), ex); finalAttributeTypeName, abstractFile.getName(), abstractFile.getId()), ex);
} }
}
return null;
});
if (attributeType != null) {
ThunderbirdMboxFileIngestModule.addArtifactAttribute(email.getValue(), attributeType, attributes);
}
}
} }
} }