Autopsy  4.13.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ThunderbirdMboxFileIngestModule.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2019 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.thunderbirdparser;
20 
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashSet;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Set;
30 import java.util.logging.Level;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33 import org.apache.james.mime4j.MimeException;
34 import org.openide.util.NbBundle;
35 import org.openide.util.NbBundle.Messages;
49 import org.sleuthkit.datamodel.AbstractFile;
50 import org.sleuthkit.datamodel.Account;
51 import org.sleuthkit.datamodel.AccountFileInstance;
52 import org.sleuthkit.datamodel.Blackboard;
53 import org.sleuthkit.datamodel.BlackboardArtifact;
54 import org.sleuthkit.datamodel.BlackboardAttribute;
55 import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
56 import org.sleuthkit.datamodel.DerivedFile;
57 import org.sleuthkit.datamodel.Relationship;
58 import org.sleuthkit.datamodel.TskCoreException;
59 import org.sleuthkit.datamodel.TskData;
60 import org.sleuthkit.datamodel.TskDataException;
61 import org.sleuthkit.datamodel.TskException;
62 import org.sleuthkit.datamodel.blackboardutils.CommunicationArtifactsHelper;
63 import org.sleuthkit.datamodel.blackboardutils.FileAttachment;
64 import org.sleuthkit.datamodel.blackboardutils.MessageAttachments;
65 
71 public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
72  private static final Logger logger = Logger.getLogger(ThunderbirdMboxFileIngestModule.class.getName());
76  private Blackboard blackboard;
77  private CommunicationArtifactsHelper communicationArtifactsHelper;
78 
79  private Case currentCase;
80 
85  }
86 
87  @Override
88  @Messages ({"ThunderbirdMboxFileIngestModule.noOpenCase.errMsg=Exception while getting open case."})
89  public void startUp(IngestJobContext context) throws IngestModuleException {
90  this.context = context;
91  try {
92  currentCase = Case.getCurrentCaseThrows();
94  } catch (NoCurrentCaseException ex) {
95  logger.log(Level.SEVERE, "Exception while getting open case.", ex);
96  throw new IngestModuleException(Bundle.ThunderbirdMboxFileIngestModule_noOpenCase_errMsg(), ex);
97  }
98  }
99 
100  @Override
101  public ProcessResult process(AbstractFile abstractFile) {
102 
103  blackboard = currentCase.getSleuthkitCase().getBlackboard();
104 
105  // skip known
106  if (abstractFile.getKnown().equals(TskData.FileKnown.KNOWN)) {
107  return ProcessResult.OK;
108  }
109 
110  //skip unalloc
111  if ((abstractFile.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)) ||
112  (abstractFile.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.SLACK))) {
113  return ProcessResult.OK;
114  }
115 
116  if ((abstractFile.isFile() == false)) {
117  return ProcessResult.OK;
118  }
119 
120  // check its signature
121  boolean isMbox = false;
122  boolean isEMLFile = false;
123 
124  try {
125  byte[] t = new byte[64];
126  if (abstractFile.getSize() > 64) {
127  int byteRead = abstractFile.read(t, 0, 64);
128  if (byteRead > 0) {
129  isMbox = MboxParser.isValidMimeTypeMbox(t);
130  isEMLFile = EMLParser.isEMLFile(abstractFile, t);
131  }
132  }
133  } catch (TskException ex) {
134  logger.log(Level.WARNING, null, ex);
135  }
136 
137  boolean isPstFile = PstParser.isPstFile(abstractFile);
138  boolean isVcardFile = VcardParser.isVcardFile(abstractFile);
139 
140  if (isMbox || isEMLFile || isPstFile || isVcardFile ) {
141  try {
142  communicationArtifactsHelper = new CommunicationArtifactsHelper(currentCase.getSleuthkitCase(),
143  EmailParserModuleFactory.getModuleName(), abstractFile, Account.Type.EMAIL);
144  } catch (TskCoreException ex) {
145  logger.log(Level.SEVERE, String.format("Failed to create CommunicationArtifactsHelper for file with object id = %d", abstractFile.getId()), ex);
146  return ProcessResult.ERROR;
147  }
148  }
149 
150  if (isMbox) {
151  return processMBox(abstractFile);
152  }
153 
154  if (isEMLFile) {
155  return processEMLFile(abstractFile);
156  }
157 
158  if (isPstFile) {
159  return processPst(abstractFile);
160  }
161 
162  if (isVcardFile) {
163  return processVcard(abstractFile);
164  }
165 
166  return ProcessResult.OK;
167  }
168 
176  @Messages({"ThunderbirdMboxFileIngestModule.processPst.indexError.message=Failed to index encryption detected artifact for keyword search."})
177  private ProcessResult processPst(AbstractFile abstractFile) {
178  String fileName;
179  try {
180  fileName = getTempPath() + File.separator + abstractFile.getName()
181  + "-" + String.valueOf(abstractFile.getId());
182  } catch (NoCurrentCaseException ex) {
183  logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
184  return ProcessResult.ERROR;
185  }
186  File file = new File(fileName);
187 
188  long freeSpace = services.getFreeDiskSpace();
189  if ((freeSpace != IngestMonitor.DISK_FREE_SPACE_UNKNOWN) && (abstractFile.getSize() >= freeSpace)) {
190  logger.log(Level.WARNING, "Not enough disk space to write file to disk."); //NON-NLS
192  NbBundle.getMessage(this.getClass(),
193  "ThunderbirdMboxFileIngestModule.processPst.errMsg.outOfDiskSpace",
194  abstractFile.getName()));
195  services.postMessage(msg);
196  return ProcessResult.OK;
197  }
198 
199  try {
200  ContentUtils.writeToFile(abstractFile, file, context::fileIngestIsCancelled);
201  } catch (IOException ex) {
202  logger.log(Level.WARNING, "Failed writing pst file to disk.", ex); //NON-NLS
203  return ProcessResult.OK;
204  }
205 
206  PstParser parser = new PstParser(services);
207  PstParser.ParseResult result = parser.open(file, abstractFile.getId());
208 
209  switch( result) {
210  case OK:
211  Iterator<EmailMessage> pstMsgIterator = parser.getEmailMessageIterator();
212  if (pstMsgIterator != null) {
213  processEmails(parser.getPartialEmailMessages(), pstMsgIterator , abstractFile);
214  } else {
215  // sometimes parser returns ParseResult=OK but there are no messages
216  postErrorMessage(
217  NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.processPst.errProcFile.msg",
218  abstractFile.getName()),
219  NbBundle.getMessage(this.getClass(),
220  "ThunderbirdMboxFileIngestModule.processPst.errProcFile.details"));
221  logger.log(Level.INFO, "PSTParser failed to parse {0}", abstractFile.getName()); //NON-NLS
222  // delete the temp file
223  if (file.delete() == false) {
224  logger.log(Level.INFO, "Failed to delete temp file: {0}", file.getName()); //NON-NLS
225  }
226  return ProcessResult.ERROR;
227  }
228  break;
229 
230  case ENCRYPT:
231  // encrypted pst: Add encrypted file artifact
232  try {
233 
234  BlackboardArtifact artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED);
235  artifact.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, EmailParserModuleFactory.getModuleName(), NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.encryptionFileLevel")));
236 
237  try {
238  // index the artifact for keyword search
239  blackboard.postArtifact(artifact, EmailParserModuleFactory.getModuleName());
240  } catch (Blackboard.BlackboardException ex) {
241  MessageNotifyUtil.Notify.error(Bundle.ThunderbirdMboxFileIngestModule_processPst_indexError_message(), artifact.getDisplayName());
242  logger.log(Level.SEVERE, "Unable to index blackboard artifact " + artifact.getArtifactID(), ex); //NON-NLS
243  }
244  } catch (TskCoreException ex) {
245  logger.log(Level.INFO, "Failed to add encryption attribute to file: {0}", abstractFile.getName()); //NON-NLS
246  }
247  break;
248  default:
249  // parsing error: log message
250  postErrorMessage(
251  NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.processPst.errProcFile.msg",
252  abstractFile.getName()),
253  NbBundle.getMessage(this.getClass(),
254  "ThunderbirdMboxFileIngestModule.processPst.errProcFile.details"));
255  logger.log(Level.INFO, "PSTParser failed to parse {0}", abstractFile.getName()); //NON-NLS
256  // delete the temp file
257  if (file.delete() == false) {
258  logger.log(Level.INFO, "Failed to delete temp file: {0}", file.getName()); //NON-NLS
259  }
260  return ProcessResult.ERROR;
261  }
262 
263  if (file.delete() == false) {
264  logger.log(Level.INFO, "Failed to delete temp file: {0}", file.getName()); //NON-NLS
265  }
266 
267  return ProcessResult.OK;
268  }
269 
277  private ProcessResult processMBox(AbstractFile abstractFile) {
278  String mboxFileName = abstractFile.getName();
279  String mboxParentDir = abstractFile.getParentPath();
280  // use the local path to determine the e-mail folder structure
281  String emailFolder = "";
282  // email folder is everything after "Mail" or ImapMail
283  if (mboxParentDir.contains("/Mail/")) { //NON-NLS
284  emailFolder = mboxParentDir.substring(mboxParentDir.indexOf("/Mail/") + 5); //NON-NLS
285  } else if (mboxParentDir.contains("/ImapMail/")) { //NON-NLS
286  emailFolder = mboxParentDir.substring(mboxParentDir.indexOf("/ImapMail/") + 9); //NON-NLS
287  }
288  emailFolder += mboxFileName;
289  emailFolder = emailFolder.replaceAll(".sbd", ""); //NON-NLS
290 
291  String fileName;
292  try {
293  fileName = getTempPath() + File.separator + abstractFile.getName()
294  + "-" + String.valueOf(abstractFile.getId());
295  } catch (NoCurrentCaseException ex) {
296  logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
297  return ProcessResult.ERROR;
298  }
299  File file = new File(fileName);
300 
301  long freeSpace = services.getFreeDiskSpace();
302  if ((freeSpace != IngestMonitor.DISK_FREE_SPACE_UNKNOWN) && (abstractFile.getSize() >= freeSpace)) {
303  logger.log(Level.WARNING, "Not enough disk space to write file to disk."); //NON-NLS
304  postErrorMessage(
305  NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.processMBox.errProcFile.msg",
306  abstractFile.getName()),
307  NbBundle.getMessage(this.getClass(),
308  "ThunderbirdMboxFileIngestModule.processMBox.errProfFile.details"));
309  return ProcessResult.OK;
310  }
311 
312  try {
313  ContentUtils.writeToFile(abstractFile, file, context::fileIngestIsCancelled);
314  } catch (IOException ex) {
315  logger.log(Level.WARNING, "Failed writing mbox file to disk.", ex); //NON-NLS
316  return ProcessResult.OK;
317  }
318 
319  MboxParser emailIterator = MboxParser.getEmailIterator( emailFolder, file, abstractFile.getId());
320  List<EmailMessage> emails = new ArrayList<>();
321  if(emailIterator != null) {
322  while(emailIterator.hasNext()) {
323  EmailMessage emailMessage = emailIterator.next();
324  if(emailMessage != null) {
325  emails.add(emailMessage);
326  }
327  }
328 
329  String errors = emailIterator.getErrors();
330  if (!errors.isEmpty()) {
331  postErrorMessage(
332  NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.processMBox.errProcFile.msg2",
333  abstractFile.getName()), errors);
334  }
335  }
336  processEmails(emails, MboxParser.getEmailIterator( emailFolder, file, abstractFile.getId()), abstractFile);
337 
338  if (file.delete() == false) {
339  logger.log(Level.INFO, "Failed to delete temp file: {0}", file.getName()); //NON-NLS
340  }
341 
342  return ProcessResult.OK;
343  }
344 
353  @Messages({
354  "# {0} - file name",
355  "# {1} - file ID",
356  "ThunderbirdMboxFileIngestModule.errorMessage.outOfDiskSpace=Out of disk space. Cannot copy '{0}' (id={1}) to parse."
357  })
358  private ProcessResult processVcard(AbstractFile abstractFile) {
359  try {
360  VcardParser parser = new VcardParser(currentCase, context);
361  parser.parse(abstractFile);
362  } catch (IOException | NoCurrentCaseException ex) {
363  logger.log(Level.WARNING, String.format("Exception while parsing the file '%s' (id=%d).", abstractFile.getName(), abstractFile.getId()), ex); //NON-NLS
364  return ProcessResult.OK;
365  }
366  return ProcessResult.OK;
367  }
368 
369  private ProcessResult processEMLFile(AbstractFile abstractFile) {
370  try {
371  EmailMessage message = EMLParser.parse(abstractFile);
372 
373  if (message == null) {
374  return ProcessResult.OK;
375  }
376 
377  List<AbstractFile> derivedFiles = new ArrayList<>();
378 
379  BlackboardArtifact msgArtifact = addEmailArtifact(message, abstractFile);
380 
381  if ((msgArtifact != null) && (message.hasAttachment())) {
382  derivedFiles.addAll(handleAttachments(message.getAttachments(), abstractFile, msgArtifact));
383  }
384 
385  if (derivedFiles.isEmpty() == false) {
386  for (AbstractFile derived : derivedFiles) {
387  services.fireModuleContentEvent(new ModuleContentEvent(derived));
388  }
389  }
390  context.addFilesToJob(derivedFiles);
391 
392  } catch (IOException ex) {
393  logger.log(Level.WARNING, String.format("Error reading eml file %s", abstractFile.getName()), ex);
394  return ProcessResult.ERROR;
395  } catch (MimeException ex) {
396  logger.log(Level.WARNING, String.format("Error reading eml file %s", abstractFile.getName()), ex);
397  return ProcessResult.ERROR;
398  }
399 
400  return ProcessResult.OK;
401  }
402 
409  static String getTempPath() throws NoCurrentCaseException {
410  String tmpDir = Case.getCurrentCaseThrows().getTempDirectory() + File.separator
411  + "EmailParser"; //NON-NLS
412  File dir = new File(tmpDir);
413  if (dir.exists() == false) {
414  dir.mkdirs();
415  }
416  return tmpDir;
417  }
418 
426  static String getModuleOutputPath() throws NoCurrentCaseException {
427  String outDir = Case.getCurrentCaseThrows().getModuleDirectory() + File.separator
428  + EmailParserModuleFactory.getModuleName();
429  File dir = new File(outDir);
430  if (dir.exists() == false) {
431  dir.mkdirs();
432  }
433  return outDir;
434  }
435 
442  static String getRelModuleOutputPath() throws NoCurrentCaseException {
443  return Case.getCurrentCaseThrows().getModuleOutputDirectoryRelativePath() + File.separator
444  + EmailParserModuleFactory.getModuleName();
445  }
446 
455  private void processEmails(List<EmailMessage> partialEmailsForThreading, Iterator<EmailMessage> fullMessageIterator, AbstractFile abstractFile) {
456 
457  // Putting try/catch around this to catch any exception and still allow
458  // the creation of the artifacts to continue.
459  try{
460  EmailMessageThreader.threadMessages(partialEmailsForThreading);
461  } catch(Exception ex) {
462  logger.log(Level.WARNING, String.format("Exception thrown parsing emails from %s", abstractFile.getName()), ex);
463  }
464 
465  List<AbstractFile> derivedFiles = new ArrayList<>();
466 
467  int msgCnt = 0;
468  while(fullMessageIterator.hasNext()) {
469  EmailMessage current = fullMessageIterator.next();
470 
471  if(current == null) {
472  continue;
473  }
474 
475  if(partialEmailsForThreading.size() > msgCnt) {
476  EmailMessage threaded = partialEmailsForThreading.get(msgCnt++);
477 
478  if(threaded.getMessageID().equals(current.getMessageID()) &&
479  threaded.getSubject().equals(current.getSubject())) {
480  current.setMessageThreadID(threaded.getMessageThreadID());
481  }
482  }
483 
484  BlackboardArtifact msgArtifact = addEmailArtifact(current, abstractFile);
485 
486  if ((msgArtifact != null) && (current.hasAttachment())) {
487  derivedFiles.addAll(handleAttachments(current.getAttachments(), abstractFile, msgArtifact ));
488  }
489  }
490 
491  if (derivedFiles.isEmpty() == false) {
492  for (AbstractFile derived : derivedFiles) {
493  services.fireModuleContentEvent(new ModuleContentEvent(derived));
494  }
495  }
496  context.addFilesToJob(derivedFiles);
497  }
508  @NbBundle.Messages({
509  "ThunderbirdMboxFileIngestModule.handleAttch.addAttachmentsErrorMsg=Failed to add attachments to email message."
510 })
511  private List<AbstractFile> handleAttachments(List<EmailMessage.Attachment> attachments, AbstractFile abstractFile, BlackboardArtifact messageArtifact) {
512  List<AbstractFile> files = new ArrayList<>();
513  List<FileAttachment> fileAttachments = new ArrayList<>();
514  for (EmailMessage.Attachment attach : attachments) {
515  String filename = attach.getName();
516  long crTime = attach.getCrTime();
517  long mTime = attach.getmTime();
518  long aTime = attach.getaTime();
519  long cTime = attach.getcTime();
520  String relPath = attach.getLocalPath();
521  long size = attach.getSize();
522  TskData.EncodingType encodingType = attach.getEncodingType();
523 
524  try {
525  DerivedFile df = fileManager.addDerivedFile(filename, relPath,
526  size, cTime, crTime, aTime, mTime, true, abstractFile, "",
527  EmailParserModuleFactory.getModuleName(), EmailParserModuleFactory.getModuleVersion(), "", encodingType);
528 
529  associateAttachmentWithMesssge(messageArtifact, df);
530 
531  files.add(df);
532 
533  fileAttachments.add(new FileAttachment(df));
534  } catch (TskCoreException ex) {
535  postErrorMessage(
536  NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.handleAttch.errMsg",
537  abstractFile.getName()),
538  NbBundle.getMessage(this.getClass(),
539  "ThunderbirdMboxFileIngestModule.handleAttch.errMsg.details", filename));
540  logger.log(Level.INFO, "", ex);
541  }
542  }
543 
544 
545  try {
546  communicationArtifactsHelper.addAttachments(messageArtifact, new MessageAttachments(fileAttachments, Collections.emptyList()));
547  } catch (TskCoreException ex) {
548  postErrorMessage(
549  NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.handleAttch.addAttachmentsErrorMsg"),
550  "");
551  logger.log(Level.INFO, "Failed to add attachments to email message.", ex);
552  }
553 
554  return files;
555  }
556 
561  private BlackboardArtifact associateAttachmentWithMesssge(BlackboardArtifact message, AbstractFile attachedFile) throws TskCoreException {
562  Collection<BlackboardAttribute> attributes = new ArrayList<>();
563  attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, EmailParserModuleFactory.getModuleName(), message.getArtifactID()));
564 
565  BlackboardArtifact bba = attachedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
566  bba.addAttributes(attributes); //write out to bb
567  return bba;
568  }
569 
577  private Set<String> findEmailAddresess(String input) {
578  Pattern p = Pattern.compile("\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b",
579  Pattern.CASE_INSENSITIVE);
580  Matcher m = p.matcher(input);
581  Set<String> emailAddresses = new HashSet<>();
582  while (m.find()) {
583  emailAddresses.add( m.group());
584  }
585  return emailAddresses;
586  }
587 
596  @Messages({"ThunderbirdMboxFileIngestModule.addArtifact.indexError.message=Failed to index email message detected artifact for keyword search."})
597  private BlackboardArtifact addEmailArtifact(EmailMessage email, AbstractFile abstractFile) {
598  BlackboardArtifact bbart = null;
599  List<BlackboardAttribute> bbattributes = new ArrayList<>();
600  String to = email.getRecipients();
601  String cc = email.getCc();
602  String bcc = email.getBcc();
603  String from = email.getSender();
604  long dateL = email.getSentDate();
605  String headers = email.getHeaders();
606  String body = email.getTextBody();
607  String bodyHTML = email.getHtmlBody();
608  String rtf = email.getRtfBody();
609  String subject = email.getSubject();
610  long id = email.getId();
611  String localPath = email.getLocalPath();
612  String threadID = email.getMessageThreadID();
613 
614  List<String> senderAddressList = new ArrayList<>();
615  String senderAddress;
616  senderAddressList.addAll(findEmailAddresess(from));
617 
618  AccountFileInstance senderAccountInstance = null;
619 
620  if (senderAddressList.size() == 1) {
621  senderAddress = senderAddressList.get(0);
622  try {
623  senderAccountInstance = currentCase.getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.EMAIL, senderAddress, EmailParserModuleFactory.getModuleName(), abstractFile);
624  }
625  catch(TskCoreException ex) {
626  logger.log(Level.WARNING, "Failed to create account for email address " + senderAddress, ex); //NON-NLS
627  }
628  }
629  else {
630  logger.log(Level.WARNING, "Failed to find sender address, from = {0}", from); //NON-NLS
631  }
632 
633  List<String> recipientAddresses = new ArrayList<>();
634  recipientAddresses.addAll(findEmailAddresess(to));
635  recipientAddresses.addAll(findEmailAddresess(cc));
636  recipientAddresses.addAll(findEmailAddresess(bcc));
637 
638  List<AccountFileInstance> recipientAccountInstances = new ArrayList<>();
639  recipientAddresses.forEach((addr) -> {
640  try {
641  AccountFileInstance recipientAccountInstance =
642  currentCase.getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.EMAIL, addr,
643  EmailParserModuleFactory.getModuleName(), abstractFile);
644  recipientAccountInstances.add(recipientAccountInstance);
645  }
646  catch(TskCoreException ex) {
647  logger.log(Level.WARNING, "Failed to create account for email address " + addr, ex); //NON-NLS
648  }
649  });
650 
651  addArtifactAttribute(headers, ATTRIBUTE_TYPE.TSK_HEADERS, bbattributes);
652  addArtifactAttribute(from, ATTRIBUTE_TYPE.TSK_EMAIL_FROM, bbattributes);
653  addArtifactAttribute(to, ATTRIBUTE_TYPE.TSK_EMAIL_TO, bbattributes);
654  addArtifactAttribute(subject, ATTRIBUTE_TYPE.TSK_SUBJECT, bbattributes);
655 
656  addArtifactAttribute(dateL, ATTRIBUTE_TYPE.TSK_DATETIME_RCVD, bbattributes);
657  addArtifactAttribute(dateL, ATTRIBUTE_TYPE.TSK_DATETIME_SENT, bbattributes);
658 
659  addArtifactAttribute(body, ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN, bbattributes);
660 
661  addArtifactAttribute(((id < 0L) ? NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.notAvail") : String.valueOf(id)),
662  ATTRIBUTE_TYPE.TSK_MSG_ID, bbattributes);
663 
664  addArtifactAttribute(((localPath.isEmpty() == false) ? localPath : ""),
665  ATTRIBUTE_TYPE.TSK_PATH, bbattributes);
666 
667  addArtifactAttribute(cc, ATTRIBUTE_TYPE.TSK_EMAIL_CC, bbattributes);
668  addArtifactAttribute(bodyHTML, ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML, bbattributes);
669  addArtifactAttribute(rtf, ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF, bbattributes);
670  addArtifactAttribute(threadID, ATTRIBUTE_TYPE.TSK_THREAD_ID, bbattributes);
671 
672 
673  try {
674 
675  bbart = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG);
676  bbart.addAttributes(bbattributes);
677 
678  // Add account relationships
679  currentCase.getSleuthkitCase().getCommunicationsManager().addRelationships(senderAccountInstance, recipientAccountInstances, bbart,Relationship.Type.MESSAGE, dateL);
680 
681  try {
682  // index the artifact for keyword search
683  blackboard.postArtifact(bbart, EmailParserModuleFactory.getModuleName());
684  } catch (Blackboard.BlackboardException ex) {
685  logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bbart.getArtifactID(), ex); //NON-NLS
686  MessageNotifyUtil.Notify.error(Bundle.ThunderbirdMboxFileIngestModule_addArtifact_indexError_message(), bbart.getDisplayName());
687  }
688  } catch (TskCoreException | TskDataException ex) {
689  logger.log(Level.WARNING, null, ex);
690  }
691 
692  return bbart;
693  }
694 
702  static void addArtifactAttribute(String stringVal, BlackboardAttribute.Type attrType, Collection<BlackboardAttribute> bbattributes) {
703  if (stringVal.isEmpty() == false) {
704  bbattributes.add(new BlackboardAttribute(attrType, EmailParserModuleFactory.getModuleName(), stringVal));
705  }
706  }
707 
715  static void addArtifactAttribute(String stringVal, ATTRIBUTE_TYPE attrType, Collection<BlackboardAttribute> bbattributes) {
716  if (stringVal.isEmpty() == false) {
717  bbattributes.add(new BlackboardAttribute(attrType, EmailParserModuleFactory.getModuleName(), stringVal));
718  }
719  }
720 
728  static void addArtifactAttribute(long longVal, ATTRIBUTE_TYPE attrType, Collection<BlackboardAttribute> bbattributes) {
729  if (longVal > 0) {
730  bbattributes.add(new BlackboardAttribute(attrType, EmailParserModuleFactory.getModuleName(), longVal));
731  }
732  }
733 
740  void postErrorMessage(String subj, String details) {
741  IngestMessage ingestMessage = IngestMessage.createErrorMessage(EmailParserModuleFactory.getModuleVersion(), subj, details);
742  services.postMessage(ingestMessage);
743  }
744 
750  IngestServices getServices() {
751  return services;
752  }
753 
754  @Override
755  public void shutDown() {
756  // nothing to shut down
757  }
758 }
static IngestMessage createErrorMessage(String source, String subject, String detailsHtml)
void processEmails(List< EmailMessage > partialEmailsForThreading, Iterator< EmailMessage > fullMessageIterator, AbstractFile abstractFile)
BlackboardArtifact addEmailArtifact(EmailMessage email, AbstractFile abstractFile)
static< T > long writeToFile(Content content, java.io.File outputFile, ProgressHandle progress, Future< T > worker, boolean source)
synchronized DerivedFile addDerivedFile(String fileName, String localPath, long size, long ctime, long crtime, long atime, long mtime, boolean isFile, Content parentObj, String rederiveDetails, String toolName, String toolVersion, String otherDetails, TskData.EncodingType encodingType)
BlackboardArtifact associateAttachmentWithMesssge(BlackboardArtifact message, AbstractFile attachedFile)
void addFilesToJob(List< AbstractFile > files)
void postMessage(final IngestMessage message)
void fireModuleContentEvent(ModuleContentEvent moduleContentEvent)
static void error(String title, String message)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
List< AbstractFile > handleAttachments(List< EmailMessage.Attachment > attachments, AbstractFile abstractFile, BlackboardArtifact messageArtifact)
static synchronized IngestServices getInstance()

Copyright © 2012-2019 Basis Technology. Generated on: Tue Jan 7 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.