Merge remote-tracking branch 'upstream/develop-4.3.1' into develop

This commit is contained in:
Richard Cordovano 2017-02-08 19:57:21 -05:00
commit d18ef89bf1
5 changed files with 150 additions and 95 deletions

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2016 Basis Technology Corp. * Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -19,62 +19,104 @@
package org.sleuthkit.autopsy.datamodel; package org.sleuthkit.autopsy.datamodel;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.TimeZone;
import java.util.logging.Level; import java.util.logging.Level;
import org.apache.commons.lang.StringUtils;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; 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.sleuthkit.datamodel.TskException;
/** /**
* StringContent object for a blackboard artifact, that can be looked up and * An HTML representation of an artifact. The representation is plain vanilla
* used to display text for the DataContent viewers. Displays values in artifact * HTML, so any styling needs to be supplied by the display mechansim. For
* in HTML. Note that it has no style associated with it and assumes that the * example, GUI components such as content viewers might use HTMLEditorKit to
* pane showing the HTML has styles set (such as with HTMLEditorKit). * add styling.
*/ */
public class ArtifactStringContent implements StringContent { public class ArtifactStringContent implements StringContent {
BlackboardArtifact artifact; private final static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private final static Logger logger = Logger.getLogger(ArtifactStringContent.class.getName());
private final BlackboardArtifact artifact;
private String stringContent = ""; private String stringContent = "";
static final Logger logger = Logger.getLogger(ArtifactStringContent.class.getName());
private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public ArtifactStringContent(BlackboardArtifact art) { /**
artifact = art; * Constructs an HTML representation of an artifact. The representation is
* plain vanilla HTML, so any styling needs to be supplied by the display
* mechansim. For example, GUI components such as content viewers might use
* HTMLEditorKit to add styling.
*
* @param artifact The artifact to be represented as HTML.
*/
public ArtifactStringContent(BlackboardArtifact artifact) {
this.artifact = artifact;
} }
/**
* Gets the HTML representation of the artifact.
*
* @return The HTML representation of the artifact as a string.
*/
@Messages({
"ArtifactStringContent.attrsTableHeader.attribute=Attribute",
"ArtifactStringContent.attrsTableHeader.value=Value",
"ArtifactStringContent.attrsTableHeader.sources=Source(s)",
"ArtifactStringContent.failedToGetSourcePath.message=Failed to get source file path from case database",
"ArtifactStringContent.failedToGetAttributes.message=Failed to get some or all attributes from case database"
})
@Override @Override
@SuppressWarnings("deprecation")
public String getString() { public String getString() {
if (stringContent.isEmpty()) { if (stringContent.isEmpty()) {
/*
* Start the document.
*/
StringBuilder buffer = new StringBuilder(1024);
buffer.append("<html>\n"); //NON-NLS
buffer.append("<body>\n"); //NON-NLS
/*
* Use the artifact display name as a header.
*/
buffer.append("<h3>"); //NON-NLS
buffer.append(artifact.getDisplayName());
buffer.append("</h3>\n"); //NON-NLS
/*
* Put the attributes, source content path and artifact id in a
* table.
*/
buffer.append("<table border='1'>"); //NON-NLS
buffer.append("<tr>"); //NON-NLS
buffer.append("<td>"); //NON-NLS
buffer.append(Bundle.ArtifactStringContent_attrsTableHeader_attribute());
buffer.append("</td>"); //NON-NLS
buffer.append("<td>"); //NON-NLS
buffer.append(Bundle.ArtifactStringContent_attrsTableHeader_value());
buffer.append("</td>"); //NON-NLS
buffer.append("<td>"); //NON-NLS
buffer.append(Bundle.ArtifactStringContent_attrsTableHeader_sources());
buffer.append("</td>"); //NON-NLS
buffer.append("</tr>\n"); //NON-NLS
try { try {
StringBuilder buffer = new StringBuilder(); Content content = artifact.getSleuthkitCase().getContentById(artifact.getObjectID());
buffer.append("<html>\n"); //NON-NLS
buffer.append("<body>\n"); //NON-NLS
// artifact name header /*
buffer.append("<h4>"); //NON-NLS * Add rows for each attribute.
buffer.append(artifact.getDisplayName()); */
buffer.append("</h4>\n"); //NON-NLS
// start table for attributes
buffer.append("<table border='0'>"); //NON-NLS
buffer.append("<tr>"); //NON-NLS
buffer.append("</tr>\n"); //NON-NLS
// cycle through each attribute and display in a row in the table.
for (BlackboardAttribute attr : artifact.getAttributes()) { for (BlackboardAttribute attr : artifact.getAttributes()) {
// name column /*
* Attribute display name column.
*/
buffer.append("<tr><td>"); //NON-NLS buffer.append("<tr><td>"); //NON-NLS
buffer.append(attr.getAttributeType().getDisplayName()); buffer.append(attr.getAttributeType().getDisplayName());
buffer.append("</td>"); //NON-NLS buffer.append("</td>"); //NON-NLS
// value column /*
* Attribute value column.
*/
buffer.append("<td>"); //NON-NLS buffer.append("<td>"); //NON-NLS
switch (attr.getAttributeType().getValueType()) { switch (attr.getAttributeType().getValueType()) {
case STRING: case STRING:
@ -94,42 +136,49 @@ public class ArtifactStringContent implements StringContent {
case DATETIME: case DATETIME:
long epoch = attr.getValueLong(); long epoch = attr.getValueLong();
String time = "0000-00-00 00:00:00"; String time = "0000-00-00 00:00:00";
if (epoch != 0) { if (null != content && 0 != epoch) {
dateFormatter.setTimeZone(getTimeZone(artifact)); dateFormatter.setTimeZone(ContentUtils.getTimeZone(content));
time = dateFormatter.format(new java.util.Date(epoch * 1000)); time = dateFormatter.format(new java.util.Date(epoch * 1000));
} }
buffer.append(time); buffer.append(time);
break; break;
} }
if (!"".equals(attr.getContext())) {
buffer.append(" (");
buffer.append(attr.getContext());
buffer.append(")");
}
buffer.append("</td>"); //NON-NLS buffer.append("</td>"); //NON-NLS
/*
* Attribute source modules column.
*/
buffer.append("<td>"); //NON-NLS
buffer.append(StringUtils.join(attr.getSources(), ", "));
buffer.append("</td>"); //NON-NLS
buffer.append("</tr>\n"); //NON-NLS buffer.append("</tr>\n"); //NON-NLS
} }
final Content content = getAssociatedContent(artifact); /*
* Add a row for the source content path.
String path = ""; */
try {
path = content.getUniquePath();
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Exception while calling Content.getUniquePath() on {0} : {1}", new Object[]{content, ex.getLocalizedMessage()}); //NON-NLS
}
//add file path
buffer.append("<tr>"); //NON-NLS buffer.append("<tr>"); //NON-NLS
buffer.append("<td>"); //NON-NLS buffer.append("<td>"); //NON-NLS
buffer.append(NbBundle.getMessage(this.getClass(), "ArtifactStringContent.getStr.srcFilePath.text")); buffer.append(NbBundle.getMessage(this.getClass(), "ArtifactStringContent.getStr.srcFilePath.text"));
buffer.append("</td>"); //NON-NLS buffer.append("</td>"); //NON-NLS
buffer.append("<td>"); //NON-NLS buffer.append("<td>"); //NON-NLS
String path = "";
try {
if (null != content) {
path = content.getUniquePath();
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error getting source content path for artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex);
path = Bundle.ArtifactStringContent_failedToGetSourcePath_message();
}
buffer.append(path); buffer.append(path);
buffer.append("</td>"); //NON-NLS buffer.append("</td>"); //NON-NLS
buffer.append("</tr>\n"); //NON-NLS buffer.append("</tr>\n"); //NON-NLS
// add artifact ID (useful for debugging) /*
* Add a row for the artifact id.
*/
buffer.append("<tr><td>"); //NON-NLS buffer.append("<tr><td>"); //NON-NLS
buffer.append(NbBundle.getMessage(this.getClass(), "ArtifactStringContent.getStr.artifactId.text")); buffer.append(NbBundle.getMessage(this.getClass(), "ArtifactStringContent.getStr.artifactId.text"));
buffer.append("</td><td>"); //NON-NLS buffer.append("</td><td>"); //NON-NLS
@ -137,29 +186,26 @@ public class ArtifactStringContent implements StringContent {
buffer.append("</td>"); //NON-NLS buffer.append("</td>"); //NON-NLS
buffer.append("</tr>\n"); //NON-NLS buffer.append("</tr>\n"); //NON-NLS
/*
* Finish the document
*/
buffer.append("</table>"); //NON-NLS
buffer.append("</html>\n"); //NON-NLS
stringContent = buffer.toString();
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error getting data for artifact (artifact_id=%d)", artifact.getArtifactID()), ex);
buffer.append("<tr><td>"); //NON-NLS
buffer.append(Bundle.ArtifactStringContent_failedToGetAttributes_message());
buffer.append("</td>"); //NON-NLS
buffer.append("</tr>\n"); //NON-NLS
buffer.append("</table>"); //NON-NLS buffer.append("</table>"); //NON-NLS
buffer.append("</html>\n"); //NON-NLS buffer.append("</html>\n"); //NON-NLS
stringContent = buffer.toString(); stringContent = buffer.toString();
} catch (TskException ex) {
stringContent = NbBundle.getMessage(this.getClass(), "ArtifactStringContent.getStr.err");
} }
} }
return stringContent; return stringContent;
} }
private static Content getAssociatedContent(BlackboardArtifact artifact) {
try {
return artifact.getSleuthkitCase().getContentById(artifact.getObjectID());
} catch (TskException ex) {
logger.log(Level.WARNING, "Getting file failed", ex); //NON-NLS
}
throw new IllegalArgumentException(NbBundle.getMessage(ArtifactStringContent.class, "ArtifactStringContent.exception.msg"));
}
private static TimeZone getTimeZone(BlackboardArtifact artifact) {
return ContentUtils.getTimeZone(getAssociatedContent(artifact));
}
} }

View File

@ -12,7 +12,7 @@ AbstractAbstractFileNode.modeColLbl=Mode
AbstractAbstractFileNode.useridColLbl=UserID AbstractAbstractFileNode.useridColLbl=UserID
AbstractAbstractFileNode.groupidColLbl=GroupID AbstractAbstractFileNode.groupidColLbl=GroupID
AbstractAbstractFileNode.metaAddrColLbl=Meta Addr. AbstractAbstractFileNode.metaAddrColLbl=Meta Addr.
AbstractAbstractFileNode.attrAddrColLbl=Attr. Addr. AbstractAbstractFileNode.attrAddrColLbl=Attr. Addr.ArtifactStringContent.getStr.err
AbstractAbstractFileNode.typeDirColLbl=Type(Dir) AbstractAbstractFileNode.typeDirColLbl=Type(Dir)
AbstractAbstractFileNode.typeMetaColLbl=Type(Meta) AbstractAbstractFileNode.typeMetaColLbl=Type(Meta)
AbstractAbstractFileNode.knownColLbl=Known AbstractAbstractFileNode.knownColLbl=Known
@ -25,7 +25,6 @@ AbstractContentNode.exception.cannotChangeSysName.msg=Cannot change the system n
AbstractFsContentNode.noDesc.text=no description AbstractFsContentNode.noDesc.text=no description
ArtifactStringContent.getStr.srcFilePath.text=Source File Path ArtifactStringContent.getStr.srcFilePath.text=Source File Path
ArtifactStringContent.getStr.err=Error getting content ArtifactStringContent.getStr.err=Error getting content
ArtifactStringContent.exception.msg=Could not get file from database
ArtifactTypeNode.createSheet.artType.name=Artifact Type ArtifactTypeNode.createSheet.artType.name=Artifact Type
ArtifactTypeNode.createSheet.artType.displayName=Artifact Type ArtifactTypeNode.createSheet.artType.displayName=Artifact Type
ArtifactTypeNode.createSheet.artType.desc=no description ArtifactTypeNode.createSheet.artType.desc=no description

View File

@ -18,7 +18,6 @@ AbstractContentNode.exception.cannotChangeSysName.msg=\u30b7\u30b9\u30c6\u30e0\u
AbstractFsContentNode.noDesc.text=\u8aac\u660e\u304c\u3042\u308a\u307e\u305b\u3093 AbstractFsContentNode.noDesc.text=\u8aac\u660e\u304c\u3042\u308a\u307e\u305b\u3093
ArtifactStringContent.getStr.srcFilePath.text=\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9 ArtifactStringContent.getStr.srcFilePath.text=\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9
ArtifactStringContent.getStr.err=\u30b3\u30f3\u30c6\u30f3\u30c4\u53d6\u5f97\u30a8\u30e9\u30fc ArtifactStringContent.getStr.err=\u30b3\u30f3\u30c6\u30f3\u30c4\u53d6\u5f97\u30a8\u30e9\u30fc
ArtifactStringContent.exception.msg=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304b\u3089\u30d5\u30a1\u30a4\u30eb\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f
ArtifactTypeNode.createSheet.artType.desc=\u8aac\u660e\u304c\u3042\u308a\u307e\u305b\u3093 ArtifactTypeNode.createSheet.artType.desc=\u8aac\u660e\u304c\u3042\u308a\u307e\u305b\u3093
ArtifactTypeNode.createSheet.childCnt.name=\u30c1\u30e3\u30a4\u30eb\u30c9\u6570 ArtifactTypeNode.createSheet.childCnt.name=\u30c1\u30e3\u30a4\u30eb\u30c9\u6570
ArtifactTypeNode.createSheet.childCnt.desc=\u8aac\u660e\u304c\u3042\u308a\u307e\u305b\u3093 ArtifactTypeNode.createSheet.childCnt.desc=\u8aac\u660e\u304c\u3042\u308a\u307e\u305b\u3093

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2016 Basis Technology Corp. * Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import javax.xml.bind.DatatypeConverter; import javax.xml.bind.DatatypeConverter;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard; import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
@ -31,7 +32,6 @@ import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.openide.util.NbBundle;
/** /**
* A file ingest module that associates custom artifacts and attributes with * A file ingest module that associates custom artifacts and attributes with
@ -43,21 +43,21 @@ import org.openide.util.NbBundle;
final class CustomArtifactsCreatorIngestModule extends FileIngestModuleAdapter { final class CustomArtifactsCreatorIngestModule extends FileIngestModuleAdapter {
private static final Logger logger = Logger.getLogger(CustomArtifactsCreatorIngestModule.class.getName()); private static final Logger logger = Logger.getLogger(CustomArtifactsCreatorIngestModule.class.getName());
private static final String moduleName = CustomArtifactsCreatorIngestModuleFactory.getModuleName(); private static final String MODULE_NAME = CustomArtifactsCreatorIngestModuleFactory.getModuleName();
private static final String ARTIFACT_TYPE_NAME = "AUT_ARTIFACT"; private static final String ARTIFACT_TYPE_NAME = "CUSTOM_ARTIFACT";
private static final String ARTIFACT_DISPLAY_NAME = "Autopsy Artifact"; private static final String ARTIFACT_DISPLAY_NAME = "Custom Artifact";
private static final String INT_ATTR_TYPE_NAME = "AUT_INT_ATTRIBUTE"; private static final String INT_ATTR_TYPE_NAME = "CUSTOM_INT_ATTRIBUTE";
private static final String INT_ATTR_DISPLAY_NAME = "Autopsy Integer"; private static final String INT_ATTR_DISPLAY_NAME = "Custom Integer";
private static final String DOUBLE_ATTR_TYPE_NAME = "AUT_DOUBLE_ATTRIBUTE"; private static final String DOUBLE_ATTR_TYPE_NAME = "CUSTOM_DOUBLE_ATTRIBUTE";
private static final String DOUBLE_ATTR_DISPLAY_NAME = "Autopsy Double"; private static final String DOUBLE_ATTR_DISPLAY_NAME = "Custom Double";
private static final String LONG_ATTR_TYPE_NAME = "AUT_LONG_ATTRIBUTE"; private static final String LONG_ATTR_TYPE_NAME = "CUSTOM_LONG_ATTRIBUTE";
private static final String LONG_ATTR_DISPLAY_NAME = "Autopsy Long"; private static final String LONG_ATTR_DISPLAY_NAME = "Custom Long";
private static final String DATETIME_ATTR_TYPE_NAME = "AUT_DATETIME_ATTRIBUTE"; private static final String DATETIME_ATTR_TYPE_NAME = "CUSTOM_DATETIME_ATTRIBUTE";
private static final String DATETIME_ATTR_DISPLAY_NAME = "Autopsy Datetime"; private static final String DATETIME_ATTR_DISPLAY_NAME = "Custom Datetime";
private static final String BYTES_ATTR_TYPE_NAME = "AUT_BYTES_ATTRIBUTE"; private static final String BYTES_ATTR_TYPE_NAME = "CUSTOM_BYTES_ATTRIBUTE";
private static final String BYTES_ATTR_DISPLAY_NAME = "Autopsy Bytes"; private static final String BYTES_ATTR_DISPLAY_NAME = "Custom Bytes";
private static final String STRING_ATTR_TYPE_NAME = "AUT_STRING_ATTRIBUTE"; private static final String STRING_ATTR_TYPE_NAME = "CUSTOM_STRING_ATTRIBUTE";
private static final String STRING_ATTR_DISPLAY_NAME = "Autopsy String"; private static final String STRING_ATTR_DISPLAY_NAME = "Custom String";
private BlackboardArtifact.Type artifactType; private BlackboardArtifact.Type artifactType;
private BlackboardAttribute.Type intAttrType; private BlackboardAttribute.Type intAttrType;
private BlackboardAttribute.Type doubleAttrType; private BlackboardAttribute.Type doubleAttrType;
@ -91,19 +91,30 @@ final class CustomArtifactsCreatorIngestModule extends FileIngestModuleAdapter {
return ProcessResult.OK; return ProcessResult.OK;
} }
/*
* Add a custom artifact with one custom attribute of each value type.
*/
try { try {
/*
* Add a custom artifact with one custom attribute of each value
* type.
*/
BlackboardArtifact artifact = file.newArtifact(artifactType.getTypeID()); BlackboardArtifact artifact = file.newArtifact(artifactType.getTypeID());
List<BlackboardAttribute> attributes = new ArrayList<>(); List<BlackboardAttribute> attributes = new ArrayList<>();
attributes.add(new BlackboardAttribute(intAttrType, moduleName, 0)); attributes.add(new BlackboardAttribute(intAttrType, MODULE_NAME, 0));
attributes.add(new BlackboardAttribute(doubleAttrType, moduleName, 0.0)); attributes.add(new BlackboardAttribute(doubleAttrType, MODULE_NAME, 0.0));
attributes.add(new BlackboardAttribute(longAttributeType, moduleName, 0L)); attributes.add(new BlackboardAttribute(longAttributeType, MODULE_NAME, 0L));
attributes.add(new BlackboardAttribute(dateTimeAttrType, moduleName, 60L)); attributes.add(new BlackboardAttribute(dateTimeAttrType, MODULE_NAME, 60L));
attributes.add(new BlackboardAttribute(bytesAttrType, moduleName, DatatypeConverter.parseHexBinary("ABCD"))); attributes.add(new BlackboardAttribute(bytesAttrType, MODULE_NAME, DatatypeConverter.parseHexBinary("ABCD")));
attributes.add(new BlackboardAttribute(stringAttrType, moduleName, "Zero")); attributes.add(new BlackboardAttribute(stringAttrType, MODULE_NAME, "Zero"));
artifact.addAttributes(attributes); artifact.addAttributes(attributes);
/*
* Add a second source module to the attributes. Try to do it twice.
* The second attempt should have no effect on the data.
*/
for (BlackboardAttribute attr : attributes) {
attr.addSource("Added Module");
attr.addSource("Added Module");
}
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Failed to process file (obj_id = %d)", file.getId()), ex); logger.log(Level.SEVERE, String.format("Failed to process file (obj_id = %d)", file.getId()), ex);
return ProcessResult.ERROR; return ProcessResult.ERROR;

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2016 Basis Technology Corp. * Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -30,7 +30,7 @@ import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
* attributes with files for test purposes. Uncomment the service provider * attributes with files for test purposes. Uncomment the service provider
* annotation to activate this test fixture. * annotation to activate this test fixture.
*/ */
//@ServiceProvider(service = IngestModuleFactory.class) @ServiceProvider(service = IngestModuleFactory.class)
public final class CustomArtifactsCreatorIngestModuleFactory extends IngestModuleFactoryAdapter { public final class CustomArtifactsCreatorIngestModuleFactory extends IngestModuleFactoryAdapter {
@Override @Override