19 package org.sleuthkit.autopsy.report.caseuco;
21 import com.fasterxml.jackson.core.JsonEncoding;
22 import com.fasterxml.jackson.core.JsonFactory;
23 import com.fasterxml.jackson.core.JsonGenerator;
24 import com.fasterxml.jackson.core.util.DefaultIndenter;
25 import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
26 import java.io.IOException;
27 import java.nio.file.Files;
28 import java.nio.file.Paths;
29 import java.sql.ResultSet;
30 import java.sql.SQLException;
31 import java.util.SimpleTimeZone;
32 import java.util.logging.Level;
33 import org.openide.util.NbBundle;
64 "ReportCaseUco.noCaseOpen=Unable to open currect case",
65 "ReportCaseUco.unableToCreateDirectories=Unable to create directory for CASE-UCO report",
66 "ReportCaseUco.initializing=Creating directories...",
67 "ReportCaseUco.querying=Querying files...",
68 "ReportCaseUco.ingestWarning=Warning, this report will be created before ingest services completed",
69 "ReportCaseUco.processing=Saving files in CASE-UCO format...",
70 "ReportCaseUco.srcModuleName.text=CASE-UCO Report"
72 @SuppressWarnings(
"deprecation")
77 progressPanel.
start();
81 JsonFactory jsonGeneratorFactory =
new JsonFactory();
82 java.io.File reportFile = Paths.get(reportOutputPath).toFile();
84 Files.createDirectories(Paths.get(reportFile.getParent()));
85 }
catch (IOException ex) {
86 logger.log(Level.SEVERE,
"Unable to create directory for CASE-UCO report", ex);
97 JsonGenerator jsonGenerator = null;
98 SimpleTimeZone timeZone =
new SimpleTimeZone(0,
"GMT");
100 jsonGenerator = jsonGeneratorFactory.createGenerator(reportFile, JsonEncoding.UTF8);
102 jsonGenerator.setPrettyPrinter(
new DefaultPrettyPrinter().withObjectIndenter(
new DefaultIndenter(
" ",
"\n")));
112 String caseTraceId =
saveCaseInfo(skCase, jsonGenerator);
115 String dataSourceTraceId =
saveDataSourceInfo(selectedDataSourceId, caseTraceId, skCase, jsonGenerator);
118 final String getAllFilesQuery =
"select obj_id, name, size, crtime, atime, mtime, md5, parent_path, mime_type, extension from tsk_files where "
119 +
"data_source_obj_id = " + Long.toString(selectedDataSourceId)
120 +
" AND ((meta_type = " + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_UNDEF.getValue()
121 +
") OR (meta_type = " + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue()
122 +
") OR (meta_type = " + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT.getValue() +
"))";
124 try (SleuthkitCase.CaseDbQuery queryResult = skCase.executeQuery(getAllFilesQuery)) {
125 ResultSet resultSet = queryResult.getResultSet();
130 while (resultSet.next()) {
136 Long objectId = resultSet.getLong(1);
137 String fileName = resultSet.getString(2);
138 long size = resultSet.getLong(
"size");
142 String md5Hash = resultSet.getString(
"md5");
143 String parent_path = resultSet.getString(
"parent_path");
144 String mime_type = resultSet.getString(
"mime_type");
145 String extension = resultSet.getString(
"extension");
147 saveFileInCaseUcoFormat(objectId, fileName, parent_path, md5Hash, mime_type, size, crtime, atime, mtime, extension, jsonGenerator, dataSourceTraceId);
157 }
catch (TskCoreException ex) {
158 logger.log(Level.SEVERE,
"Failed to get list of files from case database", ex);
160 }
catch (IOException ex) {
161 logger.log(Level.SEVERE,
"Failed to create JSON output for the CASE-UCO report", ex);
163 }
catch (SQLException ex) {
164 logger.log(Level.WARNING,
"Unable to read result set", ex);
167 logger.log(Level.SEVERE,
"No current case open", ex);
170 if (jsonGenerator != null) {
172 jsonGenerator.close();
173 }
catch (IOException ex) {
174 logger.log(Level.WARNING,
"Failed to close JSON output file", ex);
181 catalog.writeStartObject();
182 catalog.writeFieldName(
"@graph");
183 catalog.writeStartArray();
187 catalog.writeEndArray();
188 catalog.writeEndObject();
205 String uniqueCaseName;
207 TskData.DbType dbType = skCase.getDatabaseType();
208 if (dbType == TskData.DbType.SQLITE) {
210 dbFileName = skCase.getDatabaseName();
212 uniqueCaseName = skCase.getDatabaseName();
216 String caseDirPath = skCase.getDbDirPath();
217 String caseTraceId =
"case-" + uniqueCaseName;
218 catalog.writeStartObject();
219 catalog.writeStringField(
"@id", caseTraceId);
220 catalog.writeStringField(
"@type",
"Trace");
222 catalog.writeFieldName(
"propertyBundle");
223 catalog.writeStartArray();
224 catalog.writeStartObject();
227 caseDirPath = caseDirPath.replaceAll(
"\\\\",
"/");
229 catalog.writeStringField(
"@type",
"File");
230 if (dbType == TskData.DbType.SQLITE) {
231 catalog.writeStringField(
"filePath", caseDirPath +
"/" + dbFileName);
232 catalog.writeBooleanField(
"isDirectory",
false);
234 catalog.writeStringField(
"filePath", caseDirPath);
235 catalog.writeBooleanField(
"isDirectory",
true);
237 catalog.writeEndObject();
239 catalog.writeEndArray();
240 catalog.writeEndObject();
257 private static String
saveDataSourceInfo(Long selectedDataSourceId, String caseTraceId, SleuthkitCase skCase, JsonGenerator jsonGenerator)
throws TskCoreException, SQLException, IOException {
259 Long imageSize = (long) 0;
260 String imageName =
"";
261 boolean isImageDataSource =
false;
262 String getImageDataSourceQuery =
"select size from tsk_image_info where obj_id = " + selectedDataSourceId;
263 try (SleuthkitCase.CaseDbQuery queryResult = skCase.executeQuery(getImageDataSourceQuery)) {
264 ResultSet resultSet = queryResult.getResultSet();
266 while (resultSet.next()) {
268 imageSize = resultSet.getLong(1);
269 isImageDataSource =
true;
274 if (isImageDataSource) {
276 String getPathToDataSourceQuery =
"select name from tsk_image_names where obj_id = " + selectedDataSourceId;
277 try (SleuthkitCase.CaseDbQuery queryResult = skCase.executeQuery(getPathToDataSourceQuery)) {
278 ResultSet resultSet = queryResult.getResultSet();
279 while (resultSet.next()) {
280 imageName = resultSet.getString(1);
286 String getLogicalDataSourceQuery =
"select name from tsk_files where obj_id = " + selectedDataSourceId;
287 try (SleuthkitCase.CaseDbQuery queryResult = skCase.executeQuery(getLogicalDataSourceQuery)) {
288 ResultSet resultSet = queryResult.getResultSet();
289 while (resultSet.next()) {
290 imageName = resultSet.getString(1);
299 private static String
saveDataSourceInCaseUcoFormat(JsonGenerator catalog, String imageName, Long imageSize, Long selectedDataSourceId, String caseTraceId)
throws IOException {
302 String dataSourceTraceId =
"data-source-" + selectedDataSourceId;
303 catalog.writeStartObject();
304 catalog.writeStringField(
"@id", dataSourceTraceId);
305 catalog.writeStringField(
"@type",
"Trace");
307 catalog.writeFieldName(
"propertyBundle");
308 catalog.writeStartArray();
310 catalog.writeStartObject();
311 catalog.writeStringField(
"@type",
"File");
314 imageName = imageName.replaceAll(
"\\\\",
"/");
316 catalog.writeStringField(
"filePath", imageName);
317 catalog.writeEndObject();
320 catalog.writeStartObject();
321 catalog.writeStringField(
"@type",
"ContentData");
322 catalog.writeStringField(
"sizeInBytes", Long.toString(imageSize));
323 catalog.writeEndObject();
326 catalog.writeEndArray();
327 catalog.writeEndObject();
330 catalog.writeStartObject();
331 catalog.writeStringField(
"@id",
"relationship-" + caseTraceId);
332 catalog.writeStringField(
"@type",
"Relationship");
333 catalog.writeStringField(
"source", dataSourceTraceId);
334 catalog.writeStringField(
"target", caseTraceId);
335 catalog.writeStringField(
"kindOfRelationship",
"contained-within");
336 catalog.writeBooleanField(
"isDirectional",
true);
338 catalog.writeFieldName(
"propertyBundle");
339 catalog.writeStartArray();
340 catalog.writeStartObject();
341 catalog.writeStringField(
"@type",
"PathRelation");
342 catalog.writeStringField(
"path", imageName);
343 catalog.writeEndObject();
344 catalog.writeEndArray();
346 catalog.writeEndObject();
348 return dataSourceTraceId;
351 private static void saveFileInCaseUcoFormat(Long objectId, String fileName, String parent_path, String md5Hash, String mime_type,
long size, String ctime,
352 String atime, String mtime, String extension, JsonGenerator catalog, String dataSourceTraceId)
throws IOException {
354 String fileTraceId =
"file-" + objectId;
357 catalog.writeStartObject();
358 catalog.writeStringField(
"@id", fileTraceId);
359 catalog.writeStringField(
"@type",
"Trace");
361 catalog.writeFieldName(
"propertyBundle");
362 catalog.writeStartArray();
364 catalog.writeStartObject();
365 catalog.writeStringField(
"@type",
"File");
366 catalog.writeStringField(
"createdTime", ctime);
367 catalog.writeStringField(
"accessedTime", atime);
368 catalog.writeStringField(
"modifiedTime", mtime);
369 if (extension != null) {
370 catalog.writeStringField(
"extension", extension);
372 catalog.writeStringField(
"fileName", fileName);
373 if (parent_path != null) {
374 catalog.writeStringField(
"filePath", parent_path + fileName);
376 catalog.writeBooleanField(
"isDirectory",
false);
377 catalog.writeStringField(
"sizeInBytes", Long.toString(size));
378 catalog.writeEndObject();
380 catalog.writeStartObject();
381 catalog.writeStringField(
"@type",
"ContentData");
382 if (mime_type != null) {
383 catalog.writeStringField(
"mimeType", mime_type);
385 if (md5Hash != null) {
386 catalog.writeFieldName(
"hash");
387 catalog.writeStartArray();
388 catalog.writeStartObject();
389 catalog.writeStringField(
"@type",
"Hash");
390 catalog.writeStringField(
"hashMethod",
"MD5");
391 catalog.writeStringField(
"hashValue", md5Hash);
392 catalog.writeEndObject();
393 catalog.writeEndArray();
395 catalog.writeStringField(
"sizeInBytes", Long.toString(size));
397 catalog.writeEndObject();
399 catalog.writeEndArray();
400 catalog.writeEndObject();
403 catalog.writeStartObject();
404 catalog.writeStringField(
"@id",
"relationship-" + objectId);
405 catalog.writeStringField(
"@type",
"Relationship");
406 catalog.writeStringField(
"source", fileTraceId);
407 catalog.writeStringField(
"target", dataSourceTraceId);
408 catalog.writeStringField(
"kindOfRelationship",
"contained-within");
409 catalog.writeBooleanField(
"isDirectional",
true);
411 catalog.writeFieldName(
"propertyBundle");
412 catalog.writeStartArray();
413 catalog.writeStartObject();
414 catalog.writeStringField(
"@type",
"PathRelation");
415 if (parent_path != null) {
416 catalog.writeStringField(
"path", parent_path + fileName);
418 catalog.writeStringField(
"path", fileName);
420 catalog.writeEndObject();
421 catalog.writeEndArray();
423 catalog.writeEndObject();
static synchronized IngestManager getInstance()
static void warn(String message)
void complete(ReportStatus reportStatus)
boolean isIngestRunning()
void addReport(String localPath, String srcModuleName, String reportName)
void setIndeterminate(boolean indeterminate)
static String getStringTimeISO8601(long epochSeconds, TimeZone tzone)
SleuthkitCase getSleuthkitCase()
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
void updateStatusLabel(String statusMessage)
static void error(String message)