19package org.sleuthkit.autopsy.datamodel;
21import java.beans.PropertyChangeEvent;
22import java.beans.PropertyChangeListener;
23import java.sql.ResultSet;
24import java.sql.SQLException;
25import java.util.ArrayList;
26import java.util.EnumSet;
27import java.util.HashMap;
28import java.util.LinkedHashMap;
31import java.util.Observable;
32import java.util.Observer;
34import java.util.logging.Level;
35import org.openide.nodes.ChildFactory;
36import org.openide.nodes.Children;
37import org.openide.nodes.Node;
38import org.openide.nodes.Sheet;
39import org.openide.util.NbBundle;
40import org.openide.util.WeakListeners;
41import org.openide.util.lookup.Lookups;
42import org.sleuthkit.autopsy.casemodule.Case;
43import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
44import org.sleuthkit.autopsy.coreutils.Logger;
45import org.sleuthkit.autopsy.ingest.IngestManager;
46import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
47import org.sleuthkit.datamodel.BlackboardArtifact;
48import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_EMAIL_MSG;
49import org.sleuthkit.datamodel.BlackboardAttribute;
50import org.sleuthkit.datamodel.SleuthkitCase;
51import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
52import org.sleuthkit.datamodel.TskCoreException;
53import org.sleuthkit.autopsy.datamodel.Artifacts.UpdatableCountTypeNode;
54import org.sleuthkit.datamodel.DataArtifact;
64 private static final String
LABEL_NAME = BlackboardArtifact.Type.TSK_EMAIL_MSG.getTypeName();
81 public static final Map<String, String>
parsePath(String path) {
82 Map<String, String> parsed =
new HashMap<>();
84 if (split.length < 4) {
115 this.filteringDSObjId = objId;
121 return visitor.
visit(
this);
124 private final class EmailResults
extends Observable {
127 private final Map<String, Map<String, List<Long>>>
accounts =
new LinkedHashMap<>();
141 return accounts.get(account).keySet();
147 return accounts.get(account).get(folder);
151 @SuppressWarnings(
"deprecation")
162 int emailArtifactId = BlackboardArtifact.Type.TSK_EMAIL_MSG.getTypeID();
163 int pathAttrId = BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID();
165 String query =
"SELECT \n"
166 +
" art.artifact_obj_id AS artifact_obj_id,\n"
167 +
" (SELECT value_text FROM blackboard_attributes attr\n"
168 +
" WHERE attr.artifact_id = art.artifact_id AND attr.attribute_type_id = " + pathAttrId +
"\n"
169 +
" LIMIT 1) AS value_text\n"
171 +
" blackboard_artifacts art\n"
172 +
" WHERE art.artifact_type_id = " + emailArtifactId +
"\n"
176 Map<String, Map<String, List<Long>>> newMapping =
new HashMap<>();
178 try (CaseDbQuery dbQuery =
skCase.executeQuery(query)) {
179 ResultSet resultSet = dbQuery.getResultSet();
180 while (resultSet.next()) {
181 Long artifactObjId = resultSet.getLong(
"artifact_obj_id");
182 Map<String, String> accountFolderMap =
parsePath(resultSet.getString(
"value_text"));
186 Map<String, List<Long>> folders = newMapping.computeIfAbsent(account, (str) ->
new LinkedHashMap<>());
187 List<Long> messages = folders.computeIfAbsent(folder, (str) ->
new ArrayList<>());
188 messages.add(artifactObjId);
190 }
catch (TskCoreException | SQLException ex) {
191 logger.log(Level.WARNING,
"Cannot initialize email extraction: ", ex);
212 Lookups.singleton(TSK_EMAIL_MSG.getDisplayName()),
213 TSK_EMAIL_MSG.getDisplayName(),
218 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/mail-icon-16.png");
229 return visitor.
visit(
this);
234 Sheet sheet = super.createSheet();
235 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
236 if (sheetSet ==
null) {
237 sheetSet = Sheet.createPropertiesSet();
241 sheetSet.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.name"),
242 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.displayName"),
243 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.desc"),
251 return getClass().getName();
258 private class AccountFactory extends ChildFactory.Detachable<String> implements Observer {
264 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
266 public void propertyChange(PropertyChangeEvent evt) {
267 String eventType = evt.getPropertyName();
284 if (
null != eventData && eventData.
getBlackboardArtifactType().getTypeID() == BlackboardArtifact.Type.TSK_EMAIL_MSG.getTypeID()) {
310 if (evt.getNewValue() ==
null) {
318 private final PropertyChangeListener
weakPcl = WeakListeners.propertyChange(
pcl,
null);
350 public void update(Observable o, Object arg) {
366 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/account-icon-16.png");
377 Sheet sheet = super.createSheet();
378 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
379 if (sheetSet ==
null) {
380 sheetSet = Sheet.createPropertiesSet();
384 sheetSet.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.name"),
385 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.displayName"),
386 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.desc"),
399 return visitor.
visit(
this);
403 public void update(Observable o, Object arg) {
409 return getClass().getName();
416 private class FolderFactory extends ChildFactory<String> implements Observer {
438 public void update(Observable o, Object arg) {
456 private static String
getFolderKey(String accountName, String folderName) {
457 return accountName +
"_" + folderName;
471 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/folder-icon-16.png");
490 Sheet sheet = super.createSheet();
491 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
492 if (sheetSet ==
null) {
493 sheetSet = Sheet.createPropertiesSet();
497 sheetSet.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.name"),
498 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.displayName"),
499 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.desc"),
507 return visitor.
visit(
this);
511 public void update(Observable o, Object arg) {
517 return getClass().getName();
542 public void update(Observable o, Object arg) {
548 List<DataArtifact> keys =
new ArrayList<>();
553 DataArtifact art =
skCase.getBlackboard().getDataArtifactById(
id);
558 }
catch (TskCoreException ex) {
559 logger.log(Level.WARNING,
"Error getting mail messages keys", ex);
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
static Case getCurrentCaseThrows()
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
synchronized static Logger getLogger(String name)
UpdatableCountTypeNode(Children children, Lookup lookup, String baseName, long filteringDSObjId, BlackboardArtifact.Type... types)
final long filteringDSObjId
static final Logger logger
BaseChildFactory(String nodeName)
DisplayableItemNode(Children children)
static synchronized IngestManager getInstance()
void removeIngestModuleEventListener(final PropertyChangeListener listener)
void removeIngestJobEventListener(final PropertyChangeListener listener)
void addIngestModuleEventListener(final PropertyChangeListener listener)
void addIngestJobEventListener(final PropertyChangeListener listener)
BlackboardArtifact.Type getBlackboardArtifactType()
T visit(DataSourceFilesNode in)