diff --git a/thunderbirdparser/nbproject/project.xml b/thunderbirdparser/nbproject/project.xml
index d4c0a0b53d..411ae5cca9 100644
--- a/thunderbirdparser/nbproject/project.xml
+++ b/thunderbirdparser/nbproject/project.xml
@@ -39,6 +39,15 @@
10.12
+
+ org.sleuthkit.autopsy.corelibs
+
+
+
+ 3
+ 1.2
+
+
org.sleuthkit.autopsy.keywordsearch
diff --git a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java
index b3381cbd09..f4baac77a5 100644
--- a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java
+++ b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java
@@ -28,6 +28,8 @@ import java.util.Set;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
+import org.apache.commons.lang.StringUtils;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
@@ -43,16 +45,19 @@ import org.sleuthkit.autopsy.ingest.IngestModule.ProcessResult;
import org.sleuthkit.autopsy.ingest.IngestMonitor;
import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
-import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Account;
import org.sleuthkit.datamodel.AccountFileInstance;
import org.sleuthkit.datamodel.Blackboard;
import org.sleuthkit.datamodel.BlackboardArtifact;
+import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
+import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
+import org.sleuthkit.datamodel.CommunicationsManager;
import org.sleuthkit.datamodel.DerivedFile;
import org.sleuthkit.datamodel.Relationship;
+import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.TskDataException;
@@ -66,36 +71,39 @@ import org.sleuthkit.datamodel.TskException;
public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
private static final Logger logger = Logger.getLogger(ThunderbirdMboxFileIngestModule.class.getName());
- private IngestServices services = IngestServices.getInstance();
+ private final IngestServices services = IngestServices.getInstance();
private FileManager fileManager;
private IngestJobContext context;
private Blackboard blackboard;
+ private SleuthkitCase sleuthkitCase;
+ private CommunicationsManager communicationsManager;
ThunderbirdMboxFileIngestModule() {
}
@Override
- @Messages({"ThunderbirdMboxFileIngestModule.noOpenCase.errMsg=Exception while getting open case."})
+ @Messages({"ThunderbirdMboxFileIngestModule.noOpenCase.errMsg=Exception while getting open case.",
+ "ThunderbirdMboxFileIngestModule.noCommsManager.errMsg=Exception while getting communications manager."})
public void startUp(IngestJobContext context) throws IngestModuleException {
this.context = context;
try {
- fileManager = Case.getCurrentCaseThrows().getServices().getFileManager();
+ Case currentCaseThrows = Case.getCurrentCaseThrows();
+ fileManager = currentCaseThrows.getServices().getFileManager();
+ sleuthkitCase = currentCaseThrows.getSleuthkitCase();
+ blackboard = sleuthkitCase.getBlackboard();
+ communicationsManager = sleuthkitCase.getCommunicationsManager();
} catch (NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "Exception while getting open case.", ex);
throw new IngestModuleException(Bundle.ThunderbirdMboxFileIngestModule_noOpenCase_errMsg(), ex);
+ } catch (TskCoreException ex) {
+ logger.log(Level.SEVERE, "Exception while getting communications manager.", ex);
+ throw new IngestModuleException(Bundle.ThunderbirdMboxFileIngestModule_noCommsManager_errMsg(), ex);
}
}
@Override
public ProcessResult process(AbstractFile abstractFile) {
- try {
- blackboard = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard();
- } catch (NoCurrentCaseException ex) {
- logger.log(Level.SEVERE, "Exception while getting open case.", ex);
- return ProcessResult.ERROR;
- }
-
// skip known
if (abstractFile.getKnown().equals(TskData.FileKnown.KNOWN)) {
return ProcessResult.OK;
@@ -176,42 +184,44 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
PstParser parser = new PstParser(services);
PstParser.ParseResult result = parser.parse(file, abstractFile.getId());
- if (result == PstParser.ParseResult.OK) {
- try {
- // parse success: Process email and add artifacts
- processEmails(parser.getResults(), abstractFile);
- } catch (NoCurrentCaseException ex) {
- logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
- return ProcessResult.ERROR;
- }
-
- } else if (result == PstParser.ParseResult.ENCRYPT) {
- // encrypted pst: Add encrypted file artifact
- try {
- BlackboardArtifact artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED);
- artifact.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, EmailParserModuleFactory.getModuleName(), NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.encryptionFileLevel")));
-
+ switch (result) {
+ case OK:
try {
- // index the artifact for keyword search
- blackboard.postArtifact(artifact, EmailParserModuleFactory.getModuleName());
- } catch (Blackboard.BlackboardException ex) {
- MessageNotifyUtil.Notify.error(Bundle.ThunderbirdMboxFileIngestModule_processPst_indexError_message(), artifact.getDisplayName());
- logger.log(Level.SEVERE, "Unable to index blackboard artifact " + artifact.getArtifactID(), ex); //NON-NLS
+ // parse success: Process email and add artifacts
+ processEmails(parser.getResults(), abstractFile);
+ } catch (NoCurrentCaseException ex) {
+ logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
+ return ProcessResult.ERROR;
}
+ break;
+ case ENCRYPT:
+ // encrypted pst: Add encrypted file artifact
+ try {
+ BlackboardArtifact artifact = abstractFile.newArtifact(TSK_ENCRYPTION_DETECTED);
+ artifact.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, EmailParserModuleFactory.getModuleName(), NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.encryptionFileLevel")));
- services.fireModuleDataEvent(new ModuleDataEvent(EmailParserModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED));
- } catch (TskCoreException ex) {
- logger.log(Level.INFO, "Failed to add encryption attribute to file: {0}", abstractFile.getName()); //NON-NLS
- }
- } else {
- // parsing error: log message
- postErrorMessage(
- NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.processPst.errProcFile.msg",
- abstractFile.getName()),
- NbBundle.getMessage(this.getClass(),
- "ThunderbirdMboxFileIngestModule.processPst.errProcFile.details"));
- logger.log(Level.INFO, "PSTParser failed to parse {0}", abstractFile.getName()); //NON-NLS
- return ProcessResult.ERROR;
+ try {
+ /* Post the encryption artifact, which will index it and
+ * send out a notification event to the
+ */
+ blackboard.postArtifact(artifact, EmailParserModuleFactory.getModuleName());
+ } catch (Blackboard.BlackboardException ex) {
+ MessageNotifyUtil.Notify.error(Bundle.ThunderbirdMboxFileIngestModule_processPst_indexError_message(), artifact.getDisplayName());
+ logger.log(Level.SEVERE, "Unable to post blackboard artifact " + artifact.getArtifactID(), ex); //NON-NLS
+ }
+ } catch (TskCoreException ex) {
+ logger.log(Level.INFO, "Failed to add encryption attribute to file: {0}", abstractFile.getName()); //NON-NLS
+ }
+ break;
+ default:
+ // parsing error: log message
+ postErrorMessage(
+ NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.processPst.errProcFile.msg",
+ abstractFile.getName()),
+ NbBundle.getMessage(this.getClass(),
+ "ThunderbirdMboxFileIngestModule.processPst.errProcFile.details"));
+ logger.log(Level.INFO, "PSTParser failed to parse {0}", abstractFile.getName()); //NON-NLS
+ return ProcessResult.ERROR;
}
if (file.delete() == false) {
@@ -246,7 +256,7 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
} else if (mboxParentDir.contains("/ImapMail/")) { //NON-NLS
emailFolder = mboxParentDir.substring(mboxParentDir.indexOf("/ImapMail/") + 9); //NON-NLS
}
- emailFolder = emailFolder + mboxFileName;
+ emailFolder += mboxFileName;
emailFolder = emailFolder.replaceAll(".sbd", ""); //NON-NLS
String fileName;
@@ -363,13 +373,10 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
}
}
- if (derivedFiles.isEmpty() == false) {
- for (AbstractFile derived : derivedFiles) {
- services.fireModuleContentEvent(new ModuleContentEvent(derived));
- }
+ if (isNotEmpty(derivedFiles)) {
+ derivedFiles.forEach(derived -> services.fireModuleContentEvent(new ModuleContentEvent(derived)));
}
context.addFilesToJob(derivedFiles);
- services.fireModuleDataEvent(new ModuleDataEvent(EmailParserModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG));
}
/**
@@ -423,7 +430,7 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
Pattern p = Pattern.compile("\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b",
Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(input);
- Set emailAddresses = new HashSet();
+ Set emailAddresses = new HashSet<>();
while (m.find()) {
emailAddresses.add(m.group());
}
@@ -447,43 +454,37 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
String bcc = email.getBcc();
String from = email.getSender();
long dateL = email.getSentDate();
- String headers = email.getHeaders();
- String body = email.getTextBody();
- String bodyHTML = email.getHtmlBody();
- String rtf = email.getRtfBody();
- String subject = email.getSubject();
long id = email.getId();
- String localPath = email.getLocalPath();
List senderAddressList = new ArrayList<>();
- String senderAddress;
+
senderAddressList.addAll(findEmailAddresess(from));
AccountFileInstance senderAccountInstance = null;
- Case openCase = Case.getCurrentCaseThrows();
-
if (senderAddressList.size() == 1) {
- senderAddress = senderAddressList.get(0);
+ String senderAddress = senderAddressList.get(0);
try {
- senderAccountInstance = openCase.getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.EMAIL, senderAddress, EmailParserModuleFactory.getModuleName(), abstractFile);
+ senderAccountInstance = communicationsManager.
+ createAccountFileInstance(Account.Type.EMAIL, senderAddress, EmailParserModuleFactory.getModuleName(), abstractFile);
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Failed to create account for email address " + senderAddress, ex); //NON-NLS
}
} else {
- logger.log(Level.WARNING, "Failed to find sender address, from = " + from); //NON-NLS
+ logger.log(Level.WARNING, "Failed to find sender address, from = {0}", from); //NON-NLS
}
+ //TODO: should this be a set?
List recipientAddresses = new ArrayList<>();
recipientAddresses.addAll(findEmailAddresess(to));
recipientAddresses.addAll(findEmailAddresess(cc));
recipientAddresses.addAll(findEmailAddresess(bcc));
List recipientAccountInstances = new ArrayList<>();
- recipientAddresses.forEach((addr) -> {
+ recipientAddresses.forEach(addr -> {
try {
- AccountFileInstance recipientAccountInstance
- = openCase.getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.EMAIL, addr,
+ AccountFileInstance recipientAccountInstance = communicationsManager
+ .createAccountFileInstance(Account.Type.EMAIL, addr,
EmailParserModuleFactory.getModuleName(), abstractFile);
recipientAccountInstances.add(recipientAccountInstance);
} catch (TskCoreException ex) {
@@ -491,36 +492,35 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
}
});
- addEmailAttribute(headers, ATTRIBUTE_TYPE.TSK_HEADERS, bbattributes);
+ addEmailAttribute(email.getHeaders(), ATTRIBUTE_TYPE.TSK_HEADERS, bbattributes);
addEmailAttribute(from, ATTRIBUTE_TYPE.TSK_EMAIL_FROM, bbattributes);
addEmailAttribute(to, ATTRIBUTE_TYPE.TSK_EMAIL_TO, bbattributes);
- addEmailAttribute(subject, ATTRIBUTE_TYPE.TSK_SUBJECT, bbattributes);
-
+ addEmailAttribute(cc, ATTRIBUTE_TYPE.TSK_EMAIL_CC, bbattributes);
+ addEmailAttribute(email.getSubject(), ATTRIBUTE_TYPE.TSK_SUBJECT, bbattributes);
addEmailAttribute(dateL, ATTRIBUTE_TYPE.TSK_DATETIME_RCVD, bbattributes);
addEmailAttribute(dateL, ATTRIBUTE_TYPE.TSK_DATETIME_SENT, bbattributes);
-
- addEmailAttribute(body, ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN, bbattributes);
+ addEmailAttribute(email.getTextBody(), ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN, bbattributes);
+ addEmailAttribute(email.getHtmlBody(), ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML, bbattributes);
+ addEmailAttribute(email.getRtfBody(), ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF, bbattributes);
addEmailAttribute(((id < 0L) ? NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.notAvail") : String.valueOf(id)),
ATTRIBUTE_TYPE.TSK_MSG_ID, bbattributes);
- addEmailAttribute(((localPath.isEmpty() == false) ? localPath : "/foo/bar"),
+ addEmailAttribute(StringUtils.defaultIfEmpty(email.getLocalPath(), "/foo/bar"), //TODO: really /foo/bar?
ATTRIBUTE_TYPE.TSK_PATH, bbattributes);
- addEmailAttribute(cc, ATTRIBUTE_TYPE.TSK_EMAIL_CC, bbattributes);
- addEmailAttribute(bodyHTML, ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML, bbattributes);
- addEmailAttribute(rtf, ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF, bbattributes);
-
try {
-
- bbart = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG);
+ bbart = abstractFile.newArtifact(TSK_EMAIL_MSG);
bbart.addAttributes(bbattributes);
// Add account relationships
- openCase.getSleuthkitCase().getCommunicationsManager().addRelationships(senderAccountInstance, recipientAccountInstances, bbart, Relationship.Type.MESSAGE, dateL);
+ communicationsManager.addRelationships(senderAccountInstance, recipientAccountInstances, bbart, Relationship.Type.MESSAGE, dateL);
try {
- // index the artifact for keyword search
+ /*
+ * Post the artifact to the blackboard which will index it for
+ * keyword search and send a notification for the UI.
+ */
blackboard.postArtifact(bbart, EmailParserModuleFactory.getModuleName());
} catch (Blackboard.BlackboardException ex) {
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bbart.getArtifactID(), ex); //NON-NLS
@@ -534,7 +534,7 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
}
private void addEmailAttribute(String stringVal, ATTRIBUTE_TYPE attrType, Collection bbattributes) {
- if (stringVal.isEmpty() == false) {
+ if (StringUtils.isNotBlank(stringVal)) {
bbattributes.add(new BlackboardAttribute(attrType, EmailParserModuleFactory.getModuleName(), stringVal));
}
}
@@ -550,10 +550,6 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
services.postMessage(ingestMessage);
}
- IngestServices getServices() {
- return services;
- }
-
@Override
public void shutDown() {
// nothing to shut down