20 package org.sleuthkit.autopsy.report.modules.caseuco;
22 import com.google.gson.Gson;
23 import com.google.gson.GsonBuilder;
24 import com.google.gson.JsonElement;
25 import com.google.gson.stream.JsonWriter;
27 import java.io.FileOutputStream;
28 import java.io.IOException;
29 import java.io.OutputStream;
30 import java.io.OutputStreamWriter;
31 import java.nio.file.Files;
32 import java.nio.file.Path;
33 import java.nio.file.Paths;
34 import java.util.ArrayDeque;
35 import java.util.Deque;
36 import java.util.HashSet;
37 import java.util.List;
39 import java.util.logging.Level;
40 import java.util.stream.Collectors;
41 import javax.swing.JPanel;
42 import org.openide.util.NbBundle;
51 import org.
sleuthkit.caseuco.ContentNotExportableException;
54 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
59 import org.
sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil;
73 add(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_UNDEF.getValue());
74 add(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue());
75 add(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT.getValue());
93 return NbBundle.getMessage(this.getClass(),
"CaseUcoReportModule.getName.text");
103 return REPORT_FILE_NAME +
"." +
EXTENSION;
108 return NbBundle.getMessage(this.getClass(),
"CaseUcoReportModule.getDesc.text");
132 "CaseUcoReportModule.notInitialized=CASE-UCO settings panel has not been initialized",
133 "CaseUcoReportModule.noDataSourceSelected=No data source selected for CASE-UCO report",
134 "CaseUcoReportModule.ioError=I/O error encountered while generating report",
135 "CaseUcoReportModule.noCaseOpen=No case is currently open",
136 "CaseUcoReportModule.tskCoreException=TskCoreException [%s] encountered while generating the report. Please reference the log for more details.",
137 "CaseUcoReportModule.processingDataSource=Processing datasource: %s",
138 "CaseUcoReportModule.ingestWarning=Warning, this report will be created before ingest services completed",
139 "CaseUcoReportModule.unableToCreateDirectories=Unable to create directory for CASE-UCO report",
140 "CaseUcoReportModule.srcModuleName=CASE-UCO Report"
151 Files.createDirectories(reportDirectory);
152 }
catch (IOException ex) {
153 logger.log(Level.WARNING,
"Unable to create directory for CASE-UCO report.", ex);
155 Bundle.CaseUcoReportModule_unableToCreateDirectories());
161 Path caseJsonReportFile = reportDirectory.resolve(REPORT_FILE_NAME +
"." + EXTENSION);
163 try (OutputStream stream =
new FileOutputStream(caseJsonReportFile.toFile());
164 JsonWriter reportWriter =
new JsonWriter(
new OutputStreamWriter(stream,
"UTF-8"))) {
165 Gson gson =
new GsonBuilder().setPrettyPrinting().
create();
166 reportWriter.setIndent(
" ");
167 reportWriter.beginObject();
168 reportWriter.name(
"@graph");
169 reportWriter.beginArray();
171 CaseUcoExporter exporter =
new CaseUcoExporter(currentCase.
getSleuthkitCase());
172 for (JsonElement element : exporter.exportSleuthkitCase()) {
173 gson.toJson(element, reportWriter);
181 progressPanel.
start();
186 for (
int i = 0; i < dataSources.size(); i++) {
187 DataSource dataSource = dataSources.get(i);
189 Bundle.CaseUcoReportModule_processingDataSource(),
190 dataSource.getName()));
192 for (JsonElement element : exporter.exportDataSource(dataSource)) {
193 gson.toJson(element, reportWriter);
201 Set<Long> dataSourceIds = dataSources.stream()
202 .map((datasource) -> datasource.getId())
203 .collect(Collectors.toSet());
205 logger.log(Level.INFO,
"Writing all artifacts to the CASE-UCO report. "
206 +
"Keyword hits will be skipped as they can't be represented"
207 +
" in CASE format.");
211 for (ARTIFACT_TYPE artType : currentCase.
getSleuthkitCase().getBlackboardArtifactTypesInUse()) {
212 if(artType.equals(BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT)) {
217 for (BlackboardArtifact artifact : currentCase.
getSleuthkitCase().getBlackboardArtifacts(artType)) {
218 if (dataSourceIds.contains(artifact.getDataSource().getId())) {
220 for (JsonElement element : exporter.exportBlackboardArtifact(artifact)) {
221 gson.toJson(element, reportWriter);
223 }
catch (ContentNotExportableException ex) {
224 logger.log(Level.INFO, String.format(
"Unable to export blackboard artifact (id: %d, type: %d) to CASE/UCO. "
225 +
"The artifact type is either not supported or the artifact instance does not have any "
226 +
"exportable attributes.", artifact.getId(), artType.getTypeID()));
227 }
catch (BlackboardJsonAttrUtil.InvalidJsonException ex) {
228 logger.log(Level.WARNING, String.format(
"Artifact instance (id: %d, type: %d) contained a "
229 +
"malformed json attribute.", artifact.getId(), artType.getTypeID()), ex);
235 reportWriter.endArray();
236 reportWriter.endObject();
239 currentCase.
addReport(caseJsonReportFile.toString(),
240 Bundle.CaseUcoReportModule_srcModuleName(),
243 }
catch (IOException ex) {
244 logger.log(Level.WARNING,
"I/O error encountered while generating the report.", ex);
246 Bundle.CaseUcoReportModule_ioError());
248 logger.log(Level.WARNING,
"No case open.", ex);
250 Bundle.CaseUcoReportModule_noCaseOpen());
251 }
catch (TskCoreException ex) {
252 logger.log(Level.WARNING,
"TskCoreException encounted while generating the report.", ex);
254 String.format(Bundle.CaseUcoReportModule_tskCoreException(), ex.toString()));
264 return currentCase.getSleuthkitCase().getDataSources().stream()
265 .filter((dataSource) -> {
272 .collect(Collectors.toList());
288 Gson gson, CaseUcoExporter exporter, JsonWriter reportWriter)
throws IOException, TskCoreException {
290 Deque<Content> stack =
new ArrayDeque<>();
291 stack.addAll(dataSource.getChildren());
294 while (!stack.isEmpty()) {
295 Content current = stack.pop();
296 if (current instanceof AbstractFile) {
297 AbstractFile file = (AbstractFile) (current);
298 if (SUPPORTED_TYPES.contains(file.getMetaType().getValue())) {
300 for (JsonElement element : exporter.exportAbstractFile(file)) {
301 gson.toJson(element, reportWriter);
306 for (Content child : current.getChildren()) {
void warnIngest(ReportProgressPanel progressPanel)
static synchronized IngestManager getInstance()
void performDepthFirstSearch(DataSource dataSource, Gson gson, CaseUcoExporter exporter, JsonWriter reportWriter)
static final Set< Short > SUPPORTED_TYPES
void complete(ReportStatus reportStatus)
boolean isIngestRunning()
void addReport(String localPath, String srcModuleName, String reportName)
JPanel getConfigurationPanel()
static final String REPORT_FILE_NAME
void setIndeterminate(boolean indeterminate)
static final String EXTENSION
boolean supportsDataSourceSelection()
static final CaseUcoReportModule SINGLE_INSTANCE
static final Logger logger
void setMaximumProgress(int max)
void generateReport(GeneralReportSettings settings, ReportProgressPanel progressPanel)
SleuthkitCase getSleuthkitCase()
String getRelativeFilePath()
static String getReportFileName()
static synchronized CaseUcoReportModule getDefault()
List< Long > getSelectedDataSources()
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
void updateStatusLabel(String statusMessage)
Void create(ProgressIndicator progressIndicator, Object additionalParams)
List< DataSource > getSelectedDataSources(Case currentCase, GeneralReportSettings settings)
String getReportDirectoryPath()
void setProgress(int value)