5780: Context content viewer to show source of message attachments and web downloaded files.

- This includes replacing the TSK_DOWNLOAD_SOURCE artifact with TSK_ASSOCIATED_OBJECT artifact, in the RecentActivity module.
This commit is contained in:
Raman Arora 2019-11-21 13:14:25 -05:00
parent 5452d2ba02
commit 8e48ac03e6
9 changed files with 579 additions and 111 deletions

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
<Component id="jSourceNameLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jSourceTextLabel" pref="192" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace min="-2" pref="36" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="jSourceGoToResultButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jSourceNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jSourceTextLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="jSourceGoToResultButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="203" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="jSourceGoToResultButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContextViewer.jSourceGoToResultButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jSourceGoToResultButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Dialog" size="14" style="1"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContextViewer.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jSourceNameLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContextViewer.jSourceNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jSourceTextLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContextViewer.jSourceTextLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,357 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2019 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.contentviewers;
import java.awt.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import org.apache.commons.lang.StringUtils;
import org.openide.nodes.Node;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Displays additional context for the selected file, such as its source, and
* usage, if known.
*
*/
@ServiceProvider(service = DataContentViewer.class, position = 7)
@NbBundle.Messages({
"ContextViewer.title=Context Viewer",
"ContextViewer.toolTip=Displays context for selected file."
})
public final class ContextViewer extends javax.swing.JPanel implements DataContentViewer {
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(ContextViewer.class.getName());
// defines a list of artifacts that provide context for a file
private static final List<BlackboardArtifact.ARTIFACT_TYPE> SOURCE_CONTEXT_ARTIFACTS = new ArrayList<>();
static {
SOURCE_CONTEXT_ARTIFACTS.add(TSK_ASSOCIATED_OBJECT);
}
private BlackboardArtifact sourceContextArtifact;
/**
* Creates new form ContextViewer
*/
public ContextViewer() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jSourceGoToResultButton = new javax.swing.JButton();
jLabel1 = new javax.swing.JLabel();
jSourceNameLabel = new javax.swing.JLabel();
jSourceTextLabel = new javax.swing.JLabel();
org.openide.awt.Mnemonics.setLocalizedText(jSourceGoToResultButton, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jSourceGoToResultButton.text")); // NOI18N
jSourceGoToResultButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jSourceGoToResultButtonActionPerformed(evt);
}
});
jLabel1.setFont(new java.awt.Font("Dialog", 1, 14)); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jLabel1.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jSourceNameLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jSourceNameLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jSourceTextLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jSourceTextLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel1)
.addGroup(layout.createSequentialGroup()
.addGap(6, 6, 6)
.addComponent(jSourceNameLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 192, Short.MAX_VALUE)))
.addGap(36, 36, 36))
.addGroup(layout.createSequentialGroup()
.addComponent(jSourceGoToResultButton)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jSourceNameLabel)
.addComponent(jSourceTextLabel))
.addGap(18, 18, 18)
.addComponent(jSourceGoToResultButton)
.addGap(0, 203, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
private void jSourceGoToResultButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jSourceGoToResultButtonActionPerformed
final DirectoryTreeTopComponent dtc = DirectoryTreeTopComponent.findInstance();
// Navigate to the source context artifact.
if (sourceContextArtifact != null) {
dtc.viewArtifact(sourceContextArtifact);
}
}//GEN-LAST:event_jSourceGoToResultButtonActionPerformed
@Override
public void setNode(Node selectedNode) {
if ((selectedNode == null) || (!isSupported(selectedNode))) {
resetComponent();
return;
}
AbstractFile file = selectedNode.getLookup().lookup(AbstractFile.class);
try {
populateSourceContextData(file);
} catch (NoCurrentCaseException | TskCoreException ex) {
logger.log(Level.SEVERE, "Exception displaying context for file {0}", file); //NON-NLS
}
}
@Override
public String getTitle() {
return Bundle.ContextViewer_title();
}
@Override
public String getToolTip() {
return Bundle.ContextViewer_toolTip();
}
@Override
public DataContentViewer createInstance() {
return new ContextViewer();
}
@Override
public Component getComponent() {
return this;
}
@Override
public void resetComponent() {
setSourceName("");
setSourceText("");
}
@Override
public boolean isSupported(Node node) {
// check if the node has an abstract file and the file has any context defining artifacts.
if (node.getLookup().lookup(AbstractFile.class) != null) {
AbstractFile abstractFile = node.getLookup().lookup(AbstractFile.class);
for (BlackboardArtifact.ARTIFACT_TYPE artifactType : SOURCE_CONTEXT_ARTIFACTS) {
List<BlackboardArtifact> artifactsList;
try {
artifactsList = abstractFile.getArtifacts(artifactType);
if (!artifactsList.isEmpty()) {
return true;
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Exception while looking up context artifacts for file {0}", abstractFile); //NON-NLS
}
}
}
return false;
}
@Override
public int isPreferred(Node node) {
return 1;
}
private void populateSourceContextData(AbstractFile sourceFile) throws NoCurrentCaseException, TskCoreException {
SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
// Check for all context artifacts
boolean foundASource = false;
for (BlackboardArtifact.ARTIFACT_TYPE artifactType : SOURCE_CONTEXT_ARTIFACTS) {
List<BlackboardArtifact> artifactsList = tskCase.getBlackboardArtifacts(artifactType, sourceFile.getId());
if (!artifactsList.isEmpty()) {
foundASource = true;
}
for (BlackboardArtifact contextArtifact : artifactsList) {
addSourceEntry(contextArtifact);
}
}
if (foundASource == false) {
setSourceName("Unknown");
showSourceText(false);
}
}
@NbBundle.Messages({
"ContextViewer.attachmentSource=Attached to: ",
"ContextViewer.downloadSource=Downloaded from: "
})
private void addSourceEntry(BlackboardArtifact artifact) throws TskCoreException {
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT.getTypeID() == artifact.getArtifactTypeID()) {
BlackboardAttribute associatedArtifactAttribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
if (associatedArtifactAttribute != null) {
long artifactId = associatedArtifactAttribute.getValueLong();
BlackboardArtifact associatedArtifact = artifact.getSleuthkitCase().getBlackboardArtifact(artifactId);
//save the artifact id for "Go to Result" button
sourceContextArtifact = associatedArtifact;
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == associatedArtifact.getArtifactTypeID()
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == associatedArtifact.getArtifactTypeID()) {
setSourceName(Bundle.ContextViewer_attachmentSource());
setSourceText(msgArtifactToAbbreiviatedString(associatedArtifact));
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == associatedArtifact.getArtifactTypeID()
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == associatedArtifact.getArtifactTypeID()) {
setSourceName(Bundle.ContextViewer_downloadSource());
setSourceText(webDownloadArtifactToString(associatedArtifact));
}
}
}
}
private void setSourceName(String nameLabel) {
jSourceNameLabel.setText(nameLabel);
}
private void setSourceText(String text) {
jSourceTextLabel.setText(text);
showSourceText(true);
}
private void showSourceText(boolean isVisible) {
jSourceTextLabel.setVisible(isVisible);
}
private String webDownloadArtifactToString(BlackboardArtifact artifact) throws TskCoreException {
StringBuilder sb = new StringBuilder(1024);
Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == artifact.getArtifactTypeID()
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == artifact.getArtifactTypeID()) {
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL, attributesMap, "URL");
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED, attributesMap, "On");
}
return sb.toString();
}
private String msgArtifactToAbbreiviatedString(BlackboardArtifact artifact) throws TskCoreException {
StringBuilder sb = new StringBuilder(1024);
Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == artifact.getArtifactTypeID()) {
sb.append("Message ");
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM, attributesMap, "From");
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO, attributesMap, "To");
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, "On");
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == artifact.getArtifactTypeID()) {
sb.append("Email ");
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM, attributesMap, "From");
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO, attributesMap, "To");
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT, attributesMap, "On");
}
return sb.toString();
}
private void appendAttributeString(StringBuilder sb, BlackboardAttribute.ATTRIBUTE_TYPE attribType,
Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap, String prependStr) {
BlackboardAttribute attribute = attributesMap.get(attribType);
if (attribute != null) {
String attrVal = attribute.getDisplayString();
if (!StringUtils.isEmpty(attrVal)) {
if (!StringUtils.isEmpty(prependStr)) {
sb.append(prependStr).append(" ");
}
sb.append(StringUtils.abbreviate(attrVal, 200)).append(" ");
}
}
}
private String getAttribNameValue(BlackboardAttribute.ATTRIBUTE_TYPE attribType, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap) {
BlackboardAttribute attribute = attributesMap.get(attribType);
if (attribute != null) {
return String.format("%s : %s", attribType.getDisplayName(), attribute.getDisplayString());
}
return null;
}
private Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> getAttributesMap(BlackboardArtifact artifact) throws TskCoreException {
Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributeMap = new HashMap<>();
List<BlackboardAttribute> attributeList = artifact.getAttributes();
for (BlackboardAttribute attribute : attributeList) {
BlackboardAttribute.ATTRIBUTE_TYPE type = BlackboardAttribute.ATTRIBUTE_TYPE.fromID(attribute.getAttributeType().getTypeID());
attributeMap.put(type, attribute);
}
return attributeMap;
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel jLabel1;
private javax.swing.JButton jSourceGoToResultButton;
private javax.swing.JLabel jSourceNameLabel;
private javax.swing.JLabel jSourceTextLabel;
// End of variables declaration//GEN-END:variables
}

