mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 07:56:16 +00:00
2841: Attachments are children of messages.
2692: Messages & Attachments show in DataSource tree
This commit is contained in:
parent
4fdea244af
commit
a4dc97af6e
@ -45,6 +45,7 @@ import org.sleuthkit.datamodel.LocalFilesDataSource;
|
||||
import org.sleuthkit.datamodel.TskDataException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractContent;
|
||||
import org.sleuthkit.datamodel.CarvingResult;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
@ -295,7 +296,7 @@ public class FileManager implements Closeable {
|
||||
* @param atime The accessed time of the file.
|
||||
* @param mtime The modified time of the file.
|
||||
* @param isFile True if a file, false if a directory.
|
||||
* @param parentFile The parent file from which the file was derived.
|
||||
* @param parentObj The parent object from which the file was derived.
|
||||
* @param rederiveDetails The details needed to re-derive file (will be
|
||||
* specific to the derivation method), currently
|
||||
* unused.
|
||||
@ -317,7 +318,7 @@ public class FileManager implements Closeable {
|
||||
long size,
|
||||
long ctime, long crtime, long atime, long mtime,
|
||||
boolean isFile,
|
||||
AbstractFile parentFile,
|
||||
Content parentObj,
|
||||
String rederiveDetails, String toolName, String toolVersion, String otherDetails,
|
||||
TskData.EncodingType encodingType) throws TskCoreException {
|
||||
if (null == caseDb) {
|
||||
@ -325,7 +326,7 @@ public class FileManager implements Closeable {
|
||||
}
|
||||
return caseDb.addDerivedFile(fileName, localPath, size,
|
||||
ctime, crtime, atime, mtime,
|
||||
isFile, parentFile, rederiveDetails, toolName, toolVersion, otherDetails, encodingType);
|
||||
isFile, parentObj, rederiveDetails, toolName, toolVersion, otherDetails, encodingType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,6 +25,7 @@ import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.datamodel.FileTypes.FileTypesNode;
|
||||
import org.sleuthkit.autopsy.datamodel.accounts.Accounts;
|
||||
import org.sleuthkit.autopsy.datamodel.accounts.Accounts.AccountsRootNode;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.DerivedFile;
|
||||
import org.sleuthkit.datamodel.Directory;
|
||||
@ -117,6 +118,11 @@ abstract class AbstractContentChildren<T> extends Keys<T> {
|
||||
return new SlackFileNode(sf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractContentNode<? extends Content> visit(BlackboardArtifact art) {
|
||||
return new BlackboardArtifactNode(art);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractContentNode<? extends Content> defaultVisit(SleuthkitVisitableItem di) {
|
||||
throw new UnsupportedOperationException(NbBundle.getMessage(this.getClass(),
|
||||
|
@ -21,8 +21,8 @@ package org.sleuthkit.autopsy.datamodel;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.openide.util.Lookup;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
@ -48,13 +48,23 @@ public abstract class AbstractContentNode<T extends Content> extends ContentNode
|
||||
* @param content Underlying Content instances
|
||||
*/
|
||||
AbstractContentNode(T content) {
|
||||
//TODO consider child factory for the content children
|
||||
super(new ContentChildren(content), Lookups.singleton(content));
|
||||
this(content, Lookups.singleton(content) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles aspects that depend on the Content object
|
||||
*
|
||||
* @param content Underlying Content instances
|
||||
* @param lookup The Lookup object for the node.
|
||||
*/
|
||||
AbstractContentNode(T content, Lookup lookup) {
|
||||
//TODO consider child factory for the content children
|
||||
super(new ContentChildren(content), lookup);
|
||||
this.content = content;
|
||||
//super.setName(ContentUtils.getSystemName(content));
|
||||
super.setName("content_" + Long.toString(content.getId())); //NON-NLS
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the content data associated with this node
|
||||
*
|
||||
@ -66,8 +76,7 @@ public abstract class AbstractContentNode<T extends Content> extends ContentNode
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
throw new UnsupportedOperationException(
|
||||
NbBundle.getMessage(this.getClass(), "AbstractContentNode.exception.cannotChangeSysName.msg"));
|
||||
super.setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,6 +25,7 @@ import java.beans.PropertyChangeListener;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -34,6 +35,7 @@ import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.swing.Action;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.NbBundle;
|
||||
@ -43,9 +45,11 @@ import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagDeletedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
||||
import static org.sleuthkit.autopsy.datamodel.DataModelActionsFactory.VIEW_IN_NEW_WINDOW;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import static org.sleuthkit.autopsy.datamodel.DisplayableItemNode.findLinked;
|
||||
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
|
||||
import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction;
|
||||
import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
@ -61,7 +65,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
* Node wrapping a blackboard artifact object. This is generated from several
|
||||
* places in the tree.
|
||||
*/
|
||||
public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifact> {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(BlackboardArtifactNode.class.getName());
|
||||
|
||||
@ -72,6 +76,7 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
private final BlackboardArtifact artifact;
|
||||
private Content associated = null;
|
||||
private List<NodeProperty<? extends Object>> customProperties;
|
||||
|
||||
/*
|
||||
* Artifact types which should have the full unique path of the associated
|
||||
* content as a property.
|
||||
@ -130,22 +135,17 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
* @param iconPath icon to use for the artifact
|
||||
*/
|
||||
public BlackboardArtifactNode(BlackboardArtifact artifact, String iconPath) {
|
||||
super(Children.LEAF, createLookup(artifact));
|
||||
super(artifact, createLookup(artifact));
|
||||
|
||||
this.artifact = artifact;
|
||||
|
||||
// Look for associated Content i.e. the source file for the artifact
|
||||
if (this.getLookup().lookupAll(Content.class).size() > 1) {
|
||||
for (Content content : this.getLookup().lookupAll(Content.class)) {
|
||||
if ( (content != null) && (!(content instanceof BlackboardArtifact)) ){
|
||||
this.associated = content;
|
||||
break;
|
||||
}
|
||||
for (Content content : this.getLookup().lookupAll(Content.class)) {
|
||||
if ( (content != null) && (!(content instanceof BlackboardArtifact)) ){
|
||||
this.associated = content;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (null == this.associated ) {
|
||||
this.associated = this.getLookup().lookup(Content.class);
|
||||
}
|
||||
|
||||
this.setName(Long.toString(artifact.getArtifactID()));
|
||||
this.setDisplayName();
|
||||
@ -160,32 +160,18 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
* @param artifact artifact to encapsulate
|
||||
*/
|
||||
public BlackboardArtifactNode(BlackboardArtifact artifact) {
|
||||
super(Children.LEAF, createLookup(artifact));
|
||||
|
||||
this.artifact = artifact;
|
||||
|
||||
// Look for associated Content - the source file for the artifact
|
||||
if (this.getLookup().lookupAll(Content.class).size() > 1) {
|
||||
for (Content content : this.getLookup().lookupAll(Content.class)) {
|
||||
if ( (content != null) && (!(content instanceof BlackboardArtifact)) ){
|
||||
this.associated = content;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (null == this.associated ) {
|
||||
this.associated = this.getLookup().lookup(Content.class);
|
||||
}
|
||||
this.setName(Long.toString(artifact.getArtifactID()));
|
||||
this.setDisplayName();
|
||||
this.setIconBaseWithExtension(ExtractedContent.getIconFilePath(artifact.getArtifactTypeID())); //NON-NLS
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
this(artifact, ExtractedContent.getIconFilePath(artifact.getArtifactTypeID()));
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
}
|
||||
|
||||
public BlackboardArtifact getArtifact() {
|
||||
return this.artifact;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NbBundle.Messages({
|
||||
"BlackboardArtifactNode.getAction.errorTitle=Error getting actions",
|
||||
@ -235,10 +221,7 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
*/
|
||||
private void setDisplayName() {
|
||||
String displayName = ""; //NON-NLS
|
||||
if (associated != null) {
|
||||
displayName = associated.getName();
|
||||
}
|
||||
|
||||
|
||||
// If this is a node for a keyword hit on an artifact, we set the
|
||||
// display name to be the artifact type name followed by " Artifact"
|
||||
// e.g. "Messages Artifact".
|
||||
@ -262,9 +245,30 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
// Do nothing since the display name will be set to the file name.
|
||||
}
|
||||
}
|
||||
|
||||
if (displayName.isEmpty() && artifact != null) {
|
||||
displayName = artifact.getName();
|
||||
}
|
||||
|
||||
this.setDisplayName(displayName);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the associated source file/content
|
||||
*
|
||||
* @return source file/content name
|
||||
*/
|
||||
public String getSrcName() {
|
||||
|
||||
String srcName = "";
|
||||
if (associated != null) {
|
||||
srcName = associated.getName();
|
||||
}
|
||||
return srcName;
|
||||
}
|
||||
|
||||
|
||||
@NbBundle.Messages({
|
||||
"BlackboardArtifactNode.createSheet.artifactType.displayName=Artifact Type",
|
||||
"BlackboardArtifactNode.createSheet.artifactType.name=Artifact Type",
|
||||
@ -288,7 +292,7 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.name"),
|
||||
NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.displayName"),
|
||||
NO_DESCR,
|
||||
this.getDisplayName()));
|
||||
this.getSrcName()));
|
||||
if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) {
|
||||
try {
|
||||
BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
|
||||
@ -579,4 +583,9 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
public String getItemType() {
|
||||
return getClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T accept(ContentNodeVisitor<T> v) {
|
||||
return v.visit(this);
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,9 @@ interface ContentNodeVisitor<T> {
|
||||
T visit(LocalFileNode dfn);
|
||||
|
||||
T visit(SlackFileNode sfn);
|
||||
|
||||
T visit(BlackboardArtifactNode bban);
|
||||
|
||||
|
||||
/**
|
||||
* Visitor with an implementable default behavior for all types. Override
|
||||
@ -100,5 +103,10 @@ interface ContentNodeVisitor<T> {
|
||||
public T visit(SlackFileNode sfn) {
|
||||
return defaultVisit(sfn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(BlackboardArtifactNode bban) {
|
||||
return defaultVisit(bban);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -428,7 +428,7 @@ public class EmailExtracted implements AutopsyVisitableItem {
|
||||
|
||||
@Override
|
||||
public boolean isLeafTypeNode() {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.directorytree;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.beans.PropertyVetoException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
@ -43,6 +44,7 @@ import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import org.sleuthkit.autopsy.datamodel.AbstractAbstractFileNode.AbstractFilePropertyType;
|
||||
import org.sleuthkit.autopsy.datamodel.AbstractFsContentNode;
|
||||
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
|
||||
@ -71,6 +73,8 @@ import org.sleuthkit.datamodel.TskData;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
import org.sleuthkit.datamodel.VirtualDirectory;
|
||||
import static org.sleuthkit.autopsy.directorytree.Bundle.*;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* A node used to wrap another node before passing it to the result viewers. The
|
||||
@ -210,6 +214,26 @@ public class DataResultFilterNode extends FilterNode {
|
||||
return propertySets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the display name for the wrapped node.
|
||||
*
|
||||
* OutlineView used in the DataResult table uses getDisplayName() to populate
|
||||
* the first column, which is Source File.
|
||||
*
|
||||
* Hence this override to return the 'correct' displayName for the wrapped node.
|
||||
*
|
||||
* @return The display name for the node.
|
||||
*/
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
final Node orig = getOriginal();
|
||||
String name = orig.getDisplayName();
|
||||
if ((orig instanceof BlackboardArtifactNode)) {
|
||||
name = ((BlackboardArtifactNode) orig).getSrcName();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds information about which child node of this node, if any, should be
|
||||
* selected. Can be null.
|
||||
@ -248,16 +272,20 @@ public class DataResultFilterNode extends FilterNode {
|
||||
|
||||
private boolean filterKnown;
|
||||
private boolean filterSlack;
|
||||
private boolean filterArtifacts; // display message artifacts in the DataSource subtree
|
||||
|
||||
/**
|
||||
* the constructor
|
||||
*/
|
||||
private DataResultFilterChildren(Node arg, ExplorerManager sourceEm) {
|
||||
super(arg);
|
||||
|
||||
this.filterArtifacts = false;
|
||||
switch (SelectionContext.getSelectionContext(arg)) {
|
||||
case DATA_SOURCES:
|
||||
filterSlack = filterSlackFromDataSources;
|
||||
filterKnown = filterKnownFromDataSources;
|
||||
filterArtifacts = true;
|
||||
break;
|
||||
case VIEWS:
|
||||
filterSlack = filterSlackFromViews;
|
||||
@ -291,6 +319,16 @@ public class DataResultFilterNode extends FilterNode {
|
||||
return new Node[]{};
|
||||
}
|
||||
}
|
||||
|
||||
// filter out all non-message artifacts, if displaying the results from the Data Source tree
|
||||
BlackboardArtifact art = key.getLookup().lookup(BlackboardArtifact.class);
|
||||
if (art != null && filterArtifacts) {
|
||||
if ( (art.getArtifactTypeID() != BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) &&
|
||||
(art.getArtifactTypeID() != BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) ) {
|
||||
return new Node[]{};
|
||||
}
|
||||
}
|
||||
|
||||
return new Node[]{new DataResultFilterNode(key, sourceEm, filterKnown, filterSlack)};
|
||||
}
|
||||
}
|
||||
@ -459,8 +497,20 @@ public class DataResultFilterNode extends FilterNode {
|
||||
|
||||
@Override
|
||||
public AbstractAction visit(BlackboardArtifactNode ban) {
|
||||
return new ViewContextAction(
|
||||
NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewInDir.text"), ban);
|
||||
BlackboardArtifact artifact = ban.getArtifact();
|
||||
try {
|
||||
if ( (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) ||
|
||||
(artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) ) {
|
||||
if (artifact.hasChildren()) {
|
||||
return openChild(ban);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, MessageFormat.format("Error getting children from blackboard artifact{0}.", artifact.getArtifactID()), ex); //NON-NLS
|
||||
}
|
||||
return new ViewContextAction(
|
||||
NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewInDir.text"), ban);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -26,6 +26,7 @@ import org.sleuthkit.autopsy.datamodel.DirectoryNode;
|
||||
import org.openide.nodes.FilterNode;
|
||||
import org.openide.nodes.Node;
|
||||
import org.sleuthkit.autopsy.datamodel.AbstractAbstractFileNode;
|
||||
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
|
||||
import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
|
||||
import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel.FileNode;
|
||||
@ -36,6 +37,7 @@ import org.sleuthkit.autopsy.datamodel.SlackFileNode;
|
||||
import org.sleuthkit.autopsy.datamodel.VirtualDirectoryNode;
|
||||
import org.sleuthkit.autopsy.datamodel.VolumeNode;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.Directory;
|
||||
import org.sleuthkit.datamodel.LayoutFile;
|
||||
@ -198,7 +200,7 @@ class DirectoryTreeFilterChildren extends FilterNode.Children {
|
||||
List<Content> derivedChildren = node.getContentChildren();
|
||||
//child of a file, must be a (derived) file too
|
||||
for (Content childContent : derivedChildren) {
|
||||
if (((AbstractFile) childContent).isDir()) {
|
||||
if ((childContent instanceof AbstractFile) && ((AbstractFile) childContent).isDir()) {
|
||||
return false;
|
||||
} else {
|
||||
try {
|
||||
@ -249,6 +251,16 @@ class DirectoryTreeFilterChildren extends FilterNode.Children {
|
||||
return defaultVisit(ft);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visit(BlackboardArtifactNode bbafn) {
|
||||
// Only show Message arttifacts with children
|
||||
if ( (bbafn.getArtifact().getArtifactTypeID() == ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) ||
|
||||
(bbafn.getArtifact().getArtifactTypeID() == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) ) {
|
||||
return bbafn.hasContentChildren();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ShowItemVisitor extends DisplayableItemNodeVisitor.Default<Boolean> {
|
||||
@ -292,10 +304,23 @@ class DirectoryTreeFilterChildren extends FilterNode.Children {
|
||||
//return vdn.hasContentChildren();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean visit(FileTypesNode fileTypes) {
|
||||
return defaultVisit(fileTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visit(BlackboardArtifactNode bbafn) {
|
||||
|
||||
// Only show Message arttifacts with children
|
||||
if ( (bbafn.getArtifact().getArtifactTypeID() == ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) ||
|
||||
(bbafn.getArtifact().getArtifactTypeID() == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) ) {
|
||||
return bbafn.hasContentChildren();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -25,14 +25,17 @@ import java.util.logging.Level;
|
||||
import javax.swing.Action;
|
||||
import org.openide.nodes.FilterNode;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.openide.util.lookup.ProxyLookup;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datamodel.AbstractContentNode;
|
||||
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
|
||||
import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.RunIngestModulesAction;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.Directory;
|
||||
import org.sleuthkit.datamodel.Image;
|
||||
@ -77,7 +80,7 @@ class DirectoryTreeFilterNode extends FilterNode {
|
||||
String name = orig.getDisplayName();
|
||||
if (orig instanceof AbstractContentNode) {
|
||||
AbstractFile file = getLookup().lookup(AbstractFile.class);
|
||||
if (file != null) {
|
||||
if ((file != null) && (false == (orig instanceof BlackboardArtifactNode)) ){
|
||||
try {
|
||||
int numVisibleChildren = getVisibleChildCount(file);
|
||||
|
||||
@ -92,6 +95,15 @@ class DirectoryTreeFilterNode extends FilterNode {
|
||||
logger.log(Level.SEVERE, "Error getting children count to display for file: " + file, ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
else if (orig instanceof BlackboardArtifactNode) {
|
||||
BlackboardArtifact artifact = ((BlackboardArtifactNode) orig).getArtifact();
|
||||
try {
|
||||
int numAttachments = artifact.getChildrenCount();
|
||||
name = name + " \u200E(\u200E" + numAttachments + ")\u200E"; //NON-NLS
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error getting chidlren count for atifact: " + artifact, ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
@ -115,7 +127,7 @@ class DirectoryTreeFilterNode extends FilterNode {
|
||||
if (purgeKnownFiles || purgeSlackFiles) {
|
||||
// Purge known and/or slack files from the file count
|
||||
for (int i = 0; i < childList.size(); i++) {
|
||||
Content child = (Content) childList.get(i);
|
||||
Content child = childList.get(i);
|
||||
if (child instanceof AbstractFile) {
|
||||
AbstractFile childFile = (AbstractFile) child;
|
||||
if ((purgeKnownFiles && childFile.getKnown() == TskData.FileKnown.KNOWN)
|
||||
@ -125,6 +137,7 @@ class DirectoryTreeFilterNode extends FilterNode {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return numVisibleChildren;
|
||||
}
|
||||
|
@ -295,11 +295,15 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
|
||||
*/
|
||||
private void processEmails(List<EmailMessage> emails, AbstractFile abstractFile) {
|
||||
List<AbstractFile> derivedFiles = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
for (EmailMessage email : emails) {
|
||||
if (email.hasAttachment()) {
|
||||
derivedFiles.addAll(handleAttachments(email.getAttachments(), abstractFile));
|
||||
BlackboardArtifact msgArtifact = addArtifact(email, abstractFile);
|
||||
|
||||
if ((msgArtifact != null) && (email.hasAttachment())) {
|
||||
derivedFiles.addAll(handleAttachments(email.getAttachments(), abstractFile, msgArtifact ));
|
||||
}
|
||||
addArtifact(email, abstractFile);
|
||||
}
|
||||
|
||||
if (derivedFiles.isEmpty() == false) {
|
||||
@ -320,7 +324,7 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<AbstractFile> handleAttachments(List<EmailMessage.Attachment> attachments, AbstractFile abstractFile) {
|
||||
private List<AbstractFile> handleAttachments(List<EmailMessage.Attachment> attachments, AbstractFile abstractFile, BlackboardArtifact messageArtifact) {
|
||||
List<AbstractFile> files = new ArrayList<>();
|
||||
for (EmailMessage.Attachment attach : attachments) {
|
||||
String filename = attach.getName();
|
||||
@ -334,7 +338,7 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
|
||||
|
||||
try {
|
||||
DerivedFile df = fileManager.addDerivedFile(filename, relPath,
|
||||
size, cTime, crTime, aTime, mTime, true, abstractFile, "",
|
||||
size, cTime, crTime, aTime, mTime, true, messageArtifact, "",
|
||||
EmailParserModuleFactory.getModuleName(), EmailParserModuleFactory.getModuleVersion(), "", encodingType);
|
||||
files.add(df);
|
||||
} catch (TskCoreException ex) {
|
||||
@ -356,7 +360,8 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
|
||||
* @param abstractFile
|
||||
*/
|
||||
@Messages({"ThunderbirdMboxFileIngestModule.addArtifact.indexError.message=Failed to index email message detected artifact for keyword search."})
|
||||
private void addArtifact(EmailMessage email, AbstractFile abstractFile) {
|
||||
private BlackboardArtifact addArtifact(EmailMessage email, AbstractFile abstractFile) {
|
||||
BlackboardArtifact bbart = null;
|
||||
List<BlackboardAttribute> bbattributes = new ArrayList<>();
|
||||
String to = email.getRecipients();
|
||||
String cc = email.getCc();
|
||||
@ -414,12 +419,9 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
|
||||
if (rtf.isEmpty() == false) {
|
||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF, EmailParserModuleFactory.getModuleName(), rtf));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
try {
|
||||
BlackboardArtifact bbart;
|
||||
|
||||
bbart = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG);
|
||||
bbart.addAttributes(bbattributes);
|
||||
|
||||
@ -433,6 +435,8 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, null, ex);
|
||||
}
|
||||
|
||||
return bbart;
|
||||
}
|
||||
|
||||
void postErrorMessage(String subj, String details) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user