7084 resolve merge conflicts

This commit is contained in:
William Schaefer
2020-12-28 10:24:31 -05:00
18 changed files with 379 additions and 145 deletions
@@ -52,9 +52,11 @@ import javax.swing.JPanel;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDateTime;
import org.openide.nodes.Node;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.casemodule.Case;
@@ -76,6 +78,7 @@ import org.sleuthkit.datamodel.TskException;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
/**
* View correlation results from other cases
@@ -466,11 +469,16 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
if (bbArtifact != null && CentralRepository.isEnabled()) {
ret.addAll(CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact));
}
boolean isSupported = false;
try {
isSupported = this.file != null && this.file.getSize() > 0 && isDownloadParentSupported(node);
} catch (TskCoreException ex) {
LOGGER.log(Level.WARNING, ex.getMessage(), ex);
}
// we can correlate based on the MD5 if it is enabled
if (this.file != null && CentralRepository.isEnabled() && this.file.getSize() > 0) {
if (isSupported && CentralRepository.isEnabled()) {
try {
List<CorrelationAttributeInstance.Type> artifactTypes = CentralRepository.getInstance().getDefinedCorrelationTypes();
String md5 = this.file.getMd5Hash();
if (md5 != null && !md5.isEmpty() && null != artifactTypes && !artifactTypes.isEmpty()) {
@@ -498,7 +506,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
LOGGER.log(Level.SEVERE, "Error connecting to DB", ex); // NON-NLS
}
// If EamDb not enabled, get the Files default correlation type to allow Other Occurances to be enabled.
} else if (this.file != null && this.file.getSize() > 0) {
} else if (isSupported) {
String md5 = this.file.getMd5Hash();
if (md5 != null && !md5.isEmpty()) {
try {
@@ -517,10 +525,39 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
}
}
}
return ret;
}
/**
* Private helper method to check if the node is an TSK_WEB_DOWNLOAD or
* TSK_WEB_CACHE artifact and if it is, if the file reflects the parent file
* or the downloaded file.
*
* @param node The node to check support for.
*
* @return False if the node is for a Web Cache or a Web Download artifact,
* and that artifact's content file is it's parent.
*
* @throws TskCoreException Unable to retrieve the parent of the artifact in
* this node.
*/
private boolean isDownloadParentSupported(Node node) throws TskCoreException {
if (node instanceof BlackboardArtifactNode) {
BlackboardArtifact theArtifact = ((BlackboardArtifactNode) node).getArtifact();
try {
//disable the content viewer when a download or cached file does not exist instead of displaying its parent
if ((theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
|| theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())
&& this.file.getId() == theArtifact.getParent().getId()) {
return false;
}
} catch (TskCoreException ex) {
throw new TskCoreException(String.format("Error getting parent of artifact with type %s and objID = %d can not confirm content with name %s and objId = %d is not the parent. Other occurences will not correlate on the file.", theArtifact.getArtifactTypeName(), theArtifact.getObjectID(), this.file.getName(), this.file.getId()), ex);
}
}
return true;
}
@Messages({"DataContentViewerOtherCases.earliestCaseNotAvailable= Not Enabled."})
/**
* Gets the list of Eam Cases and determines the earliest case creation
@@ -701,11 +738,16 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
this.file = this.getAbstractFileFromNode(node);
if (CentralRepository.isEnabled()) {
return !getCorrelationAttributesFromNode(node).isEmpty();
} else {
return this.file != null
&& this.file.getSize() > 0
&& ((this.file.getMd5Hash() != null) && (!this.file.getMd5Hash().isEmpty()));
} else if (this.file == null || this.file.getSize() <= 0 || StringUtils.isBlank(file.getMd5Hash())) {
return false;
}
boolean isSupported = false;
try {
isSupported = isDownloadParentSupported(node);
} catch (TskCoreException ex) {
LOGGER.log(Level.WARNING, ex.getMessage(), ex);
}
return isSupported;
}
@Override
@@ -8,6 +8,9 @@
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
</SyntheticProperties>
<Events>
<EventHandler event="windowOpened" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="formWindowOpened"/>
</Events>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
@@ -22,6 +22,7 @@ import java.awt.Component;
import java.util.logging.Level;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import org.openide.util.NbBundle;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
@@ -38,6 +39,8 @@ public class PersonaDetailsDialog extends JDialog {
private static final Logger logger = Logger.getLogger(PersonaDetailsDialog.class.getName());
private final PersonaDetailsDialogCallback callback;
private String popupMessageOnStartup = "";
@NbBundle.Messages({
"PersonaDetailsDialogCreateTitle=Create Persona",
@@ -91,6 +94,11 @@ public class PersonaDetailsDialog extends JDialog {
pdp = new org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowOpened(java.awt.event.WindowEvent evt) {
formWindowOpened(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(cancelBtn, org.openide.util.NbBundle.getMessage(PersonaDetailsDialog.class, "PersonaDetailsDialog.cancelBtn.text")); // NOI18N
cancelBtn.setMaximumSize(new java.awt.Dimension(79, 23));
@@ -159,10 +167,20 @@ public class PersonaDetailsDialog extends JDialog {
dispose();
}//GEN-LAST:event_cancelBtnActionPerformed
private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened
if(!popupMessageOnStartup.isEmpty()) {
JOptionPane.showMessageDialog(this, popupMessageOnStartup, "Persona Details", JOptionPane.INFORMATION_MESSAGE);
}
}//GEN-LAST:event_formWindowOpened
public PersonaDetailsPanel getDetailsPanel() {
return this.pdp;
}
public void setStartupPopupMessage(String message) {
popupMessageOnStartup = message;
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton cancelBtn;
private javax.swing.JScrollPane jScrollPane1;
@@ -22,6 +22,9 @@
-->
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Events>
<EventHandler event="componentShown" listener="java.awt.event.ComponentListener" parameters="java.awt.event.ComponentEvent" handler="formComponentShown"/>
</Events>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
@@ -225,6 +225,10 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
void addEditExistingAlias(PersonaAlias alias, String justification, Persona.Confidence confidence) {
aliasesToEdit.put(alias, new PAlias(alias.getAlias(), justification, confidence));
}
PersonaDetailsMode getMode() {
return mode;
}
/**
* A data bucket class for yet-to-be-created PersonaAccount
@@ -384,6 +388,12 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
casesTablePane = new javax.swing.JScrollPane();
casesTable = new javax.swing.JTable();
addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentShown(java.awt.event.ComponentEvent evt) {
formComponentShown(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(examinerLbl, org.openide.util.NbBundle.getMessage(PersonaDetailsPanel.class, "PersonaDetailsPanel.examinerLbl.text")); // NOI18N
examinerField.setEditable(false);
@@ -622,6 +632,10 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel {
);
}// </editor-fold>//GEN-END:initComponents
private void formComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentShown
}//GEN-LAST:event_formComponentShown
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel accountsLbl;
private javax.swing.JTable accountsTable;
@@ -28,8 +28,11 @@ import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Generic Application content viewer
@@ -37,11 +40,11 @@ import org.sleuthkit.datamodel.AbstractFile;
@ServiceProvider(service = DataContentViewer.class, position = 3)
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
public class FileViewer extends javax.swing.JPanel implements DataContentViewer {
private static final int CONFIDENCE_LEVEL = 5;
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(FileViewer.class.getName());
private final Map<String, FileTypeViewer> mimeTypeToViewerMap = new HashMap<>();
// TBD: This hardcoded list of viewers should be replaced with a dynamic lookup
@@ -53,7 +56,7 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
new WindowsRegistryViewer(),
new PDFViewer()
};
private FileTypeViewer lastViewer;
/**
@@ -71,9 +74,9 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
}
});
}
initComponents();
LOGGER.log(Level.INFO, "Created ApplicationContentViewer instance: {0}", this); //NON-NLS
}
@@ -82,8 +85,7 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
*
* @param file
*
* @return FileTypeViewer, null if no known content viewer supports the
* file
* @return FileTypeViewer, null if no known content viewer supports the file
*/
private FileTypeViewer getSupportingViewer(AbstractFile file) {
FileTypeViewer viewer = mimeTypeToViewerMap.get(file.getMIMEType());
@@ -110,18 +112,18 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
// End of variables declaration//GEN-END:variables
@Override
public void setNode(Node selectedNode) {
resetComponent();
if (selectedNode == null) {
if (selectedNode == null || !isSupported(selectedNode)) {
return;
}
AbstractFile file = selectedNode.getLookup().lookup(AbstractFile.class);
if ((file == null) || (file.isDir())) {
return;
}
String mimeType = file.getMIMEType();
if (Strings.isNullOrEmpty(mimeType)) {
LOGGER.log(Level.INFO, "Mimetype not known for file: {0}", file.getName()); //NON-NLS
@@ -133,67 +135,81 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
return;
}
}
if (mimeType.equalsIgnoreCase("application/octet-stream")) {
return;
} else {
FileTypeViewer viewer = getSupportingViewer(file);
if (viewer != null) {
lastViewer = viewer;
viewer.setFile(file);
this.removeAll();
this.add(viewer.getComponent());
this.validate();
}
}
}
@Override
@NbBundle.Messages("ApplicationContentViewer.title=Application")
public String getTitle() {
return Bundle.ApplicationContentViewer_title();
}
@Override
@NbBundle.Messages("ApplicationContentViewer.toolTip=Displays file contents.")
public String getToolTip() {
return Bundle.ApplicationContentViewer_toolTip();
}
@Override
public DataContentViewer createInstance() {
return new FileViewer();
}
@Override
public Component getComponent() {
return this;
}
@Override
public void resetComponent() {
if (lastViewer != null) {
lastViewer.resetComponent();
}
this.removeAll();
lastViewer = null;
}
@Override
public boolean isSupported(Node node) {
if (node == null) {
return false;
}
AbstractFile aFile = node.getLookup().lookup(AbstractFile.class);
if ((aFile == null) || (aFile.isDir())) {
return false;
}
if (node instanceof BlackboardArtifactNode) {
BlackboardArtifact theArtifact = ((BlackboardArtifactNode) node).getArtifact();
//disable the content viewer when a download or cached file does not exist instead of displaying its parent
try {
if ((theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
|| theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())
&& aFile.getId() == theArtifact.getParent().getId()) {
return false;
}
} catch (TskCoreException ex) {
LOGGER.log(Level.WARNING, String.format("Error getting parent of artifact with type %s and objID = %d can not confirm file with name %s and objId = %d is not the parent. File content viewer will not be supported.",
theArtifact.getArtifactTypeName(), theArtifact.getObjectID(), aFile.getName(), aFile.getId()), ex);
return false;
}
}
String mimeType = aFile.getMIMEType();
if (Strings.isNullOrEmpty(mimeType)) {
LOGGER.log(Level.INFO, "Mimetype not known for file: {0}", aFile.getName()); //NON-NLS
@@ -205,20 +221,20 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
return false;
}
}
if (mimeType.equalsIgnoreCase("application/octet-stream")) {
return false;
} else {
return (getSupportingViewer(aFile) != null);
}
}
@Override
public int isPreferred(Node node) {
AbstractFile file = node.getLookup().lookup(AbstractFile.class);
String mimeType = file.getMIMEType();
if (Strings.isNullOrEmpty(mimeType)) {
LOGGER.log(Level.INFO, "Mimetype not known for file: {0}", file.getName()); //NON-NLS
try {
@@ -229,7 +245,7 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
return 0;
}
}
if (mimeType.equalsIgnoreCase("application/octet-stream")) {
return 0;
} else {
@@ -237,7 +253,7 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
return CONFIDENCE_LEVEL;
}
}
return 0;
}
}
@@ -29,6 +29,7 @@ import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
@@ -50,7 +51,7 @@ import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
public class Metadata extends javax.swing.JPanel implements DataContentViewer {
private static final Logger LOGGER = Logger.getLogger(Metadata.class.getName());
/**
* Creates new form Metadata
*/
@@ -148,6 +149,10 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
"Metadata.nodeText.none=None"})
@Override
public void setNode(Node node) {
if ((node == null) || (!isSupported(node))) {
resetComponent();
return;
}
AbstractFile file = node.getLookup().lookup(AbstractFile.class);
Image image = node.getLookup().lookup(Image.class);
DataSource dataSource = node.getLookup().lookup(DataSource.class);
@@ -176,7 +181,6 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.created"), ContentUtils.getStringTime(file.getCrtime(), file));
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.changed"), ContentUtils.getStringTime(file.getCtime(), file));
String md5 = file.getMd5Hash();
if (md5 == null) {
md5 = NbBundle.getMessage(this.getClass(), "Metadata.tableRowContent.md5notCalc");
@@ -189,12 +193,12 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.sha256"), sha256);
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.hashLookupResults"), file.getKnown().toString());
addAcquisitionDetails(sb, dataSource);
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.internalid"), Long.toString(file.getId()));
if (file.getType().compareTo(TSK_DB_FILES_TYPE_ENUM.LOCAL) == 0) {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), file.getLocalAbsPath());
}
try {
List<BlackboardArtifact> associatedObjectArtifacts = file.getArtifacts(ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
if (!associatedObjectArtifacts.isEmpty()) {
@@ -207,14 +211,14 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
}
}
} catch (TskCoreException ex) {
sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.exceptionNotice.text")).append(ex.getLocalizedMessage());
sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.exceptionNotice.text")).append(ex.getLocalizedMessage());
}
endTable(sb);
/*
* If we have a file system file, grab the more detailed metadata text
* too
* If we have a file system file, grab the more detailed metadata
* text too
*/
try {
if (file instanceof FsContent) {
@@ -226,11 +230,11 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
for (String str : fsFile.getMetaDataText()) {
sb.append(str).append("<br />"); //NON-NLS
/*
* Very long results can cause the UI to hang before displaying,
* so truncate the results if necessary.
/*
* Very long results can cause the UI to hang before
* displaying, so truncate the results if necessary.
*/
if(sb.length() > 50000){
if (sb.length() > 50000) {
sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.truncated"));
break;
}
@@ -246,7 +250,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
} catch (TskCoreException ex) {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.name"), image.getName());
}
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.imageType"), image.getType().getName());
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.imageType"), image.getType().getName());
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.size"), Long.toString(image.getSize()));
try {
@@ -282,46 +286,46 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
StringBuilder pathValues = new StringBuilder("<div>");
pathValues.append(imagePaths[0]);
pathValues.append("</div>");
for (int i=1; i < imagePaths.length; i++) {
for (int i = 1; i < imagePaths.length; i++) {
pathValues.append("<div>");
pathValues.append(imagePaths[i]);
pathValues.append("</div>");
}
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), pathValues.toString());
} else {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"),
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"),
NbBundle.getMessage(this.getClass(), "Metadata.nodeText.none"));
}
}
setText(sb.toString());
jTextPane1.setCaretPosition(0);
this.setCursor(null);
}
/**
* Adds a row for download source from the given associated artifact,
* if the associated artifacts specifies a source.
*
* @param sb string builder.
* Adds a row for download source from the given associated artifact, if the
* associated artifacts specifies a source.
*
* @param sb string builder.
* @param associatedArtifact
*
*
* @throws TskCoreException if there is an error
*/
private void addDownloadSourceRow(StringBuilder sb, BlackboardArtifact associatedArtifact ) throws TskCoreException {
if (associatedArtifact != null &&
((associatedArtifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()) ||
(associatedArtifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())) ) {
private void addDownloadSourceRow(StringBuilder sb, BlackboardArtifact associatedArtifact) throws TskCoreException {
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());
}
}
}
/**
* Add the acquisition details to the results (if applicable)
*
*
* @param sb The output StringBuilder object
* @param dataSource The data source (may be null)
*/
@@ -369,6 +373,22 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
public boolean isSupported(Node node) {
Image image = node.getLookup().lookup(Image.class);
AbstractFile file = node.getLookup().lookup(AbstractFile.class);
if (file != null && node instanceof BlackboardArtifactNode) {
BlackboardArtifact theArtifact = ((BlackboardArtifactNode) node).getArtifact();
//disable the content viewer when a download or cached file does not exist instead of displaying its parent
try {
if ((theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
|| theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())
&& file.getId() == theArtifact.getParent().getId()) {
return false;
}
} catch (TskCoreException ex) {
LOGGER.log(Level.WARNING, String.format("Error getting parent of artifact with type %s and objID = %d can not confirm file with name %s and objId = %d is not the parent. Metadata viewer will not be supported.",
theArtifact.getArtifactTypeName(), theArtifact.getObjectID(), file.getName(), file.getId()), ex);
return false;
}
}
return (file != null) || (image != null);
}
@@ -26,6 +26,8 @@ ContactArtifactViewer_cr_disabled_message=Enable Central Repository to view, cre
ContactArtifactViewer_emails_header=Email
ContactArtifactViewer_found_all_accounts_label=All accounts found.
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_missing_account_label=Missing contact account
ContactArtifactViewer_others_header=Other
@@ -60,6 +62,7 @@ GeneralPurposeArtifactViewer.details.historyHeader=Visit Details
GeneralPurposeArtifactViewer.details.otherHeader=Other
GeneralPurposeArtifactViewer.details.searchHeader=Web Search
GeneralPurposeArtifactViewer.details.sourceHeader=Source
GeneralPurposeArtifactViewer.noFile.text=\ (no longer exists)
GeneralPurposeArtifactViewer.term.label=Term
GeneralPurposeArtifactViewer.unknown.text=Unknown
GeneralPurposeArtifactViewer_menuitem_copy=Copy
@@ -68,6 +71,8 @@ MessageAccountPanel_button_create_label=Create
MessageAccountPanel_button_view_label=View
MessageAccountPanel_contact_label=Contact:
MessageAccountPanel_copy_label=Copy
# {0} - accountIdentifer
MessageAccountPanel_id_not_found_in_cr=Unable to find an account with identifier {0} in the Central Repository.
MessageAccountPanel_no_matches=No matches found.
MessageAccountPanel_persona_label=Persona:
MessageAccountPanel_unknown_label=Unknown
@@ -106,5 +111,7 @@ DefaultTableArtifactContentViewer.selectAllMenuItem.text=Select All
DefaultTableArtifactContentViewer.copyMenuItem.text=Copy
PersonaAccountFetcher.account.justification=Account found in Call Log artifact
# {0} - accountIdentifer
PersonaAccountFetcher_not_account_in_cr=Unable to find an account with identifier {0} in the Central Repository.
# {0} - Persona count
PersonaDisplayTask_persona_count_suffix=(1 of {0})
@@ -40,6 +40,7 @@ import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.SwingWorker;
import org.apache.commons.lang.StringUtils;
@@ -751,7 +752,9 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
}
@NbBundle.Messages({
"ContactArtifactViewer_persona_account_justification=Account found in Contact artifact"
"ContactArtifactViewer_persona_account_justification=Account found in Contact artifact",
"# {0} - accountIdentifer",
"ContactArtifactViewer_id_not_found_in_cr=Unable to find account(s) associated with contact {0} in the Central Repository."
})
@Override
@@ -771,6 +774,10 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
for (CentralRepoAccount account : contactUniqueAccountsList) {
personaPanel.addAccount(account, Bundle.ContactArtifactViewer_persona_account_justification(), Persona.Confidence.HIGH);
}
if(contactName != null && contactUniqueAccountsList.isEmpty()) {
createPersonaDialog.setStartupPopupMessage(Bundle.ContactArtifactViewer_id_not_found_in_cr(contactName));
}
// display the dialog now
createPersonaDialog.display();
@@ -56,7 +56,7 @@ import org.sleuthkit.datamodel.TskCoreException;
*/
@ServiceProvider(service = ArtifactContentViewer.class)
public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel implements ArtifactContentViewer {
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(GeneralPurposeArtifactViewer.class.getName());
// Number of columns in the gridbag layout.
@@ -135,7 +135,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
@@ -156,7 +156,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
attributeMap.put(bba.getAttributeType().getTypeID(), attrList);
}
dataSourceName = artifact.getDataSource().getName();
sourceFileName = artifact.getParent().getName();
sourceFileName = artifact.getParent().getUniquePath();
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Unable to get attributes for artifact " + artifact.getArtifactID(), ex);
}
@@ -183,7 +183,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
gridBagConstraints.fill = GridBagConstraints.NONE;
gridBagConstraints.insets = ROW_INSETS;
}
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override
public boolean isSupported(BlackboardArtifact artifact) {
@@ -198,7 +198,7 @@ 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",
@@ -245,9 +245,10 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
"GeneralPurposeArtifactViewer.dates.end=End",
"GeneralPurposeArtifactViewer.dates.time=Time",
"GeneralPurposeArtifactViewer.term.label=Term",
"GeneralPurposeArtifactViewer.details.otherHeader=Other"})
"GeneralPurposeArtifactViewer.details.otherHeader=Other",
"GeneralPurposeArtifactViewer.noFile.text= (no longer exists)"})
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
private void updateView(BlackboardArtifact artifact, Map<Integer, List<BlackboardAttribute>> attributeMap, String dataSourceName, String sourceFileName) {
private void updateView(BlackboardArtifact artifact, Map<Integer, List<BlackboardAttribute>> attributeMap, String dataSourceName, String sourceFilePath) {
final Integer artifactTypeId = artifact.getArtifactTypeID();
if (!(artifactTypeId < 1 || artifactTypeId >= Integer.MAX_VALUE)) {
JTextPane firstTextPane = addDetailsHeader(artifactTypeId);
@@ -265,8 +266,14 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
} else {
addNameValueRow(bba.getAttributeType().getDisplayName(), TimeUtilities.epochToTime(bba.getValueLong(), ContentUtils.getTimeZone(artifact)));
}
} else if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID() && bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT.getTypeID()) {
} else if (bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT.getTypeID() && artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
addNameValueRow(Bundle.GeneralPurposeArtifactViewer_term_label(), bba.getDisplayString());
} else if (bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID()) {
String displayString = bba.getDisplayString();
if (!attributeMap.containsKey(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID())) {
displayString += Bundle.GeneralPurposeArtifactViewer_noFile_text();
}
addNameValueRow(bba.getAttributeType().getDisplayName(), displayString);
} else {
addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString());
}
@@ -280,19 +287,21 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
headerAdded = addDates(Bundle.GeneralPurposeArtifactViewer_dates_end(), attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID()), headerAdded);
addDates(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getDisplayName(), attributeMap.remove(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()), headerAdded);
}
addHeader(Bundle.GeneralPurposeArtifactViewer_details_otherHeader());
for (int key : attributeMap.keySet()) {
for (BlackboardAttribute bba : attributeMap.get(key)) {
if (bba.getAttributeType().getTypeName().startsWith("TSK_DATETIME")) {
addNameValueRow(bba.getAttributeType().getDisplayName(), TimeUtilities.epochToTime(bba.getValueLong(), ContentUtils.getTimeZone(artifact)));
} else {
addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString());
if (!attributeMap.keySet().isEmpty()) {
addHeader(Bundle.GeneralPurposeArtifactViewer_details_otherHeader());
for (int key : attributeMap.keySet()) {
for (BlackboardAttribute bba : attributeMap.get(key)) {
if (bba.getAttributeType().getTypeName().startsWith("TSK_DATETIME")) {
addNameValueRow(bba.getAttributeType().getDisplayName(), TimeUtilities.epochToTime(bba.getValueLong(), ContentUtils.getTimeZone(artifact)));
} else {
addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString());
}
}
}
}
addHeader(Bundle.GeneralPurposeArtifactViewer_details_sourceHeader());
addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_dataSource(), dataSourceName);
addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_file(), sourceFileName);
addNameValueRow(Bundle.GeneralPurposeArtifactViewer_details_file(), sourceFilePath);
// add veritcal glue at the end
addPageEndGlue();
if (firstTextPane != null) {
@@ -562,7 +562,9 @@ final class MessageAccountPanel extends JPanel {
}
@NbBundle.Messages({
"MessageAccountPanel.account.justification=Account found in Message artifact"
"MessageAccountPanel.account.justification=Account found in Message artifact",
"# {0} - accountIdentifer",
"MessageAccountPanel_id_not_found_in_cr=Unable to find an account with identifier {0} in the Central Repository."
})
@Override
public void actionPerformed(ActionEvent e) {
@@ -591,6 +593,8 @@ final class MessageAccountPanel extends JPanel {
CentralRepoAccount account = CentralRepository.getInstance().getAccount(type, accountContainer.getAccount().getTypeSpecificID());
if (account != null) {
personaPanel.addAccount(account, Bundle.MessageAccountPanel_account_justification(), Persona.Confidence.HIGH);
} else {
createPersonaDialog.setStartupPopupMessage(Bundle.MessageAccountPanel_id_not_found_in_cr(accountContainer.getAccount().getTypeSpecificID()));
}
} catch (InvalidAccountIDException ex2) {
// These are expected when the account identifier doesn't match the format of the account type.
@@ -180,7 +180,9 @@ class PersonaAccountFetcher extends SwingWorker<Map<String, Collection<Persona>>
}
@NbBundle.Messages({
"PersonaAccountFetcher.account.justification=Account found in Call Log artifact"
"PersonaAccountFetcher.account.justification=Account found in Call Log artifact",
"# {0} - accountIdentifer",
"PersonaAccountFetcher_not_account_in_cr=Unable to find an account with identifier {0} in the Central Repository."
})
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
@@ -206,6 +208,11 @@ class PersonaAccountFetcher extends SwingWorker<Map<String, Collection<Persona>>
if (account != null) {
personaPanel.addAccount(account, Bundle.PersonaAccountFetcher_account_justification(), Persona.Confidence.HIGH);
}
if((personaSearcherData.getAccountIdentifer() != null &&
!personaSearcherData.getAccountIdentifer().isEmpty()) && account == null) {
dialog.setStartupPopupMessage(Bundle.PersonaAccountFetcher_not_account_in_cr(personaSearcherData.getAccountIdentifer()));
}
} catch (InvalidAccountIDException ex2) {
// These are expected when the account identifier doesn't match the format of the account type.
}
@@ -36,6 +36,7 @@ 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.datamodel.BlackboardArtifactNode;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
@@ -225,6 +226,21 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
// 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);
if (node instanceof BlackboardArtifactNode) {
BlackboardArtifact theArtifact = ((BlackboardArtifactNode) node).getArtifact();
//disable the content viewer when a download or cached file does not exist instead of displaying its parent
try {
if ((theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
|| theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())
&& abstractFile.getId() == theArtifact.getParent().getId()) {
return false;
}
} catch (TskCoreException ex) {
logger.log(Level.WARNING, String.format("Error getting parent of artifact with type %s and objID = %d can not confirm file with name %s and objId = %d is not the parent. Context content viewer will not be supported.",
theArtifact.getArtifactTypeName(), theArtifact.getObjectID(), abstractFile.getName(), abstractFile.getId()), ex);
return false;
}
}
for (BlackboardArtifact.ARTIFACT_TYPE artifactType : CONTEXT_ARTIFACTS) {
List<BlackboardArtifact> artifactsList;
try {
@@ -249,8 +265,7 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
}
@NbBundle.Messages({
"ContextViewer.unknownSource=Unknown ",
})
"ContextViewer.unknownSource=Unknown ",})
/**
* Looks for context providing artifacts for the given file and populates
* the source context.
@@ -263,7 +278,7 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
private void populatePanels(AbstractFile sourceFile) throws NoCurrentCaseException, TskCoreException {
SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
// Check for all context artifacts
boolean foundASource = false;
for (BlackboardArtifact.ARTIFACT_TYPE artifactType : CONTEXT_ARTIFACTS) {
@@ -292,7 +307,7 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
contextContainer.add(usagePanel);
}
}
contextContainer.setBackground(javax.swing.UIManager.getDefaults().getColor("window"));
contextContainer.setEnabled(foundASource);
contextContainer.setVisible(foundASource);
@@ -301,12 +316,12 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
jScrollPane.setVisible(foundASource);
jScrollPane.repaint();
jScrollPane.revalidate();
}
/**
* Resolves an TSK_ASSOCIATED_OBJECT artifact and adds it to the appropriate panel
* Resolves an TSK_ASSOCIATED_OBJECT artifact and adds it to the appropriate
* panel
*
* @param artifact Artifact that may provide context.
*
@@ -358,16 +373,16 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == associatedArtifact.getArtifactTypeID()) {
String sourceName = Bundle.ContextViewer_recentDocs();
String sourceText = recentDocArtifactToString(associatedArtifact);
ContextUsagePanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, dateTime);
ContextUsagePanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, dateTime);
contextUsagePanels.add(usagePanel);
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == associatedArtifact.getArtifactTypeID()) {
String sourceName = Bundle.ContextViewer_programExecution();
String sourceText = programExecArtifactToString(associatedArtifact);
ContextUsagePanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, dateTime);
ContextUsagePanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, dateTime);
contextUsagePanels.add(usagePanel);
}
Collections.sort(contextSourcePanels, new SortByDateTime());
Collections.sort(contextUsagePanels, new SortByDateTime());
}
@@ -399,8 +414,7 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
}
/**
* Returns a display string with recent Doc
* artifact.
* Returns a display string with recent Doc artifact.
*
* @param artifact artifact to get doc from.
*
@@ -415,9 +429,9 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
private String recentDocArtifactToString(BlackboardArtifact artifact) throws TskCoreException {
StringBuilder sb = new StringBuilder(ARTIFACT_STR_MAX_LEN);
Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
BlackboardAttribute attribute = attributesMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME);
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == artifact.getArtifactTypeID()) {
if (attribute != null && attribute.getValueLong() > 0) {
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_on());
@@ -429,8 +443,7 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
}
/**
* Returns a display string with Program Execution
* artifact.
* Returns a display string with Program Execution artifact.
*
* @param artifact artifact to get doc from.
*
@@ -445,9 +458,9 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
private String programExecArtifactToString(BlackboardArtifact artifact) throws TskCoreException {
StringBuilder sb = new StringBuilder(ARTIFACT_STR_MAX_LEN);
Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
BlackboardAttribute attribute = attributesMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME);
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == artifact.getArtifactTypeID()) {
if (attribute != null && attribute.getValueLong() > 0) {
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_runOn());
@@ -538,8 +551,9 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
return attributeMap;
}
interface DateTimePanel {
/**
* Return the date time value for this panel.
*
@@ -547,28 +561,28 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
*/
Long getDateTime();
}
/**
/**
* Return the dateTime value for the given message artifact.
*
* @param artifact
*
*
* @param artifact
*
* @return Long dateTime value or null if the attribute was not found.
*
* @throws TskCoreException
*
* @throws TskCoreException
*/
private Long getArtifactDateTime(BlackboardArtifact artifact) throws TskCoreException {
BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME));
BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME));
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == artifact.getArtifactTypeID()) {
attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT));
attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT));
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == artifact.getArtifactTypeID()
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == artifact.getArtifactTypeID()) {
attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED));
attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED));
}
return (attribute != null ? attribute.getValueLong() : null);
}
/**
* Class for sorting lists of DateTimePanels.
*/
@@ -578,18 +592,18 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
public int compare(DateTimePanel panel1, DateTimePanel panel2) {
Long dateTime1 = panel1.getDateTime();
Long dateTime2 = panel2.getDateTime();
if(dateTime1 == null && dateTime2 == null) {
if (dateTime1 == null && dateTime2 == null) {
return 0;
} else if(dateTime1 == null) {
} else if (dateTime1 == null) {
return -1;
} else if(dateTime2 == null) {
} else if (dateTime2 == null) {
return 1;
}
return dateTime1.compareTo(dateTime2);
}
}
@@ -19,11 +19,16 @@
package org.sleuthkit.autopsy.contentviewers.textcontentviewer;
import java.awt.Component;
import java.util.logging.Level;
import org.openide.nodes.Node;
import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.TskCoreException;
/**
* A DataContentViewer that displays text with the TextViewers available.
@@ -33,6 +38,7 @@ public class TextContentViewer implements DataContentViewer {
private final TextContentViewerPanel panel;
private volatile Node currentNode = null;
private static final Logger logger = Logger.getLogger(TextContentViewer.class.getName());
/**
* No arg constructor for creating the main instance of this Content Viewer.
@@ -52,6 +58,10 @@ public class TextContentViewer implements DataContentViewer {
@Override
public void setNode(Node selectedNode) {
if ((selectedNode == null) || (!isSupported(selectedNode))) {
resetComponent();
return;
}
currentNode = selectedNode;
panel.setNode(currentNode);
@@ -96,12 +106,26 @@ public class TextContentViewer implements DataContentViewer {
if (file == null) {
return false;
}
if (node instanceof BlackboardArtifactNode) {
BlackboardArtifact theArtifact = ((BlackboardArtifactNode) node).getArtifact();
//disable the content viewer when a download or cached file does not exist instead of displaying its parent
try {
if ((theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
|| theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())
&& file.getId() == theArtifact.getParent().getId()) {
return false;
}
} catch (TskCoreException ex) {
logger.log(Level.WARNING, String.format("Error getting parent of artifact with type %s and objID = %d can not confirm file with name %s and objId = %d is not the parent. Text content viewer will not be supported.",
theArtifact.getArtifactTypeName(), theArtifact.getObjectID(), file.getName(), file.getId()), ex);
return false;
}
}
// disable the text content viewer for directories and empty files
if (file.isDir() || file.getSize() == 0) {
return false;
}
return panel.isSupported(node);
}
@@ -501,24 +501,39 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
Lookup lookup = selectedNode.getLookup();
// Get the content. We may get BlackboardArtifacts, ignore those here.
ArrayList<BlackboardArtifact> artifacts = new ArrayList<>();
Collection<? extends Content> contents = lookup.lookupAll(Content.class);
if (contents.isEmpty()) {
return new ViewUpdate(getArtifactContents().size(), currentPage, ERROR_TEXT);
}
Content underlyingContent = null;
//find the first non-artifact content from the lookup results
for (Content content : contents) {
if ((content != null) && (!(content instanceof BlackboardArtifact))) {
// Get all of the blackboard artifacts associated with the content. These are what this
// viewer displays.
try {
artifacts = content.getAllArtifacts();
underlyingContent = content;
break;
} catch (TskException ex) {
logger.log(Level.SEVERE, "Couldn't get artifacts", ex); //NON-NLS
return new ViewUpdate(getArtifactContents().size(), currentPage, ERROR_TEXT);
underlyingContent = content;
break;
}
}
ArrayList<BlackboardArtifact> contentArtifacts = new ArrayList<>();
if (underlyingContent != null) {
try {
//get the artifacts seperately for the use case where an artifact is about a file that exists other than its parent such as a TSK_WEB_DOWNLOAD or TSK_WEB_CACHE
Collection<? extends BlackboardArtifact> nodeArtifacts = lookup.lookupAll(BlackboardArtifact.class);
if (!nodeArtifacts.isEmpty()) {
BlackboardArtifact originalArtifact = nodeArtifacts.iterator().next();
if ((originalArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
|| originalArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())
&& underlyingContent.getId() == originalArtifact.getParent().getId()) {
contentArtifacts.add(originalArtifact);
}
}
if (contentArtifacts.isEmpty()) {
// Get all of the blackboard artifacts associated with the content. These are what this
// viewer displays.
contentArtifacts = underlyingContent.getAllArtifacts();
}
} catch (TskException ex) {
logger.log(Level.SEVERE, "Couldn't get artifacts", ex); //NON-NLS
return new ViewUpdate(getArtifactContents().size(), currentPage, ERROR_TEXT);
}
}
@@ -528,7 +543,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
// Build the new artifact contents cache.
ArrayList<BlackboardArtifact> artifactContents = new ArrayList<>();
for (BlackboardArtifact artifact : artifacts) {
for (BlackboardArtifact artifact : contentArtifacts) {
artifactContents.add(artifact);
}
@@ -537,7 +552,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
int index = 0;
BlackboardArtifact artifact = lookup.lookup(BlackboardArtifact.class);
if (artifact != null) {
index = artifacts.indexOf(artifact);
index = contentArtifacts.indexOf(artifact);
if (index == -1) {
index = 0;
} else {
@@ -547,9 +562,9 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
long assocArtifactId = attr.getValueLong();
int assocArtifactIndex = -1;
for (BlackboardArtifact art : artifacts) {
for (BlackboardArtifact art : contentArtifacts) {
if (assocArtifactId == art.getArtifactID()) {
assocArtifactIndex = artifacts.indexOf(art);
assocArtifactIndex = contentArtifacts.indexOf(art);
break;
}
}
@@ -44,8 +44,10 @@ import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import static org.sleuthkit.autopsy.corecomponents.Bundle.*;
import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.datamodel.DataConversion;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.TskCoreException;
@@ -606,7 +608,24 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
return false;
}
Content content = DataContentViewerUtility.getDefaultContent(node);
return content != null && content.getSize() > 0;
if (content == null || content.getSize() <= 0) {
return false;
} else if (node instanceof BlackboardArtifactNode) {
BlackboardArtifact theArtifact = ((BlackboardArtifactNode) node).getArtifact();
//disable the content viewer when a download or cached file does not exist instead of displaying its parent
try {
if ((theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
|| theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())
&& content.getId() == theArtifact.getParent().getId()) {
return false;
}
} catch (TskCoreException ex) {
logger.log(Level.WARNING, String.format("Error getting parent of artifact with type %s and objID = %d can not confirm content with name %s and objId = %d is not the parent. Hex content viewer will not be supported.",
theArtifact.getArtifactTypeName(), theArtifact.getObjectID(), content.getName(), content.getId()), ex);
return false;
}
}
return true;
}
@Override
@@ -329,6 +329,8 @@ final class ArtifactsListPanel extends AbstractArtifactListPanel {
@NbBundle.Messages({"ArtifactsListPanel.titleColumn.name=Title",
"ArtifactsListPanel.fileNameColumn.name=Name",
"ArtifactsListPanel.dateColumn.name=Date/Time",
"ArtifactsListPanel.urlColumn.name=URL",
"ArtifactsListPanel.termColumn.name=Term",
"ArtifactsListPanel.mimeTypeColumn.name=MIME Type"})
@Override
public String getColumnName(int column) {
@@ -336,11 +338,19 @@ final class ArtifactsListPanel extends AbstractArtifactListPanel {
case 0:
return Bundle.ArtifactsListPanel_dateColumn_name();
case 1:
if (artifactType == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE || artifactType == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD) {
return Bundle.ArtifactsListPanel_fileNameColumn_name();
} else {
return Bundle.ArtifactsListPanel_titleColumn_name();
if (artifactType != null) {
switch (artifactType) {
case TSK_WEB_CACHE:
case TSK_WEB_DOWNLOAD:
return Bundle.ArtifactsListPanel_fileNameColumn_name();
case TSK_WEB_COOKIE:
return Bundle.ArtifactsListPanel_urlColumn_name();
case TSK_WEB_SEARCH_QUERY:
return Bundle.ArtifactsListPanel_termColumn_name();
default:
}
}
return Bundle.ArtifactsListPanel_titleColumn_name();
case 2:
return Bundle.ArtifactsListPanel_mimeTypeColumn_name();
default:
@@ -3,7 +3,9 @@ ArtifactMenuMouseAdapter_label=Extract Files
ArtifactsListPanel.dateColumn.name=Date/Time
ArtifactsListPanel.fileNameColumn.name=Name
ArtifactsListPanel.mimeTypeColumn.name=MIME Type
ArtifactsListPanel.termColumn.name=Term
ArtifactsListPanel.titleColumn.name=Title
ArtifactsListPanel.urlColumn.name=URL
ArtifactsListPanel.value.noValue=No value available.
ArtifactTypeFilterPanel.selectionNeeded.text=At least one Result type must be selected.
CTL_OpenDiscoveryAction=Discovery