View File

@ -191,12 +191,21 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
} }
try { try {
List<BlackboardArtifact> sourceArtifacts = file.getArtifacts(ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE); List<BlackboardArtifact> associatedObjectArtifacts = file.getArtifacts(ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
if (!sourceArtifacts.isEmpty()) { if (!associatedObjectArtifacts.isEmpty()) {
BlackboardArtifact artifact = sourceArtifacts.get(0); BlackboardArtifact artifact = associatedObjectArtifacts.get(0);
BlackboardAttribute urlAttr = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_URL)); BlackboardAttribute associatedArtifactAttribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
if (urlAttr != null) { if (associatedArtifactAttribute != null) {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.downloadSource"), urlAttr.getValueString()); long artifactId = associatedArtifactAttribute.getValueLong();
BlackboardArtifact associatedArtifact = artifact.getSleuthkitCase().getBlackboardArtifact(artifactId);
if (associatedArtifact != null &&
((associatedArtifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()) ||
(associatedArtifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())) ) {
BlackboardAttribute urlAttr = associatedArtifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_URL));
if (urlAttr != null) {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.downloadSource"), urlAttr.getValueString());
}
}
} }
} }
} catch (TskCoreException ex) { } catch (TskCoreException ex) {

View File

@ -238,8 +238,8 @@ public class ExtractedContent implements AutopsyVisitableItem {
doNotShow.add(new BlackboardArtifact.Type(TSK_INTERESTING_ARTIFACT_HIT)); doNotShow.add(new BlackboardArtifact.Type(TSK_INTERESTING_ARTIFACT_HIT));
doNotShow.add(new BlackboardArtifact.Type(TSK_ACCOUNT)); doNotShow.add(new BlackboardArtifact.Type(TSK_ACCOUNT));
doNotShow.add(new BlackboardArtifact.Type(TSK_DATA_SOURCE_USAGE)); doNotShow.add(new BlackboardArtifact.Type(TSK_DATA_SOURCE_USAGE));
doNotShow.add(new BlackboardArtifact.Type(TSK_DOWNLOAD_SOURCE)); //doNotShow.add(new BlackboardArtifact.Type(TSK_DOWNLOAD_SOURCE));
doNotShow.add(new BlackboardArtifact.Type(TSK_ASSOCIATED_OBJECT)); //doNotShow.add(new BlackboardArtifact.Type(TSK_ASSOCIATED_OBJECT));
} }
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> { private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {

View File

@ -554,22 +554,24 @@ class Chrome extends Extract {
RecentActivityExtracterModuleFactory.getModuleName(), RecentActivityExtracterModuleFactory.getModuleName(),
NbBundle.getMessage(this.getClass(), "Chrome.moduleName"))); NbBundle.getMessage(this.getClass(), "Chrome.moduleName")));
BlackboardArtifact bbart = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadFile, bbattributes); BlackboardArtifact webDownloadArtifact = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadFile, bbattributes);
if (bbart != null) { if (webDownloadArtifact != null) {
bbartifacts.add(bbart); bbartifacts.add(webDownloadArtifact);
}
// find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact.
// find the downloaded file and create a TSK_DOWNLOAD_SOURCE for it.. try {
try { for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(fullPath), FilenameUtils.getPath(fullPath))) {
for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(fullPath), FilenameUtils.getPath(fullPath))) { BlackboardArtifact associatedObjectArtifact = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
BlackboardArtifact downloadSourceArt = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE); associatedObjectArtifact.addAttribute(
downloadSourceArt.addAttributes(createDownloadSourceAttributes(result.get("url").toString())); new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
RecentActivityExtracterModuleFactory.getModuleName(), webDownloadArtifact.getArtifactID()));
bbartifacts.add(downloadSourceArt);
break; bbartifacts.add(associatedObjectArtifact);
break;
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error creating associated object artifact for file '%s'", fullPath), ex); //NON-NLS
} }
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error creating download source artifact for file '%s'", fullPath), ex); //NON-NLS
} }
} }

