Added trace and relationship entries for Autopy case. Bug fixes

This commit is contained in:
Eugene Livis 2018-11-08 16:34:24 -05:00
parent d071a155ad
commit 7c72f7cb0e

View File

@ -49,7 +49,7 @@ import org.sleuthkit.datamodel.*;
/** /**
* ReportCaseUco generates a report in the CASE/UCO format. It saves basic * ReportCaseUco generates a report in the CASE/UCO format. It saves basic
* file info like full path, name, MIME type, times, and hash. file info like full caseDirPath, name, MIME type, times, and hash.
*/ */
class ReportCaseUco implements GeneralReportModule { class ReportCaseUco implements GeneralReportModule {
@ -74,7 +74,7 @@ class ReportCaseUco implements GeneralReportModule {
/** /**
* Generates a CASE/UCO format report. * Generates a CASE/UCO format report.
* *
* @param baseReportDir path to save the report * @param baseReportDir caseDirPath to save the report
* @param progressPanel panel to update the report's progress * @param progressPanel panel to update the report's progress
*/ */
@NbBundle.Messages({ @NbBundle.Messages({
@ -94,6 +94,7 @@ class ReportCaseUco implements GeneralReportModule {
if (configPanel == null) { if (configPanel == null) {
logger.log(Level.SEVERE, "CASE/UCO settings panel has not been initialized"); //NON-NLS logger.log(Level.SEVERE, "CASE/UCO settings panel has not been initialized"); //NON-NLS
MessageNotifyUtil.Message.error(Bundle.ReportCaseUco_notInitialized()); MessageNotifyUtil.Message.error(Bundle.ReportCaseUco_notInitialized());
progressPanel.complete(ReportStatus.ERROR);
return; return;
} }
@ -101,6 +102,7 @@ class ReportCaseUco implements GeneralReportModule {
if (selectedDataSourceId == ReportCaseUcoConfigPanel.NO_DATA_SOURCE_SELECTED) { if (selectedDataSourceId == ReportCaseUcoConfigPanel.NO_DATA_SOURCE_SELECTED) {
logger.log(Level.SEVERE, "No data source selected for CASE/UCO report"); //NON-NLS logger.log(Level.SEVERE, "No data source selected for CASE/UCO report"); //NON-NLS
MessageNotifyUtil.Message.error(Bundle.ReportCaseUco_noDataSourceSelected()); MessageNotifyUtil.Message.error(Bundle.ReportCaseUco_noDataSourceSelected());
progressPanel.complete(ReportStatus.ERROR);
return; return;
} }
@ -110,6 +112,7 @@ class ReportCaseUco implements GeneralReportModule {
} catch (NoCurrentCaseException ex) { } catch (NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "Exception while getting open case.", ex); logger.log(Level.SEVERE, "Exception while getting open case.", ex);
MessageNotifyUtil.Message.error(Bundle.ReportCaseUco_noCaseOpen()); MessageNotifyUtil.Message.error(Bundle.ReportCaseUco_noCaseOpen());
progressPanel.complete(ReportStatus.ERROR);
return; return;
} }
@ -127,6 +130,7 @@ class ReportCaseUco implements GeneralReportModule {
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.SEVERE, "Unable to create directory for CASE/UCO report", ex); //NON-NLS logger.log(Level.SEVERE, "Unable to create directory for CASE/UCO report", ex); //NON-NLS
MessageNotifyUtil.Message.error(Bundle.ReportCaseUco_unableToCreateDirectories()); MessageNotifyUtil.Message.error(Bundle.ReportCaseUco_unableToCreateDirectories());
progressPanel.complete(ReportStatus.ERROR);
return; return;
} }
@ -147,8 +151,11 @@ class ReportCaseUco implements GeneralReportModule {
progressPanel.updateStatusLabel(Bundle.ReportCaseUco_querying()); progressPanel.updateStatusLabel(Bundle.ReportCaseUco_querying());
// create CASE/UCO entry for the Autopsy case
String caseTraceId = saveCaseInfo(skCase, jsonGenerator);
// create CASE/UCO data source entry // create CASE/UCO data source entry
String dataSourceTraceId = getDataSourceInfo(selectedDataSourceId, skCase, jsonGenerator); String dataSourceTraceId = saveDataSourceInfo(selectedDataSourceId, caseTraceId, skCase, jsonGenerator);
// Run getAllFilesQuery to get all files, exclude directories // Run getAllFilesQuery to get all files, exclude directories
final String getAllFilesQuery = "select obj_id, name, size, crtime, atime, mtime, md5, parent_path, mime_type, extension from tsk_files where " final String getAllFilesQuery = "select obj_id, name, size, crtime, atime, mtime, md5, parent_path, mime_type, extension from tsk_files where "
@ -162,8 +169,7 @@ class ReportCaseUco implements GeneralReportModule {
progressPanel.updateStatusLabel(Bundle.ReportCaseUco_processing()); progressPanel.updateStatusLabel(Bundle.ReportCaseUco_processing());
// Loop files and write info to report // Loop files and write info to CASE/UCO report
int count = 0;
while (resultSet.next()) { while (resultSet.next()) {
if (progressPanel.getStatus() == ReportStatus.CANCELED) { if (progressPanel.getStatus() == ReportStatus.CANCELED) {
@ -182,21 +188,24 @@ class ReportCaseUco implements GeneralReportModule {
String extension = resultSet.getString("extension"); String extension = resultSet.getString("extension");
saveFileInCaseUcoFormat(objectId, fileName, parent_path, md5Hash, mime_type, size, crtime, atime, mtime, extension, jsonGenerator, dataSourceTraceId); saveFileInCaseUcoFormat(objectId, fileName, parent_path, md5Hash, mime_type, size, crtime, atime, mtime, extension, jsonGenerator, dataSourceTraceId);
count++;
} }
progressPanel.complete(ReportStatus.COMPLETE); progressPanel.complete(ReportStatus.COMPLETE);
logger.log(Level.INFO, "ELDEBUG Number of files saved {0}", count); //NON-NLS
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get list of files from case database", ex); //NON-NLS logger.log(Level.SEVERE, "Failed to get list of files from case database", ex); //NON-NLS
progressPanel.complete(ReportStatus.ERROR);
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.SEVERE, "Failed to create JSON output for the CASE/UCO report", ex); //NON-NLS logger.log(Level.SEVERE, "Failed to create JSON output for the CASE/UCO report", ex); //NON-NLS
progressPanel.complete(ReportStatus.ERROR);
} catch (SQLException ex) { } catch (SQLException ex) {
logger.log(Level.WARNING, "Unable to read result set", ex); //NON-NLS logger.log(Level.WARNING, "Unable to read result set", ex); //NON-NLS
progressPanel.complete(ReportStatus.ERROR);
} catch (NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "No current case open", ex); //NON-NLS
progressPanel.complete(ReportStatus.ERROR);
} finally { } finally {
if (jsonGenerator != null) { if (jsonGenerator != null) {
try { try {
jsonGenerator.close(); jsonGenerator.close();
// ELTODO investigate database closing issue
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.WARNING, "Failed to close JSON output file", ex); //NON-NLS logger.log(Level.WARNING, "Failed to close JSON output file", ex); //NON-NLS
} }
@ -204,7 +213,48 @@ class ReportCaseUco implements GeneralReportModule {
} }
} }
private String getDataSourceInfo(Long selectedDataSourceId, SleuthkitCase skCase, JsonGenerator jsonGenerator) throws TskCoreException, SQLException, IOException {
private String saveCaseInfo(SleuthkitCase skCase, JsonGenerator catalog) throws TskCoreException, SQLException, IOException, NoCurrentCaseException {
// create a "trace" entry for the Autopsy case iteself
String uniqueCaseName;
String dbFileName;
TskData.DbType dbType = skCase.getDatabaseType();
if (dbType == TskData.DbType.SQLITE) {
uniqueCaseName = Case.getCurrentCaseThrows().getName();
dbFileName = skCase.getDatabaseName();
} else {
uniqueCaseName = skCase.getDatabaseName();
dbFileName = "";
}
String caseDirPath = skCase.getDbDirPath();
String caseTraceId = "case-" + uniqueCaseName;
catalog.writeStartObject();
catalog.writeStringField("@id", caseTraceId);
catalog.writeStringField("@type", "Trace");
catalog.writeFieldName("propertyBundle");
catalog.writeStartArray();
catalog.writeStartObject();
catalog.writeStringField("@type", "File");
if (dbType == TskData.DbType.SQLITE) {
catalog.writeStringField("filePath", caseDirPath + java.io.File.separator + dbFileName);
catalog.writeBooleanField("isDirectory", false);
} else {
catalog.writeStringField("filePath", caseDirPath);
catalog.writeBooleanField("isDirectory", true);
}
catalog.writeEndObject();
catalog.writeEndArray();
catalog.writeEndObject();
return caseTraceId;
}
private String saveDataSourceInfo(Long selectedDataSourceId, String caseTraceId, SleuthkitCase skCase, JsonGenerator jsonGenerator) throws TskCoreException, SQLException, IOException {
String getImageDataSourceQuery = "select size from tsk_image_info where obj_id = " + selectedDataSourceId; String getImageDataSourceQuery = "select size from tsk_image_info where obj_id = " + selectedDataSourceId;
SleuthkitCase.CaseDbQuery queryResult = skCase.executeQuery(getImageDataSourceQuery); SleuthkitCase.CaseDbQuery queryResult = skCase.executeQuery(getImageDataSourceQuery);
@ -221,12 +271,12 @@ class ReportCaseUco implements GeneralReportModule {
} }
if (isImageDataSource) { if (isImageDataSource) {
// get path to image file // get caseDirPath to image file
String getPathToDataSourceQuery = "select name from tsk_image_names where obj_id = " + selectedDataSourceId; String getPathToDataSourceQuery = "select name from tsk_image_names where obj_id = " + selectedDataSourceId;
queryResult = skCase.executeQuery(getPathToDataSourceQuery); queryResult = skCase.executeQuery(getPathToDataSourceQuery);
resultSet = queryResult.getResultSet(); resultSet = queryResult.getResultSet();
while (resultSet.next()) { while (resultSet.next()) {
imageName = resultSet.getString(1); // ELTODO remove double slashes imageName = resultSet.getString(1);
break; break;
} }
} else { } else {
@ -240,10 +290,10 @@ class ReportCaseUco implements GeneralReportModule {
} }
} }
return saveDataSourceInCaseUcoFormat(jsonGenerator, imageName, imageSize, selectedDataSourceId); return saveDataSourceInCaseUcoFormat(jsonGenerator, imageName, imageSize, selectedDataSourceId, caseTraceId);
} }
private String saveDataSourceInCaseUcoFormat(JsonGenerator catalog, String imageName, Long imageSize, Long selectedDataSourceId) throws IOException { private String saveDataSourceInCaseUcoFormat(JsonGenerator catalog, String imageName, Long imageSize, Long selectedDataSourceId, String caseTraceId) throws IOException {
// create a "trace" entry for the data source // create a "trace" entry for the data source
String dataSourceTraceId = "data-source-"+selectedDataSourceId; String dataSourceTraceId = "data-source-"+selectedDataSourceId;
@ -269,6 +319,25 @@ class ReportCaseUco implements GeneralReportModule {
catalog.writeEndArray(); catalog.writeEndArray();
catalog.writeEndObject(); catalog.writeEndObject();
// create a "relationship" entry between the case and the data source
catalog.writeStartObject();
catalog.writeStringField("@id", "relationship-" + caseTraceId);
catalog.writeStringField("@type", "Relationship");
catalog.writeStringField("source", dataSourceTraceId);
catalog.writeStringField("target", caseTraceId);
catalog.writeStringField("kindOfRelationshipe", "contained-within");
catalog.writeBooleanField("isDirectional", true);
catalog.writeFieldName("propertyBundle");
catalog.writeStartArray();
catalog.writeStartObject();
catalog.writeStringField("@type", "PathRelation");
catalog.writeStringField("path", imageName);
catalog.writeEndObject();
catalog.writeEndArray();
catalog.writeEndObject();
return dataSourceTraceId; return dataSourceTraceId;
} }