Autopsy  4.11.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.HashSet;
26 import java.util.List;
27 import java.util.Set;
28 import java.util.logging.Level;
29 import java.util.regex.Matcher;
30 import java.util.regex.Pattern;
31 import org.openide.util.NbBundle;
32 import org.openide.util.NbBundle.Messages;
48 import org.sleuthkit.datamodel.AbstractFile;
49 import org.sleuthkit.datamodel.Account;
50 import org.sleuthkit.datamodel.AccountFileInstance;
51 import org.sleuthkit.datamodel.BlackboardArtifact;
52 import org.sleuthkit.datamodel.BlackboardAttribute;
53 import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
54 import org.sleuthkit.datamodel.DerivedFile;
55 import org.sleuthkit.datamodel.Relationship;
56 import org.sleuthkit.datamodel.TskCoreException;
57 import org.sleuthkit.datamodel.TskData;
58 import org.sleuthkit.datamodel.TskDataException;
59 import org.sleuthkit.datamodel.TskException;
60 
66 public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
67  private static final Logger logger = Logger.getLogger(ThunderbirdMboxFileIngestModule.class.getName());
72 
73  private Case currentCase;
74 
79  }
80 
81  @Override
82  @Messages ({"ThunderbirdMboxFileIngestModule.noOpenCase.errMsg=Exception while getting open case."})
83  public void startUp(IngestJobContext context) throws IngestModuleException {
84  this.context = context;
85  try {
86  currentCase = Case.getCurrentCaseThrows();
88  } catch (NoCurrentCaseException ex) {
89  logger.log(Level.SEVERE, "Exception while getting open case.", ex);
90  throw new IngestModuleException(Bundle.ThunderbirdMboxFileIngestModule_noOpenCase_errMsg(), ex);
91  }
92  }
93 
94  @Override
95  public ProcessResult process(AbstractFile abstractFile) {
96 
97  try {
99  } catch (NoCurrentCaseException ex) {
100  logger.log(Level.SEVERE, "Exception while getting open case.", ex);
101  return ProcessResult.ERROR;
102  }
103 
104  // skip known
105  if (abstractFile.getKnown().equals(TskData.FileKnown.KNOWN)) {
106  return ProcessResult.OK;
107  }
108 
109  //skip unalloc
110  if ((abstractFile.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)) ||
111  (abstractFile.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.SLACK))) {
112  return ProcessResult.OK;
113  }
114 
115  if ((abstractFile.isFile() == false)) {
116  return ProcessResult.OK;
117  }
118 
119  // check its signature
120  boolean isMbox = false;
121  try {
122  byte[] t = new byte[64];
123  if (abstractFile.getSize() > 64) {
124  int byteRead = abstractFile.read(t, 0, 64);
125  if (byteRead > 0) {
126  isMbox = MboxParser.isValidMimeTypeMbox(t);
127  }
128  }
129  } catch (TskException ex) {
130  logger.log(Level.WARNING, null, ex);
131  }
132 
133  if (isMbox) {
134  return processMBox(abstractFile);
135  }
136 
137  if (PstParser.isPstFile(abstractFile)) {
138  return processPst(abstractFile);
139  }
140 
141  if (VcardParser.isVcardFile(abstractFile)) {
142  return processVcard(abstractFile);
143  }
144 
145  return ProcessResult.OK;
146  }
147 
155  @Messages({"ThunderbirdMboxFileIngestModule.processPst.indexError.message=Failed to index encryption detected artifact for keyword search."})
156  private ProcessResult processPst(AbstractFile abstractFile) {
157  String fileName;
158  try {
159  fileName = getTempPath() + File.separator + abstractFile.getName()
160  + "-" + String.valueOf(abstractFile.getId());
161  } catch (NoCurrentCaseException ex) {
162  logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
163  return ProcessResult.ERROR;
164  }
165  File file = new File(fileName);
166 
167  long freeSpace = services.getFreeDiskSpace();
168  if ((freeSpace != IngestMonitor.DISK_FREE_SPACE_UNKNOWN) && (abstractFile.getSize() >= freeSpace)) {
169  logger.log(Level.WARNING, "Not enough disk space to write file to disk."); //NON-NLS
171  NbBundle.getMessage(this.getClass(),
172  "ThunderbirdMboxFileIngestModule.processPst.errMsg.outOfDiskSpace",
173  abstractFile.getName()));
174  services.postMessage(msg);
175  return ProcessResult.OK;
176  }
177 
178  try {
179  ContentUtils.writeToFile(abstractFile, file, context::fileIngestIsCancelled);
180  } catch (IOException ex) {
181  logger.log(Level.WARNING, "Failed writing pst file to disk.", ex); //NON-NLS
182  return ProcessResult.OK;
183  }
184 
185  PstParser parser = new PstParser(services);
186  PstParser.ParseResult result = parser.parse(file, abstractFile.getId());
187 
188  if (result == PstParser.ParseResult.OK) {
189  // parse success: Process email and add artifacts
190  processEmails(parser.getResults(), abstractFile);
191 
192  } else if (result == PstParser.ParseResult.ENCRYPT) {
193  // encrypted pst: Add encrypted file artifact
194  try {
195  BlackboardArtifact artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED);
196  artifact.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, EmailParserModuleFactory.getModuleName(), NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.encryptionFileLevel")));
197 
198  try {
199  // index the artifact for keyword search
200  blackboard.indexArtifact(artifact);
201  } catch (Blackboard.BlackboardException ex) {
202  MessageNotifyUtil.Notify.error(Bundle.ThunderbirdMboxFileIngestModule_processPst_indexError_message(), artifact.getDisplayName());
203  logger.log(Level.SEVERE, "Unable to index blackboard artifact " + artifact.getArtifactID(), ex); //NON-NLS
204  }
205 
206  services.fireModuleDataEvent(new ModuleDataEvent(EmailParserModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED));
207  } catch (TskCoreException ex) {
208  logger.log(Level.INFO, "Failed to add encryption attribute to file: {0}", abstractFile.getName()); //NON-NLS
209  }
210  } else {
211  // parsing error: log message
212  postErrorMessage(
213  NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.processPst.errProcFile.msg",
214  abstractFile.getName()),
215  NbBundle.getMessage(this.getClass(),
216  "ThunderbirdMboxFileIngestModule.processPst.errProcFile.details"));
217  logger.log(Level.INFO, "PSTParser failed to parse {0}", abstractFile.getName()); //NON-NLS
218  return ProcessResult.ERROR;
219  }
220 
221  if (file.delete() == false) {
222  logger.log(Level.INFO, "Failed to delete temp file: {0}", file.getName()); //NON-NLS
223  }
224 
225  String errors = parser.getErrors();
226  if (errors.isEmpty() == false) {
227  postErrorMessage(
228  NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.processPst.errProcFile.msg2",
229  abstractFile.getName()), errors);
230  }
231 
232  return ProcessResult.OK;
233  }
234 
242  private ProcessResult processMBox(AbstractFile abstractFile) {
243  String mboxFileName = abstractFile.getName();
244  String mboxParentDir = abstractFile.getParentPath();
245  // use the local path to determine the e-mail folder structure
246  String emailFolder = "";
247  // email folder is everything after "Mail" or ImapMail
248  if (mboxParentDir.contains("/Mail/")) { //NON-NLS
249  emailFolder = mboxParentDir.substring(mboxParentDir.indexOf("/Mail/") + 5); //NON-NLS
250  } else if (mboxParentDir.contains("/ImapMail/")) { //NON-NLS
251  emailFolder = mboxParentDir.substring(mboxParentDir.indexOf("/ImapMail/") + 9); //NON-NLS
252  }
253  emailFolder = emailFolder + mboxFileName;
254  emailFolder = emailFolder.replaceAll(".sbd", ""); //NON-NLS
255 
256  String fileName;
257  try {
258  fileName = getTempPath() + File.separator + abstractFile.getName()
259  + "-" + String.valueOf(abstractFile.getId());
260  } catch (NoCurrentCaseException ex) {
261  logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
262  return ProcessResult.ERROR;
263  }
264  File file = new File(fileName);
265 
266  long freeSpace = services.getFreeDiskSpace();
267  if ((freeSpace != IngestMonitor.DISK_FREE_SPACE_UNKNOWN) && (abstractFile.getSize() >= freeSpace)) {
268  logger.log(Level.WARNING, "Not enough disk space to write file to disk."); //NON-NLS
269  postErrorMessage(
270  NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.processMBox.errProcFile.msg",
271  abstractFile.getName()),
272  NbBundle.getMessage(this.getClass(),
273  "ThunderbirdMboxFileIngestModule.processMBox.errProfFile.details"));
274  return ProcessResult.OK;
275  }
276 
277  try {
278  ContentUtils.writeToFile(abstractFile, file, context::fileIngestIsCancelled);
279  } catch (IOException ex) {
280  logger.log(Level.WARNING, "Failed writing mbox file to disk.", ex); //NON-NLS
281  return ProcessResult.OK;
282  }
283 
284  MboxParser parser = new MboxParser(services, emailFolder);
285  List<EmailMessage> emails = parser.parse(file, abstractFile.getId());
286  processEmails(emails, abstractFile);
287 
288  if (file.delete() == false) {
289  logger.log(Level.INFO, "Failed to delete temp file: {0}", file.getName()); //NON-NLS
290  }
291 
292  String errors = parser.getErrors();
293  if (errors.isEmpty() == false) {
294  postErrorMessage(
295  NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.processMBox.errProcFile.msg2",
296  abstractFile.getName()), errors);
297  }
298 
299  return ProcessResult.OK;
300  }
301 
310  @Messages({
311  "# {0} - file name",
312  "# {1} - file ID",
313  "ThunderbirdMboxFileIngestModule.errorMessage.outOfDiskSpace=Out of disk space. Cannot copy '{0}' (id={1}) to parse."
314  })
315  private ProcessResult processVcard(AbstractFile abstractFile) {
316  String fileName;
317  try {
318  fileName = getTempPath() + File.separator + abstractFile.getName()
319  + "-" + String.valueOf(abstractFile.getId());
320  } catch (NoCurrentCaseException ex) {
321  logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
322  return ProcessResult.ERROR;
323  }
324  File file = new File(fileName);
325 
326  long freeSpace = services.getFreeDiskSpace();
327  if ((freeSpace != IngestMonitor.DISK_FREE_SPACE_UNKNOWN) && (abstractFile.getSize() >= freeSpace)) {
328  logger.log(Level.WARNING, String.format("Not enough disk space to write file '%s' (id=%d) to disk.",
329  abstractFile.getName(), abstractFile.getId())); //NON-NLS
331  Bundle.ThunderbirdMboxFileIngestModule_errorMessage_outOfDiskSpace(abstractFile.getName(), abstractFile.getId()));
332  services.postMessage(msg);
333  return ProcessResult.OK;
334  }
335 
336  try {
337  ContentUtils.writeToFile(abstractFile, file, context::fileIngestIsCancelled);
338  } catch (IOException ex) {
339  logger.log(Level.WARNING, String.format("Failed writing the vCard file '%s' (id=%d) to disk.",
340  abstractFile.getName(), abstractFile.getId()), ex); //NON-NLS
341  return ProcessResult.OK;
342  }
343 
344  try {
345  VcardParser parser = new VcardParser(currentCase, context);
346  parser.parse(file, abstractFile);
347  } catch (IOException | NoCurrentCaseException ex) {
348  logger.log(Level.WARNING, String.format("Exception while parsing the file '%s' (id=%d).", file.getName(), abstractFile.getId()), ex); //NON-NLS
349  return ProcessResult.OK;
350  }
351 
352  if (file.delete() == false) {
353  logger.log(Level.INFO, "Failed to delete temp file: {0}", file.getName()); //NON-NLS
354  }
355 
356  return ProcessResult.OK;
357  }
358 
365  static String getTempPath() throws NoCurrentCaseException {
366  String tmpDir = Case.getCurrentCaseThrows().getTempDirectory() + File.separator
367  + "EmailParser"; //NON-NLS
368  File dir = new File(tmpDir);
369  if (dir.exists() == false) {
370  dir.mkdirs();
371  }
372  return tmpDir;
373  }
374 
382  static String getModuleOutputPath() throws NoCurrentCaseException {
383  String outDir = Case.getCurrentCaseThrows().getModuleDirectory() + File.separator
384  + EmailParserModuleFactory.getModuleName();
385  File dir = new File(outDir);
386  if (dir.exists() == false) {
387  dir.mkdirs();
388  }
389  return outDir;
390  }
391 
398  static String getRelModuleOutputPath() throws NoCurrentCaseException {
399  return Case.getCurrentCaseThrows().getModuleOutputDirectoryRelativePath() + File.separator
400  + EmailParserModuleFactory.getModuleName();
401  }
402 
410  private void processEmails(List<EmailMessage> emails, AbstractFile abstractFile) {
411  List<AbstractFile> derivedFiles = new ArrayList<>();
412 
413  // Putting try/catch around this to catch any exception and still allow
414  // the creation of the artifacts to continue.
415  try{
416  EmailMessageThreader.threadMessages(emails, String.format("%d", abstractFile.getId()));
417  } catch(Exception ex) {
418  logger.log(Level.WARNING, String.format("Exception thrown parsing emails from %s", abstractFile.getName()), ex);
419  }
420 
421  for (EmailMessage email : emails) {
422  BlackboardArtifact msgArtifact = addEmailArtifact(email, abstractFile);
423 
424  if ((msgArtifact != null) && (email.hasAttachment())) {
425  derivedFiles.addAll(handleAttachments(email.getAttachments(), abstractFile, msgArtifact ));
426  }
427  }
428 
429  if (derivedFiles.isEmpty() == false) {
430  for (AbstractFile derived : derivedFiles) {
431  services.fireModuleContentEvent(new ModuleContentEvent(derived));
432  }
433  }
434  context.addFilesToJob(derivedFiles);
435  services.fireModuleDataEvent(new ModuleDataEvent(EmailParserModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG));
436  }
437 
448  private List<AbstractFile> handleAttachments(List<EmailMessage.Attachment> attachments, AbstractFile abstractFile, BlackboardArtifact messageArtifact) {
449  List<AbstractFile> files = new ArrayList<>();
450  for (EmailMessage.Attachment attach : attachments) {
451  String filename = attach.getName();
452  long crTime = attach.getCrTime();
453  long mTime = attach.getmTime();
454  long aTime = attach.getaTime();
455  long cTime = attach.getcTime();
456  String relPath = attach.getLocalPath();
457  long size = attach.getSize();
458  TskData.EncodingType encodingType = attach.getEncodingType();
459 
460  try {
461  DerivedFile df = fileManager.addDerivedFile(filename, relPath,
462  size, cTime, crTime, aTime, mTime, true, messageArtifact, "",
463  EmailParserModuleFactory.getModuleName(), EmailParserModuleFactory.getModuleVersion(), "", encodingType);
464  files.add(df);
465  } catch (TskCoreException ex) {
466  postErrorMessage(
467  NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.handleAttch.errMsg",
468  abstractFile.getName()),
469  NbBundle.getMessage(this.getClass(),
470  "ThunderbirdMboxFileIngestModule.handleAttch.errMsg.details", filename));
471  logger.log(Level.INFO, "", ex);
472  }
473  }
474  return files;
475  }
476 
484  private Set<String> findEmailAddresess(String input) {
485  Pattern p = Pattern.compile("\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b",
486  Pattern.CASE_INSENSITIVE);
487  Matcher m = p.matcher(input);
488  Set<String> emailAddresses = new HashSet<>();
489  while (m.find()) {
490  emailAddresses.add( m.group());
491  }
492  return emailAddresses;
493  }
494 
503  @Messages({"ThunderbirdMboxFileIngestModule.addArtifact.indexError.message=Failed to index email message detected artifact for keyword search."})
504  private BlackboardArtifact addEmailArtifact(EmailMessage email, AbstractFile abstractFile) {
505  BlackboardArtifact bbart = null;
506  List<BlackboardAttribute> bbattributes = new ArrayList<>();
507  String to = email.getRecipients();
508  String cc = email.getCc();
509  String bcc = email.getBcc();
510  String from = email.getSender();
511  long dateL = email.getSentDate();
512  String headers = email.getHeaders();
513  String body = email.getTextBody();
514  String bodyHTML = email.getHtmlBody();
515  String rtf = email.getRtfBody();
516  String subject = email.getSubject();
517  long id = email.getId();
518  String localPath = email.getLocalPath();
519  String threadID = email.getMessageThreadID();
520 
521  List<String> senderAddressList = new ArrayList<>();
522  String senderAddress;
523  senderAddressList.addAll(findEmailAddresess(from));
524 
525  AccountFileInstance senderAccountInstance = null;
526 
527  if (senderAddressList.size() == 1) {
528  senderAddress = senderAddressList.get(0);
529  try {
530  senderAccountInstance = currentCase.getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.EMAIL, senderAddress, EmailParserModuleFactory.getModuleName(), abstractFile);
531  }
532  catch(TskCoreException ex) {
533  logger.log(Level.WARNING, "Failed to create account for email address " + senderAddress, ex); //NON-NLS
534  }
535  }
536  else {
537  logger.log(Level.WARNING, "Failed to find sender address, from = {0}", from); //NON-NLS
538  }
539 
540  List<String> recipientAddresses = new ArrayList<>();
541  recipientAddresses.addAll(findEmailAddresess(to));
542  recipientAddresses.addAll(findEmailAddresess(cc));
543  recipientAddresses.addAll(findEmailAddresess(bcc));
544 
545  List<AccountFileInstance> recipientAccountInstances = new ArrayList<>();
546  recipientAddresses.forEach((addr) -> {
547  try {
548  AccountFileInstance recipientAccountInstance =
549  currentCase.getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.EMAIL, addr,
550  EmailParserModuleFactory.getModuleName(), abstractFile);
551  recipientAccountInstances.add(recipientAccountInstance);
552  }
553  catch(TskCoreException ex) {
554  logger.log(Level.WARNING, "Failed to create account for email address " + addr, ex); //NON-NLS
555  }
556  });
557 
558  addArtifactAttribute(headers, ATTRIBUTE_TYPE.TSK_HEADERS, bbattributes);
559  addArtifactAttribute(from, ATTRIBUTE_TYPE.TSK_EMAIL_FROM, bbattributes);
560  addArtifactAttribute(to, ATTRIBUTE_TYPE.TSK_EMAIL_TO, bbattributes);
561  addArtifactAttribute(subject, ATTRIBUTE_TYPE.TSK_SUBJECT, bbattributes);
562 
563  addArtifactAttribute(dateL, ATTRIBUTE_TYPE.TSK_DATETIME_RCVD, bbattributes);
564  addArtifactAttribute(dateL, ATTRIBUTE_TYPE.TSK_DATETIME_SENT, bbattributes);
565 
566  addArtifactAttribute(body, ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN, bbattributes);
567 
568  addArtifactAttribute(((id < 0L) ? NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.notAvail") : String.valueOf(id)),
569  ATTRIBUTE_TYPE.TSK_MSG_ID, bbattributes);
570 
571  addArtifactAttribute(((localPath.isEmpty() == false) ? localPath : "/foo/bar"),
572  ATTRIBUTE_TYPE.TSK_PATH, bbattributes);
573 
574  addArtifactAttribute(cc, ATTRIBUTE_TYPE.TSK_EMAIL_CC, bbattributes);
575  addArtifactAttribute(bodyHTML, ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML, bbattributes);
576  addArtifactAttribute(rtf, ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF, bbattributes);
577  addArtifactAttribute(threadID, ATTRIBUTE_TYPE.TSK_THREAD_ID, bbattributes);
578 
579 
580  try {
581 
582  bbart = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG);
583  bbart.addAttributes(bbattributes);
584 
585  // Add account relationships
586  currentCase.getSleuthkitCase().getCommunicationsManager().addRelationships(senderAccountInstance, recipientAccountInstances, bbart,Relationship.Type.MESSAGE, dateL);
587 
588  try {
589  // index the artifact for keyword search
590  blackboard.indexArtifact(bbart);
591  } catch (Blackboard.BlackboardException ex) {
592  logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bbart.getArtifactID(), ex); //NON-NLS
593  MessageNotifyUtil.Notify.error(Bundle.ThunderbirdMboxFileIngestModule_addArtifact_indexError_message(), bbart.getDisplayName());
594  }
595  } catch (TskCoreException | TskDataException ex) {
596  logger.log(Level.WARNING, null, ex);
597  }
598 
599  return bbart;
600  }
601 
609  static void addArtifactAttribute(String stringVal, BlackboardAttribute.Type attrType, Collection<BlackboardAttribute> bbattributes) {
610  if (stringVal.isEmpty() == false) {
611  bbattributes.add(new BlackboardAttribute(attrType, EmailParserModuleFactory.getModuleName(), stringVal));
612  }
613  }
614 
622  static void addArtifactAttribute(String stringVal, ATTRIBUTE_TYPE attrType, Collection<BlackboardAttribute> bbattributes) {
623  if (stringVal.isEmpty() == false) {
624  bbattributes.add(new BlackboardAttribute(attrType, EmailParserModuleFactory.getModuleName(), stringVal));
625  }
626  }
627 
635  static void addArtifactAttribute(long longVal, ATTRIBUTE_TYPE attrType, Collection<BlackboardAttribute> bbattributes) {
636  if (longVal > 0) {
637  bbattributes.add(new BlackboardAttribute(attrType, EmailParserModuleFactory.getModuleName(), longVal));
638  }
639  }
640 
647  void postErrorMessage(String subj, String details) {
648  IngestMessage ingestMessage = IngestMessage.createErrorMessage(EmailParserModuleFactory.getModuleVersion(), subj, details);
649  services.postMessage(ingestMessage);
650  }
651 
657  IngestServices getServices() {
658  return services;
659  }
660 
661  @Override
662  public void shutDown() {
663  // nothing to shut down
664  }
665 }
static IngestMessage createErrorMessage(String source, String subject, String detailsHtml)
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)
void processEmails(List< EmailMessage > emails, AbstractFile abstractFile)
void addFilesToJob(List< AbstractFile > files)
void postMessage(final IngestMessage message)
void fireModuleDataEvent(ModuleDataEvent moduleDataEvent)
void fireModuleContentEvent(ModuleContentEvent moduleContentEvent)
static void error(String title, String message)
synchronized void indexArtifact(BlackboardArtifact artifact)
Definition: Blackboard.java:58
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-2018 Basis Technology. Generated on: Fri Jun 21 2019
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.