From 0e77b008dd6edcf6879b7b9fee85a424d5cd24ef Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 28 Jan 2022 10:00:03 -0500 Subject: [PATCH] adding host to data artifact viewers --- .../artifactviewers/Bundle.properties-MERGED | 3 ++ .../CallLogArtifactViewer.java | 22 +++++++++--- .../artifactviewers/CallLogViewData.java | 9 +++++ .../ContactArtifactViewer.java | 20 ++++++++--- .../GeneralPurposeArtifactViewer.java | 34 ++++++++++++------- 5 files changed, 66 insertions(+), 22 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/Bundle.properties-MERGED index c529a8aa9d..23afce19fb 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/Bundle.properties-MERGED @@ -8,6 +8,7 @@ CallLogArtifactViewer_label_date=Date CallLogArtifactViewer_label_direction=Direction CallLogArtifactViewer_label_duration=Duration CallLogArtifactViewer_label_from=From +CallLogArtifactViewer_label_hostName=Host CallLogArtifactViewer_label_to=To CallLogArtifactViewer_suffix_local=(Local) CallLogArtifactViewer_value_unknown=Unknown @@ -29,6 +30,7 @@ ContactArtifactViewer_heading_Source=Source # {0} - accountIdentifer ContactArtifactViewer_id_not_found_in_cr=Unable to find account(s) associated with contact {0} in the Central Repository. ContactArtifactViewer_label_datasource=Data Source +ContactArtifactViewer_label_host=Host ContactArtifactViewer_missing_account_label=Missing contact account ContactArtifactViewer_others_header=Other ContactArtifactViewer_persona_account_justification=Account found in Contact artifact @@ -65,6 +67,7 @@ GeneralPurposeArtifactViewer.details.sourceHeader=Source GeneralPurposeArtifactViewer.noFile.text=\ (no longer exists) GeneralPurposeArtifactViewer.term.label=Term GeneralPurposeArtifactViewer.unknown.text=Unknown +GeneralPurposeArtifactViewer_details_host=Host GeneralPurposeArtifactViewer_menuitem_copy=Copy MessageAccountPanel.account.justification=Account found in Message artifact MessageAccountPanel_button_create_label=Create diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java index 0830e8e6ef..33bb8d9644 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogArtifactViewer.java @@ -28,6 +28,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.logging.Level; import javax.swing.JScrollPane; @@ -36,6 +37,8 @@ import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; 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.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults; import org.sleuthkit.autopsy.coreutils.Logger; @@ -100,7 +103,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac CallLogViewData callLogViewData = null; try { callLogViewData = getCallLogViewData(artifact); - } catch (TskCoreException ex) { + } catch (NoCurrentCaseException | TskCoreException ex) { logger.log(Level.SEVERE, String.format("Error getting attributes for Calllog artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex); } List personaSearchDataList = new ArrayList<>(); @@ -115,7 +118,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac } else { currentAccountFetcher = null; } - + // repaint this.revalidate(); this.repaint(); @@ -130,7 +133,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac * * @throws TskCoreException */ - private CallLogViewData getCallLogViewData(BlackboardArtifact artifact) throws TskCoreException { + private CallLogViewData getCallLogViewData(BlackboardArtifact artifact) throws NoCurrentCaseException, TskCoreException { if (artifact == null) { return null; @@ -241,6 +244,12 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac callLogViewData.setToContactNameList(toContactNames); } + String hostName = Optional.ofNullable(Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getHostByDataSource((DataSource) dataSource)) + .map(h -> h.getName()) + .orElse(null); + + callLogViewData.setHostName(hostName); + return callLogViewData; } @@ -413,11 +422,16 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac */ @NbBundle.Messages({ "CallLogArtifactViewer_heading_Source=Source", - "CallLogArtifactViewer_label_datasource=Data Source",}) + "CallLogArtifactViewer_label_datasource=Data Source", + "CallLogArtifactViewer_label_hostName=Host"}) private void updateSourceView(CallLogViewData callLogViewData) { CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, ContentViewerDefaults.getSectionSpacing(), Bundle.CallLogArtifactViewer_heading_Source()); + CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_datasource()); CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, callLogViewData.getDataSourceName()); + + CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_hostName()); + CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, StringUtils.defaultString(callLogViewData.getHostName())); } /** diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogViewData.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogViewData.java index f7888ed7ec..16c42927be 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogViewData.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/CallLogViewData.java @@ -32,6 +32,8 @@ final class CallLogViewData { private String fromAccount = null; private String toAccount = null; + + private String hostName = null; // account identifier of the device owner, if known. // will be one of the to or from account. @@ -174,4 +176,11 @@ final class CallLogViewData { return Collections.unmodifiableList(this.fromContactNameList); } + public String getHostName() { + return hostName; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java index c65b92b8d3..449fdd9ff5 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/ContactArtifactViewer.java @@ -48,6 +48,7 @@ import org.apache.commons.lang.StringUtils; 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.centralrepository.datamodel.CentralRepoAccount; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; @@ -65,6 +66,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.InvalidAccountIDException; import org.sleuthkit.datamodel.TskCoreException; @@ -85,6 +87,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac private BlackboardArtifact contactArtifact; private String contactName; private String datasourceName; + private String hostName; private List phoneNumList = new ArrayList<>(); private List emailList = new ArrayList<>(); @@ -134,7 +137,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac if (artifact != null) { try { extractArtifactData(artifact); - } catch (TskCoreException ex) { + } catch (NoCurrentCaseException | TskCoreException ex) { logger.log(Level.SEVERE, String.format("Error getting attributes for artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex); return; } @@ -164,7 +167,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac * * @throws TskCoreException */ - private void extractArtifactData(BlackboardArtifact artifact) throws TskCoreException { + private void extractArtifactData(BlackboardArtifact artifact) throws NoCurrentCaseException, TskCoreException { this.contactArtifact = artifact; @@ -193,6 +196,10 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac } datasourceName = contactArtifact.getDataSource().getName(); + + hostName = Optional.ofNullable(Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getHostByDataSource((DataSource) contactArtifact.getDataSource())) + .map(h -> h.getName()) + .orElse(null); } /** @@ -248,7 +255,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac int prevGridWidth = contactPanelConstraints.gridwidth; contactPanelConstraints.gridwidth = 3; contactPanelConstraints.anchor = GridBagConstraints.LINE_START; - + javax.swing.JLabel contactImage = new javax.swing.JLabel(); contactImage.setIcon(getImageFromArtifact(contactArtifact)); contactImage.setText(Bundle.ContactArtifactViewer_contactImage_text()); @@ -317,11 +324,14 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac */ @NbBundle.Messages({ "ContactArtifactViewer_heading_Source=Source", - "ContactArtifactViewer_label_datasource=Data Source",}) + "ContactArtifactViewer_label_datasource=Data Source", + "ContactArtifactViewer_label_host=Host",}) private void updateSource() { CommunicationArtifactViewerHelper.addHeader(this, this.m_gridBagLayout, m_constraints, ContentViewerDefaults.getSectionSpacing(), Bundle.ContactArtifactViewer_heading_Source()); CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_label_datasource()); CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, m_constraints, datasourceName); + CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_label_host()); + CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, m_constraints, hostName); } /** @@ -350,7 +360,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac this.personaSearchStatusLabel = new javax.swing.JLabel(); personaSearchStatusLabel.setText(personaStatusLabelText); personaSearchStatusLabel.setFont(ContentViewerDefaults.getMessageFont()); - + m_constraints.gridx = 0; m_constraints.anchor = GridBagConstraints.LINE_START; diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/GeneralPurposeArtifactViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/GeneralPurposeArtifactViewer.java index e81b6705c6..35b565da50 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/GeneralPurposeArtifactViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/artifactviewers/GeneralPurposeArtifactViewer.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.contentviewers.artifactviewers; -import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.GridBagConstraints; @@ -30,13 +29,11 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.logging.Level; -import java.util.stream.Collectors; -import java.util.stream.Stream; import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; @@ -44,9 +41,10 @@ import javax.swing.JTextPane; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang3.tuple.Pair; 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.contentviewers.layout.ContentViewerDefaults; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; @@ -54,6 +52,7 @@ import org.sleuthkit.autopsy.coreutils.TimeZoneUtils; import org.sleuthkit.autopsy.discovery.ui.AbstractArtifactDetailsPanel; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.TskCoreException; /** @@ -146,7 +145,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()}); } - + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @NbBundle.Messages({"GeneralPurposeArtifactViewer.unknown.text=Unknown"}) @Override @@ -154,6 +153,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i resetComponent(); if (artifact != null) { String dataSourceName = Bundle.GeneralPurposeArtifactViewer_unknown_text(); + String hostName = Bundle.GeneralPurposeArtifactViewer_unknown_text(); String sourceFileName = Bundle.GeneralPurposeArtifactViewer_unknown_text(); Map> attributeMap = new HashMap<>(); try { @@ -167,11 +167,16 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i attributeMap.put(bba.getAttributeType().getTypeID(), attrList); } dataSourceName = artifact.getDataSource().getName(); + + hostName = Optional.ofNullable(Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getHostByDataSource((DataSource) artifact.getDataSource())) + .map(h -> h.getName()) + .orElse(null); + sourceFileName = artifact.getParent().getUniquePath(); - } catch (TskCoreException ex) { + } catch (NoCurrentCaseException | TskCoreException ex) { logger.log(Level.WARNING, "Unable to get attributes for artifact " + artifact.getArtifactID(), ex); } - updateView(artifact, attributeMap, dataSourceName, sourceFileName); + updateView(artifact, attributeMap, dataSourceName, hostName, sourceFileName); } detailsScrollPane.setViewportView(detailsPanel); detailsScrollPane.revalidate(); @@ -194,7 +199,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i gridBagConstraints.fill = GridBagConstraints.NONE; gridBagConstraints.insets = ZERO_INSETS; } - + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override public boolean isSupported(BlackboardArtifact artifact) { @@ -209,10 +214,11 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i || artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS.getTypeID() || artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_FORM_AUTOFILL.getTypeID()); } - + @NbBundle.Messages({"GeneralPurposeArtifactViewer.details.attrHeader=Details", "GeneralPurposeArtifactViewer.details.sourceHeader=Source", "GeneralPurposeArtifactViewer.details.dataSource=Data Source", + "GeneralPurposeArtifactViewer_details_host=Host", "GeneralPurposeArtifactViewer.details.file=File", "GeneralPurposeArtifactViewer.details.datesHeader=Dates"}) /** @@ -249,6 +255,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i * @param attributeMap The map of attributes that exist for the artifact. * @param dataSourceName The name of the datasource that caused the creation * of the artifact. + * @param hostName The host name. * @param sourceFilePath The path of the file that caused the creation of * the artifact. */ @@ -260,7 +267,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i "GeneralPurposeArtifactViewer.details.otherHeader=Other", "GeneralPurposeArtifactViewer.noFile.text= (no longer exists)"}) @ThreadConfined(type = ThreadConfined.ThreadType.AWT) - private void updateView(BlackboardArtifact artifact, Map> attributeMap, String dataSourceName, String sourceFilePath) { + private void updateView(BlackboardArtifact artifact, Map> attributeMap, String dataSourceName, String hostName, String sourceFilePath) { final Integer artifactTypeId = artifact.getArtifactTypeID(); if (!(artifactTypeId < 1 || artifactTypeId >= Integer.MAX_VALUE)) { JTextPane firstTextPane = addDetailsHeader(artifactTypeId); @@ -313,6 +320,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i } addHeader(Bundle.GeneralPurposeArtifactViewer_details_sourceHeader()); addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_dataSource(), dataSourceName); + addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_host(), hostName); addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_file(), sourceFilePath); // add veritcal glue at the end addPageEndGlue(); @@ -398,10 +406,10 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i headingLabel.setEditable(false); // add a blank line before the start of new section, unless it's // the first section - gridBagConstraints.insets = (gridBagConstraints.gridy == 0) + gridBagConstraints.insets = (gridBagConstraints.gridy == 0) ? FIRST_HEADER_INSETS : HEADER_INSETS; - + gridBagConstraints.gridy++; gridBagConstraints.gridx = LABEL_COLUMN;; // let the header span all of the row