View File

@ -380,12 +380,12 @@ final class ChromeCacheExtractor {
* Extracts the files if needed and adds as derived files, creates artifacts * Extracts the files if needed and adds as derived files, creates artifacts
* *
* @param cacheEntryAddress cache entry address * @param cacheEntryAddress cache entry address
* @param sourceArtifacts any source artifacts created are added to this collection * @param associatedObjectArtifacts any associated object artifacts created are added to this collection
* @param webCacheArtifacts any web cache artifacts created are added to this collection * @param webCacheArtifacts any web cache artifacts created are added to this collection
* *
* @return Optional derived file, is a derived file is added for the given entry * @return Optional derived file, is a derived file is added for the given entry
*/ */
private List<DerivedFile> processCacheEntry(CacheAddress cacheEntryAddress, Collection<BlackboardArtifact> sourceArtifacts, Collection<BlackboardArtifact> webCacheArtifacts ) throws TskCoreException, IngestModuleException { private List<DerivedFile> processCacheEntry(CacheAddress cacheEntryAddress, Collection<BlackboardArtifact> associatedObjectArtifacts, Collection<BlackboardArtifact> webCacheArtifacts ) throws TskCoreException, IngestModuleException {
List<DerivedFile> derivedFiles = new ArrayList<>(); List<DerivedFile> derivedFiles = new ArrayList<>();
@ -437,10 +437,6 @@ final class ChromeCacheExtractor {
moduleName, moduleName,
cacheEntry.getHTTPHeaders()); cacheEntry.getHTTPHeaders());
Collection<BlackboardAttribute> sourceArtifactAttributes = new ArrayList<>();
sourceArtifactAttributes.add(urlAttr);
sourceArtifactAttributes.add(createTimeAttr);
Collection<BlackboardAttribute> webCacheAttributes = new ArrayList<>(); Collection<BlackboardAttribute> webCacheAttributes = new ArrayList<>();
webCacheAttributes.add(urlAttr); webCacheAttributes.add(urlAttr);
webCacheAttributes.add(createTimeAttr); webCacheAttributes.add(createTimeAttr);
@ -450,12 +446,7 @@ final class ChromeCacheExtractor {
// add artifacts to the f_XXX file // add artifacts to the f_XXX file
if (dataSegment.isInExternalFile() ) { if (dataSegment.isInExternalFile() ) {
try { try {
BlackboardArtifact sourceArtifact = cachedFileAbstractFile.get().newArtifact(ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE);
if (sourceArtifact != null) {
sourceArtifact.addAttributes(sourceArtifactAttributes);
sourceArtifacts.add(sourceArtifact);
}
BlackboardArtifact webCacheArtifact = cacheEntryFile.get().getAbstractFile().newArtifact(ARTIFACT_TYPE.TSK_WEB_CACHE); BlackboardArtifact webCacheArtifact = cacheEntryFile.get().getAbstractFile().newArtifact(ARTIFACT_TYPE.TSK_WEB_CACHE);
if (webCacheArtifact != null) { if (webCacheArtifact != null) {
webCacheArtifact.addAttributes(webCacheAttributes); webCacheArtifact.addAttributes(webCacheAttributes);
@ -469,6 +460,14 @@ final class ChromeCacheExtractor {
moduleName, cachedFileAbstractFile.get().getId())); moduleName, cachedFileAbstractFile.get().getId()));
webCacheArtifacts.add(webCacheArtifact); webCacheArtifacts.add(webCacheArtifact);
BlackboardArtifact associatedObjectArtifact = cachedFileAbstractFile.get().newArtifact(ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
if (associatedObjectArtifact != null) {
associatedObjectArtifact.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
moduleName, webCacheArtifact.getArtifactID()));
associatedObjectArtifacts.add(associatedObjectArtifact);
}
} }
if (isBrotliCompressed) { if (isBrotliCompressed) {
@ -497,12 +496,7 @@ final class ChromeCacheExtractor {
"", "",
TskData.EncodingType.NONE); TskData.EncodingType.NONE);
BlackboardArtifact sourceArtifact = derivedFile.newArtifact(ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE);
if (sourceArtifact != null) {
sourceArtifact.addAttributes(sourceArtifactAttributes);
sourceArtifacts.add(sourceArtifact);
}
BlackboardArtifact webCacheArtifact = cacheEntryFile.get().getAbstractFile().newArtifact(ARTIFACT_TYPE.TSK_WEB_CACHE); BlackboardArtifact webCacheArtifact = cacheEntryFile.get().getAbstractFile().newArtifact(ARTIFACT_TYPE.TSK_WEB_CACHE);
if (webCacheArtifact != null) { if (webCacheArtifact != null) {
webCacheArtifact.addAttributes(webCacheAttributes); webCacheArtifact.addAttributes(webCacheAttributes);
@ -516,6 +510,14 @@ final class ChromeCacheExtractor {
moduleName, derivedFile.getId())); moduleName, derivedFile.getId()));
webCacheArtifacts.add(webCacheArtifact); webCacheArtifacts.add(webCacheArtifact);
BlackboardArtifact associatedObjectArtifact = derivedFile.newArtifact(ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
if (associatedObjectArtifact != null) {
associatedObjectArtifact.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
moduleName, webCacheArtifact.getArtifactID()));
associatedObjectArtifacts.add(associatedObjectArtifact);
}
} }
if (isBrotliCompressed) { if (isBrotliCompressed) {

View File

@ -50,6 +50,7 @@ import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.autopsy.recentactivity.BinaryCookieReader.Cookie; import org.sleuthkit.autopsy.recentactivity.BinaryCookieReader.Cookie;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
@ -637,15 +638,17 @@ final class ExtractSafari extends Extract {
time = date.getDate().getTime(); time = date.getDate().getTime();
} }
BlackboardArtifact bbart = origFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD); BlackboardArtifact webDownloadArtifact = origFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD);
bbart.addAttributes(this.createDownloadAttributes(path, pathID, url, time, NetworkUtils.extractDomain(url), getName())); webDownloadArtifact.addAttributes(this.createDownloadAttributes(path, pathID, url, time, NetworkUtils.extractDomain(url), getName()));
bbartifacts.add(bbart); bbartifacts.add(webDownloadArtifact);
// find the downloaded file and create a TSK_DOWNLOAD_SOURCE for it. // find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact.
for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(path), FilenameUtils.getPath(path))) { for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(path), FilenameUtils.getPath(path))) {
BlackboardArtifact downloadSourceArt = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE); BlackboardArtifact associatedObjectArtifact = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
downloadSourceArt.addAttributes(createDownloadSourceAttributes(url)); associatedObjectArtifact.addAttribute(
bbartifacts.add(downloadSourceArt); new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
RecentActivityExtracterModuleFactory.getModuleName(), webDownloadArtifact.getArtifactID()));
bbartifacts.add(associatedObjectArtifact);
break; break;
} }

View File

@ -36,9 +36,11 @@ import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
import org.sleuthkit.autopsy.ingest.IngestJobContext; import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE;
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN;
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION;
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID;
@ -94,7 +96,7 @@ final class ExtractZoneIdentifier extends Extract {
return; return;
} }
Collection<BlackboardArtifact> sourceArtifacts = new ArrayList<>(); Collection<BlackboardArtifact> associatedObjectArtifacts = new ArrayList<>();
Collection<BlackboardArtifact> downloadArtifacts = new ArrayList<>(); Collection<BlackboardArtifact> downloadArtifacts = new ArrayList<>();
for (AbstractFile zoneFile : zoneFiles) { for (AbstractFile zoneFile : zoneFiles) {
@ -104,7 +106,7 @@ final class ExtractZoneIdentifier extends Extract {
} }
try { try {
processZoneFile(context, dataSource, zoneFile, sourceArtifacts, downloadArtifacts, knownPathIDs); processZoneFile(context, dataSource, zoneFile, associatedObjectArtifacts, downloadArtifacts, knownPathIDs);
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
addErrorMessage(Bundle.ExtractZone_process_errMsg()); addErrorMessage(Bundle.ExtractZone_process_errMsg());
String message = String.format("Failed to process zone identifier file %s", zoneFile.getName()); //NON-NLS String message = String.format("Failed to process zone identifier file %s", zoneFile.getName()); //NON-NLS
@ -112,23 +114,23 @@ final class ExtractZoneIdentifier extends Extract {
} }
} }
postArtifacts(sourceArtifacts); postArtifacts(associatedObjectArtifacts);
postArtifacts(downloadArtifacts); postArtifacts(downloadArtifacts);
} }
/** /**
* Process a single Zone Identifier file. * Process a single Zone Identifier file.
* *
* @param context IngetJobContext * @param context IngetJobContext
* @param dataSource Content * @param dataSource Content
* @param zoneFile Zone Indentifier file * @param zoneFile Zone Indentifier file
* @param sourceArtifacts List for TSK_DOWNLOAD_SOURCE artifacts * @param associatedObjectArtifacts List for TSK_ASSOCIATED_OBJECT artifacts
* @param downloadArtifacts List for TSK_WEB_DOWNLOAD aritfacts * @param downloadArtifacts List for TSK_WEB_DOWNLOAD artifacts
* *
* @throws TskCoreException * @throws TskCoreException
*/ */
private void processZoneFile(IngestJobContext context, Content dataSource, private void processZoneFile(IngestJobContext context, Content dataSource,
AbstractFile zoneFile, Collection<BlackboardArtifact> sourceArtifacts, AbstractFile zoneFile, Collection<BlackboardArtifact> associatedObjectArtifacts,
Collection<BlackboardArtifact> downloadArtifacts, Collection<BlackboardArtifact> downloadArtifacts,
Set<Long> knownPathIDs) throws TskCoreException { Set<Long> knownPathIDs) throws TskCoreException {
@ -155,16 +157,16 @@ final class ExtractZoneIdentifier extends Extract {
BlackboardArtifact downloadBba = createDownloadArtifact(zoneFile, zoneInfo); BlackboardArtifact downloadBba = createDownloadArtifact(zoneFile, zoneInfo);
if (downloadBba != null) { if (downloadBba != null) {
downloadArtifacts.add(downloadBba); downloadArtifacts.add(downloadBba);
// create a TSK_ASSOCIATED_OBJECT for the downloaded file, associating it with the TSK_WEB_DOWNLOAD artifact.
if (downloadFile.getArtifactsCount(TSK_ASSOCIATED_OBJECT) == 0) {
BlackboardArtifact associatedObjectBba = createAssociatedObjectArtifact(downloadFile, downloadBba);
if (associatedObjectBba != null) {
associatedObjectArtifacts.add(associatedObjectBba);
}
}
} }
} }
// check if download has a child TSK_DOWNLOAD_SOURCE artifact, if not create one
if (downloadFile.getArtifactsCount(TSK_DOWNLOAD_SOURCE) == 0) {
BlackboardArtifact sourceBba = createDownloadSourceArtifact(downloadFile, zoneInfo);
if (sourceBba != null) {
sourceArtifacts.add(sourceBba);
}
}
} }
} }
@ -203,33 +205,26 @@ final class ExtractZoneIdentifier extends Extract {
} }
/** /**
* Create a Download Source Artifact for the given ZoneIdentifierInfo * Create a Associated Object Artifact for the given ZoneIdentifierInfo
* object. * object.
* *
* @param downloadFile AbstractFile representing the file downloaded, not * @param downloadFile AbstractFile representing the file downloaded, not
* the zone identifier file. * the zone identifier file.
* @param zoneInfo Zone identifier file wrapper object * @param downloadBba TSK_WEB_DOWNLOAD artifact to associate with.
* *
* @return TSK_DOWNLOAD_SOURCE object for given parameters * @return TSK_ASSOCIATED_OBJECT artifact.
*/ */
private BlackboardArtifact createDownloadSourceArtifact(AbstractFile downloadFile, ZoneIdentifierInfo zoneInfo) { private BlackboardArtifact createAssociatedObjectArtifact(AbstractFile downloadFile, BlackboardArtifact downloadBba) {
Collection<BlackboardAttribute> bbattributes = new ArrayList<>(); Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
bbattributes.addAll(Arrays.asList( bbattributes.addAll(Arrays.asList(
new BlackboardAttribute(TSK_URL, new BlackboardAttribute(TSK_ASSOCIATED_ARTIFACT,
RecentActivityExtracterModuleFactory.getModuleName(), RecentActivityExtracterModuleFactory.getModuleName(),
StringUtils.defaultString(zoneInfo.getURL(), "")), downloadBba.getArtifactID())
));
new BlackboardAttribute(TSK_DOMAIN,
RecentActivityExtracterModuleFactory.getModuleName(),
(zoneInfo.getURL() != null) ? NetworkUtils.extractDomain(zoneInfo.getURL()) : ""),
new BlackboardAttribute(TSK_LOCATION,
RecentActivityExtracterModuleFactory.getModuleName(),
StringUtils.defaultString(zoneInfo.getZoneIdAsString(), "")))); //NON-NLS
return createArtifactWithAttributes(TSK_DOWNLOAD_SOURCE, downloadFile, bbattributes); return createArtifactWithAttributes(TSK_ASSOCIATED_OBJECT, downloadFile, bbattributes);
} }
/** /**

View File

@ -544,22 +544,25 @@ class Firefox extends Extract {
domain)); //NON-NLS domain)); //NON-NLS
} }
BlackboardArtifact bbart = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes); BlackboardArtifact webDownloadArtifact = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
if (bbart != null) { if (webDownloadArtifact != null) {
bbartifacts.add(bbart); bbartifacts.add(webDownloadArtifact);
}
// find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact.
// find the downloaded file and create a TSK_DOWNLOAD_SOURCE for it. try {
try { for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) {
for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) { BlackboardArtifact associatedObjectArtifact = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
BlackboardArtifact downloadSourceArt = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE); associatedObjectArtifact.addAttribute(
downloadSourceArt.addAttributes(createDownloadSourceAttributes(source)); new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
bbartifacts.add(downloadSourceArt); RecentActivityExtracterModuleFactory.getModuleName(), webDownloadArtifact.getArtifactID()));
break;
bbartifacts.add(associatedObjectArtifact);
break;
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error creating associated object artifact for file '%s'",
downloadedFilePath), ex); //NON-NLS
} }
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error creating download source artifact for file '%s'",
downloadedFilePath), ex); //NON-NLS
} }
} }
if (errors > 0) { if (errors > 0) {
@ -681,22 +684,24 @@ class Firefox extends Extract {
RecentActivityExtracterModuleFactory.getModuleName(), domain)); //NON-NLS RecentActivityExtracterModuleFactory.getModuleName(), domain)); //NON-NLS
} }
BlackboardArtifact bbart = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes); BlackboardArtifact webDownloadArtifact = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
if (bbart != null) { if (webDownloadArtifact != null) {
bbartifacts.add(bbart); bbartifacts.add(webDownloadArtifact);
}
// find the downloaded file and create a TSK_DOWNLOAD_SOURCE for it. // find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact.
try { try {
for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) { for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) {
BlackboardArtifact downloadSourceArt = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE); BlackboardArtifact associatedObjectArtifact = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
downloadSourceArt.addAttributes(createDownloadSourceAttributes(url)); associatedObjectArtifact.addAttribute(
bbartifacts.add(downloadSourceArt); new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
break; RecentActivityExtracterModuleFactory.getModuleName(), webDownloadArtifact.getArtifactID()));
bbartifacts.add(associatedObjectArtifact);
break;
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error creating associated object artifact for file '%s'",
downloadedFilePath), ex); //NON-NLS
} }
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error creating download source artifact for file '%s'",
downloadedFilePath), ex); //NON-NLS
} }
} }
if (errors > 0) { if (errors > 0) {