19 package org.sleuthkit.autopsy.report.modules.portablecase;
21 import com.google.common.collect.ArrayListMultimap;
22 import com.google.common.collect.Multimap;
23 import com.google.gson.Gson;
24 import com.google.gson.GsonBuilder;
25 import com.google.gson.JsonElement;
26 import com.google.gson.stream.JsonWriter;
28 import java.util.logging.Level;
29 import java.io.BufferedReader;
31 import java.io.FileOutputStream;
32 import java.io.FileWriter;
33 import java.io.InputStreamReader;
34 import java.io.IOException;
35 import java.io.OutputStream;
36 import java.io.OutputStreamWriter;
37 import java.nio.file.Files;
38 import java.nio.file.Path;
39 import java.nio.file.Paths;
40 import java.sql.ResultSet;
41 import java.sql.SQLException;
42 import java.util.ArrayList;
43 import java.util.Arrays;
44 import java.util.HashMap;
45 import java.util.List;
47 import org.apache.commons.io.FileUtils;
48 import org.openide.modules.InstalledFileLocator;
49 import org.openide.util.NbBundle;
75 import org.
sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction;
77 import org.
sleuthkit.datamodel.TaggingManager.ContentTagChange;
129 "PortableCaseReportModule.getName.name=Portable Case"
133 return Bundle.PortableCaseReportModule_getName_name();
137 "PortableCaseReportModule.getDescription.description=Copies selected items to a new single-user case that can be easily shared"
141 return Bundle.PortableCaseReportModule_getDescription_description();
161 logger.log(Level.INFO,
"Portable case creation canceled by user");
179 logger.log(Level.WARNING, logWarning);
181 logger.log(Level.SEVERE, logWarning, ex);
189 "PortableCaseReportModule.generateReport.verifying=Verifying selected parameters...",
190 "PortableCaseReportModule.generateReport.creatingCase=Creating portable case database...",
191 "PortableCaseReportModule.generateReport.copyingTags=Copying tags...",
193 "PortableCaseReportModule.generateReport.copyingFiles=Copying files tagged as {0}...",
195 "PortableCaseReportModule.generateReport.copyingArtifacts=Copying artifacts tagged as {0}...",
196 "# {0} - output folder",
197 "PortableCaseReportModule.generateReport.outputDirDoesNotExist=Output folder {0} does not exist",
198 "# {0} - output folder",
199 "PortableCaseReportModule.generateReport.outputDirIsNotDir=Output folder {0} is not a folder",
200 "PortableCaseReportModule.generateReport.caseClosed=Current case has been closed",
201 "PortableCaseReportModule.generateReport.interestingItemError=Error loading intersting items",
202 "PortableCaseReportModule.generateReport.errorReadingTags=Error while reading tags from case database",
203 "PortableCaseReportModule.generateReport.errorReadingSets=Error while reading interesting items sets from case database",
204 "PortableCaseReportModule.generateReport.noContentToCopy=No interesting files, results, or tagged items to copy",
205 "PortableCaseReportModule.generateReport.errorCopyingTags=Error copying tags",
206 "PortableCaseReportModule.generateReport.errorCopyingFiles=Error copying tagged files",
207 "PortableCaseReportModule.generateReport.errorCopyingArtifacts=Error copying tagged artifacts",
208 "PortableCaseReportModule.generateReport.errorCopyingInterestingFiles=Error copying interesting files",
209 "PortableCaseReportModule.generateReport.errorCopyingInterestingResults=Error copying interesting results",
210 "PortableCaseReportModule.generateReport.errorCreatingImageTagTable=Error creating image tags table",
211 "PortableCaseReportModule.generateReport.errorCopyingAutopsy=Error copying application",
212 "# {0} - attribute type name",
213 "PortableCaseReportModule.generateReport.errorLookingUpAttrType=Error looking up attribute type {0}",
214 "PortableCaseReportModule.generateReport.compressingCase=Compressing case...",
215 "PortableCaseReportModule_generateReport_copyingAutopsy=Copying application..."
219 this.settings = options;
221 progressPanel.
start();
222 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateReport_verifying());
228 File outputDir =
new File(reportPath);
229 if (!outputDir.exists()) {
230 handleError(
"Output folder " + outputDir.toString() +
" does not exist",
231 Bundle.PortableCaseReportModule_generateReport_outputDirDoesNotExist(outputDir.toString()), null, progressPanel);
235 if (!outputDir.isDirectory()) {
236 handleError(
"Output folder " + outputDir.toString() +
" is not a folder",
237 Bundle.PortableCaseReportModule_generateReport_outputDirIsNotDir(outputDir.toString()), null, progressPanel);
247 Bundle.PortableCaseReportModule_generateReport_caseClosed(), null, progressPanel);
253 outputDir = Paths.get(outputDir.toString(),
caseName).toFile();
256 List<TagName> tagNames;
262 Bundle.PortableCaseReportModule_generateReport_errorReadingTags(), ex, progressPanel);
269 List<String> setNames;
274 handleError(
"Unable to get all interesting items sets",
275 Bundle.PortableCaseReportModule_generateReport_errorReadingSets(), ex, progressPanel);
282 if (tagNames.isEmpty() && setNames.isEmpty()) {
284 Bundle.PortableCaseReportModule_generateReport_noContentToCopy(), null, progressPanel);
290 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateReport_creatingCase());
292 if (portableSkCase == null) {
306 }
catch (TskCoreException ex) {
307 handleError(
"Error creating image tag table", Bundle.PortableCaseReportModule_generateReport_errorCreatingImageTagTable(), ex, progressPanel);
312 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateReport_copyingTags());
314 for (TagName tagName : tagNames) {
315 TagName newTagName = portableSkCase.addOrUpdateTagName(tagName.getDisplayName(), tagName.getDescription(), tagName.getColor(), tagName.getKnownStatus());
316 oldTagNameToNewTagName.put(tagName, newTagName);
318 }
catch (TskCoreException ex) {
319 handleError(
"Error copying tags", Bundle.PortableCaseReportModule_generateReport_errorCopyingTags(), ex, progressPanel);
324 for (BlackboardArtifact.ARTIFACT_TYPE type : BlackboardArtifact.ARTIFACT_TYPE.values()) {
325 oldArtTypeIdToNewArtTypeId.put(type.getTypeID(), type.getTypeID());
327 for (BlackboardAttribute.ATTRIBUTE_TYPE type : BlackboardAttribute.ATTRIBUTE_TYPE.values()) {
330 }
catch (TskCoreException ex) {
331 handleError(
"Error looking up attribute name " + type.getLabel(),
332 Bundle.PortableCaseReportModule_generateReport_errorLookingUpAttrType(type.getLabel()),
339 for (TagName tagName : tagNames) {
345 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateReport_copyingFiles(tagName.getDisplayName()));
354 }
catch (TskCoreException ex) {
355 handleError(
"Error copying tagged files", Bundle.PortableCaseReportModule_generateReport_errorCopyingFiles(), ex, progressPanel);
361 for (TagName tagName : tagNames) {
367 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateReport_copyingArtifacts(tagName.getDisplayName()));
376 }
catch (TskCoreException ex) {
377 handleError(
"Error copying tagged artifacts", Bundle.PortableCaseReportModule_generateReport_errorCopyingArtifacts(), ex, progressPanel);
382 if (!setNames.isEmpty()) {
384 List<BlackboardArtifact> interestingFiles = currentCase.
getSleuthkitCase().getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT);
385 for (BlackboardArtifact art : interestingFiles) {
392 BlackboardAttribute setAttr = art.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME));
393 if (setNames.contains(setAttr.getValueString())) {
397 }
catch (TskCoreException ex) {
398 handleError(
"Error copying interesting files", Bundle.PortableCaseReportModule_generateReport_errorCopyingInterestingFiles(), ex, progressPanel);
403 List<BlackboardArtifact> interestingResults = currentCase.
getSleuthkitCase().getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT);
404 for (BlackboardArtifact art : interestingResults) {
410 BlackboardAttribute setAttr = art.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME));
411 if (setNames.contains(setAttr.getValueString())) {
415 }
catch (TskCoreException ex) {
416 handleError(
"Error copying interesting results", Bundle.PortableCaseReportModule_generateReport_errorCopyingInterestingResults(), ex, progressPanel);
432 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateReport_copyingAutopsy());
435 }
catch (IOException ex) {
436 handleError(
"Error copying autopsy", Bundle.PortableCaseReportModule_generateReport_errorCopyingAutopsy(), ex, progressPanel);
442 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateReport_compressingCase());
475 "PortableCaseReportModule.generateCaseUcoReport.errorCreatingReportFolder=Could not make report folder",
476 "PortableCaseReportModule.generateCaseUcoReport.errorGeneratingCaseUcoReport=Problem while generating CASE-UCO report",
477 "PortableCaseReportModule.generateCaseUcoReport.startCaseUcoReportGeneration=Creating a CASE-UCO report of the portable case",
478 "PortableCaseReportModule.generateCaseUcoReport.successCaseUcoReportGeneration=Successfully created a CASE-UCO report of the portable case"
482 Path reportsDirectory = Paths.get(caseFolder.toString(),
"Reports");
483 if (!reportsDirectory.toFile().mkdir()) {
484 logger.log(Level.SEVERE,
"Could not make the report folder... skipping "
485 +
"CASE-UCO report generation for the portable case");
489 Path reportFile = reportsDirectory.resolve(CASE_UCO_FILE_NAME);
491 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateCaseUcoReport_startCaseUcoReportGeneration());
492 try (OutputStream stream =
new FileOutputStream(reportFile.toFile());
493 JsonWriter reportWriter =
new JsonWriter(
new OutputStreamWriter(stream,
"UTF-8"))) {
494 Gson gson =
new GsonBuilder().setPrettyPrinting().create();
495 reportWriter.setIndent(
" ");
496 reportWriter.beginObject();
497 reportWriter.name(
"@graph");
498 reportWriter.beginArray();
506 Path tmpDir = Paths.get(caseTempDirectory, CASE_UCO_TMP_DIR);
507 FileUtils.deleteDirectory(tmpDir.toFile());
508 Files.createDirectory(tmpDir);
510 CaseUcoExporter exporter =
new CaseUcoExporter(currentCase.
getSleuthkitCase());
511 for (JsonElement element : exporter.exportSleuthkitCase()) {
512 gson.toJson(element, reportWriter);
521 for (DataSource dataSource : currentCase.
getSleuthkitCase().getDataSources()) {
524 boolean dataSourceHasBeenIncluded =
false;
527 for (TagName tagName : tagNames) {
530 dataSource, tmpDir, gson, exporter, reportWriter, dataSourceHasBeenIncluded);
534 dataSource, tmpDir, gson, exporter, reportWriter, dataSourceHasBeenIncluded);
538 for (BlackboardArtifact bArt : artifactsWithSetName.get(dataSource.getId())) {
539 Content sourceContent = bArt.getParent();
540 dataSourceHasBeenIncluded |=
addUniqueFile(sourceContent, dataSource,
541 tmpDir, gson, exporter, reportWriter, dataSourceHasBeenIncluded);
546 reportWriter.endArray();
547 reportWriter.endObject();
548 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateCaseUcoReport_successCaseUcoReportGeneration());
549 }
catch (IOException | TskCoreException ex) {
550 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateCaseUcoReport_errorGeneratingCaseUcoReport());
551 logger.log(Level.SEVERE,
"Error encountered while trying to create "
552 +
"CASE-UCO output for portable case.. the portable case will be "
553 +
"completed without a CASE-UCO report.", ex);
563 Multimap<Long, BlackboardArtifact> artifactsWithSetName = ArrayListMultimap.create();
564 if (!setNames.isEmpty()) {
565 List<BlackboardArtifact> allArtifacts = skCase.getBlackboardArtifacts(
566 BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT);
567 allArtifacts.addAll(skCase.getBlackboardArtifacts(
568 BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT));
570 for (BlackboardArtifact bArt : allArtifacts) {
571 BlackboardAttribute setAttr = bArt.getAttribute(
572 new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME));
573 if (setNames.contains(setAttr.getValueString())) {
574 artifactsWithSetName.put(bArt.getDataSource().getId(), bArt);
578 return artifactsWithSetName;
602 Path tmpDir, Gson gson, CaseUcoExporter exporter, JsonWriter reportWriter,
603 boolean dataSourceHasBeenIncluded)
throws IOException, TskCoreException {
604 if (content instanceof AbstractFile && !(content instanceof DataSource)) {
605 AbstractFile absFile = (AbstractFile) content;
606 Path filePath = tmpDir.resolve(Long.toString(absFile.getId()));
607 if (!absFile.isDir() && !Files.exists(filePath)) {
608 if (!dataSourceHasBeenIncluded) {
609 for (JsonElement element : exporter.exportDataSource(dataSource)) {
610 gson.toJson(element, reportWriter);
615 for (JsonElement element : exporter.exportAbstractFile(absFile, Paths.get(FILE_FOLDER_NAME, subFolder, fileName).toString())) {
616 gson.toJson(element, reportWriter);
618 Files.createFile(filePath);
628 List<String> setNames =
new ArrayList<>();
629 Map<String, Long> setCounts;
633 String innerSelect =
"SELECT (value_text) AS set_name FROM blackboard_attributes WHERE (artifact_type_id = '"
634 + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() +
"' OR artifact_type_id = '"
635 + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID() +
"') AND attribute_type_id = '"
636 + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() +
"'";
639 String query =
"set_name, count(1) AS set_count FROM (" + innerSelect +
") set_names GROUP BY set_name";
644 setNames.addAll(setCounts.keySet());
656 "# {0} - case folder",
657 "PortableCaseReportModule.createCase.caseDirExists=Case folder {0} already exists",
658 "PortableCaseReportModule.createCase.errorCreatingCase=Error creating case",
660 "PortableCaseReportModule.createCase.errorCreatingFolder=Error creating folder {0}",
661 "PortableCaseReportModule.createCase.errorStoringMaxIds=Error storing maximum database IDs",})
665 caseFolder = Paths.get(outputDir.toString(),
caseName).toFile();
667 if (caseFolder.exists()) {
668 handleError(
"Case folder " + caseFolder.toString() +
" already exists",
669 Bundle.PortableCaseReportModule_createCase_caseDirExists(caseFolder.toString()), null, progressPanel);
676 }
catch (TskCoreException ex) {
677 handleError(
"Error creating case " + caseName +
" in folder " + caseFolder.toString(),
678 Bundle.PortableCaseReportModule_createCase_errorCreatingCase(), ex, progressPanel);
685 }
catch (TskCoreException ex) {
687 Bundle.PortableCaseReportModule_createCase_errorStoringMaxIds(), ex, progressPanel);
692 copiedFilesFolder = Paths.get(caseFolder.toString(),
FILE_FOLDER_NAME).toFile();
693 if (!copiedFilesFolder.mkdir()) {
694 handleError(
"Error creating folder " + copiedFilesFolder.toString(),
695 Bundle.PortableCaseReportModule_createCase_errorCreatingFolder(copiedFilesFolder.toString()), null, progressPanel);
701 File subFolder = Paths.get(copiedFilesFolder.toString(), cat.getDisplayName()).toFile();
702 if (!subFolder.mkdir()) {
703 handleError(
"Error creating folder " + subFolder.toString(),
704 Bundle.PortableCaseReportModule_createCase_errorCreatingFolder(subFolder.toString()), null, progressPanel);
709 if (!unknownTypeFolder.mkdir()) {
710 handleError(
"Error creating folder " + unknownTypeFolder.toString(),
711 Bundle.PortableCaseReportModule_createCase_errorCreatingFolder(unknownTypeFolder.toString()), null, progressPanel);
724 CaseDbAccessManager currentCaseDbManager = currentCase.
getSleuthkitCase().getCaseDbAccessManager();
726 String tableSchema =
"( table_name TEXT PRIMARY KEY, "
729 portableSkCase.getCaseDbAccessManager().createTable(MAX_ID_TABLE_NAME, tableSchema);
731 currentCaseDbManager.select(
"max(obj_id) as max_id from tsk_objects",
new StoreMaxIdCallback(
"tsk_objects"));
732 currentCaseDbManager.select(
"max(tag_id) as max_id from content_tags",
new StoreMaxIdCallback(
"content_tags"));
733 currentCaseDbManager.select(
"max(tag_id) as max_id from blackboard_artifact_tags",
new StoreMaxIdCallback(
"blackboard_artifact_tags"));
734 currentCaseDbManager.select(
"max(examiner_id) as max_id from tsk_examiners",
new StoreMaxIdCallback(
"tsk_examiners"));
747 CaseDbAccessManager portableDbAccessManager = portableSkCase.getCaseDbAccessManager();
767 for (ContentTag tag : tags) {
774 Content content = tag.getContent();
775 if (content instanceof AbstractFile) {
780 if (!oldTagNameToNewTagName.containsKey(tag.getName())) {
781 throw new TskCoreException(
"TagName map is missing entry for ID " + tag.getName().getId() +
" with display name " + tag.getName().getDisplayName());
783 ContentTagChange newContentTag = portableSkCase.getTaggingManager().addContentTag(newIdToContent.get(newFileId), oldTagNameToNewTagName.get(tag.getName()), tag.getComment(), tag.getBeginByteOffset(), tag.getEndByteOffset());
788 if (!appData.isEmpty()) {
809 currentCase.
getSleuthkitCase().getCaseDbAccessManager().select(query, callback);
810 return callback.getAppData();
826 appData = rs.getString(
"app_data");
827 }
catch (SQLException ex) {
828 logger.log(Level.WARNING,
"Unable to get app_data from result set", ex);
831 }
catch (SQLException ex) {
832 logger.log(Level.WARNING,
"Failed to get next result for app_data", ex);
841 String getAppData() {
855 String insert =
"(content_tag_id, app_data) VALUES (" + newContentTag.getId() +
", '" + appData +
"')";
872 for (BlackboardArtifactTag tag : tags) {
880 Content content = tag.getContent();
884 BlackboardArtifact newArtifact =
copyArtifact(newContentId, tag.getArtifact());
887 if (!oldTagNameToNewTagName.containsKey(tag.getName())) {
888 throw new TskCoreException(
"TagName map is missing entry for ID " + tag.getName().getId() +
" with display name " + tag.getName().getDisplayName());
890 portableSkCase.getTaggingManager().addArtifactTag(newArtifact, oldTagNameToNewTagName.get(tag.getName()), tag.getComment());
906 private BlackboardArtifact
copyArtifact(
long newContentId, BlackboardArtifact artifactToCopy)
throws TskCoreException {
908 if (oldArtifactIdToNewArtifact.containsKey(artifactToCopy.getArtifactID())) {
909 return oldArtifactIdToNewArtifact.get(artifactToCopy.getArtifactID());
913 BlackboardAttribute oldAssociatedAttribute = artifactToCopy.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
914 List<BlackboardAttribute> newAttrs =
new ArrayList<>();
915 if (oldAssociatedAttribute != null) {
916 BlackboardArtifact oldAssociatedArtifact = currentCase.
getSleuthkitCase().getBlackboardArtifact(oldAssociatedAttribute.getValueLong());
917 BlackboardArtifact newAssociatedArtifact =
copyArtifact(newContentId, oldAssociatedArtifact);
918 newAttrs.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
919 String.join(
",", oldAssociatedAttribute.getSources()), newAssociatedArtifact.getArtifactID()));
924 BlackboardArtifact newArtifact = portableSkCase.newBlackboardArtifact(newArtifactTypeId, newContentId);
925 List<BlackboardAttribute> oldAttrs = artifactToCopy.getAttributes();
928 for (BlackboardAttribute oldAttr : oldAttrs) {
931 if (oldAttr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
936 switch (oldAttr.getValueType()) {
938 newAttrs.add(
new BlackboardAttribute(newAttributeType, String.join(
",", oldAttr.getSources()),
939 oldAttr.getValueBytes()));
942 newAttrs.add(
new BlackboardAttribute(newAttributeType, String.join(
",", oldAttr.getSources()),
943 oldAttr.getValueDouble()));
946 newAttrs.add(
new BlackboardAttribute(newAttributeType, String.join(
",", oldAttr.getSources()),
947 oldAttr.getValueInt()));
951 newAttrs.add(
new BlackboardAttribute(newAttributeType, String.join(
",", oldAttr.getSources()),
952 oldAttr.getValueLong()));
956 newAttrs.add(
new BlackboardAttribute(newAttributeType, String.join(
",", oldAttr.getSources()),
957 oldAttr.getValueString()));
960 throw new TskCoreException(
"Unexpected attribute value type found: " + oldAttr.getValueType().getLabel());
964 newArtifact.addAttributes(newAttrs);
966 oldArtifactIdToNewArtifact.put(artifactToCopy.getArtifactID(), newArtifact);
980 if (oldArtTypeIdToNewArtTypeId.containsKey(oldArtifact.getArtifactTypeID())) {
981 return oldArtTypeIdToNewArtTypeId.get(oldArtifact.getArtifactTypeID());
984 BlackboardArtifact.Type oldCustomType = currentCase.
getSleuthkitCase().getArtifactType(oldArtifact.getArtifactTypeName());
986 BlackboardArtifact.Type newCustomType = portableSkCase.addBlackboardArtifactType(oldCustomType.getTypeName(), oldCustomType.getDisplayName());
987 oldArtTypeIdToNewArtTypeId.put(oldArtifact.getArtifactTypeID(), newCustomType.getTypeID());
988 return newCustomType.getTypeID();
989 }
catch (TskDataException ex) {
990 throw new TskCoreException(
"Error creating new artifact type " + oldCustomType.getTypeName(), ex);
1003 private BlackboardAttribute.Type
getNewAttributeType(BlackboardAttribute oldAttribute)
throws TskCoreException {
1004 BlackboardAttribute.Type oldAttrType = oldAttribute.getAttributeType();
1010 BlackboardAttribute.Type newCustomType = portableSkCase.addArtifactAttributeType(oldAttrType.getTypeName(),
1011 oldAttrType.getValueType(), oldAttrType.getDisplayName());
1013 return newCustomType;
1014 }
catch (TskDataException ex) {
1015 throw new TskCoreException(
"Error creating new attribute type " + oldAttrType.getTypeName(), ex);
1029 @NbBundle.Messages({
1030 "# {0} - File name",
1031 "PortableCaseReportModule.copyContentToPortableCase.copyingFile=Copying file {0}",})
1033 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_copyContentToPortableCase_copyingFile(content.getUniquePath()));
1049 if (oldIdToNewContent.containsKey(content.getId())) {
1050 return oldIdToNewContent.get(content.getId()).getId();
1057 if (content.getParent() != null) {
1062 if (content instanceof BlackboardArtifact) {
1063 BlackboardArtifact artifactToCopy = (BlackboardArtifact) content;
1066 CaseDbTransaction trans = portableSkCase.beginTransaction();
1068 if (content instanceof Image) {
1069 Image image = (Image) content;
1070 newContent = portableSkCase.addImage(image.getType(), image.getSsize(), image.getSize(), image.getName(),
1071 new ArrayList<>(), image.getTimeZone(), image.getMd5(), image.getSha1(), image.getSha256(), image.getDeviceId(), trans);
1072 }
else if (content instanceof VolumeSystem) {
1073 VolumeSystem vs = (VolumeSystem) content;
1074 newContent = portableSkCase.addVolumeSystem(parentId, vs.getType(), vs.getOffset(), vs.getBlockSize(), trans);
1075 }
else if (content instanceof Volume) {
1076 Volume vs = (Volume) content;
1077 newContent = portableSkCase.addVolume(parentId, vs.getAddr(), vs.getStart(), vs.getLength(),
1078 vs.getDescription(), vs.getFlags(), trans);
1079 }
else if (content instanceof Pool) {
1080 Pool pool = (Pool) content;
1081 newContent = portableSkCase.addPool(parentId, pool.getType(), trans);
1082 }
else if (content instanceof FileSystem) {
1083 FileSystem fs = (FileSystem) content;
1084 newContent = portableSkCase.addFileSystem(parentId, fs.getImageOffset(), fs.getFsType(), fs.getBlock_size(),
1085 fs.getBlock_count(), fs.getRoot_inum(), fs.getFirst_inum(), fs.getLastInum(),
1086 fs.getName(), trans);
1087 }
else if (content instanceof BlackboardArtifact) {
1088 BlackboardArtifact artifactToCopy = (BlackboardArtifact) content;
1090 }
else if (content instanceof AbstractFile) {
1091 AbstractFile abstractFile = (AbstractFile) content;
1093 if (abstractFile instanceof LocalFilesDataSource) {
1094 LocalFilesDataSource localFilesDS = (LocalFilesDataSource) abstractFile;
1095 newContent = portableSkCase.addLocalFilesDataSource(localFilesDS.getDeviceId(), localFilesDS.getName(), localFilesDS.getTimeZone(), trans);
1097 if (abstractFile.isDir()) {
1098 newContent = portableSkCase.addLocalDirectory(parentId, abstractFile.getName(), trans);
1104 File exportFolder = Paths.get(copiedFilesFolder.toString(), exportSubFolder).toFile();
1105 File localFile =
new File(exportFolder, fileName);
1109 Content oldParent = abstractFile.getParent();
1110 if (!oldIdToNewContent.containsKey(oldParent.getId())) {
1111 throw new TskCoreException(
"Parent of file with ID " + abstractFile.getId() +
" has not been created");
1113 Content newParent = oldIdToNewContent.get(oldParent.getId());
1116 String relativePath = FILE_FOLDER_NAME + File.separator + exportSubFolder + File.separator + fileName;
1118 newContent = portableSkCase.addLocalFile(abstractFile.getName(), relativePath, abstractFile.getSize(),
1119 abstractFile.getCtime(), abstractFile.getCrtime(), abstractFile.getAtime(), abstractFile.getMtime(),
1120 abstractFile.getMd5Hash(), abstractFile.getKnown(), abstractFile.getMIMEType(),
1121 true, TskData.EncodingType.NONE,
1123 }
catch (IOException ex) {
1124 throw new TskCoreException(
"Error copying file " + abstractFile.getName() +
" with original obj ID "
1125 + abstractFile.getId(), ex);
1130 throw new TskCoreException(
"Trying to copy unexpected Content type " + content.getClass().getName());
1133 }
catch (TskCoreException ex) {
1140 oldIdToNewContent.put(content.getId(), newContent);
1141 newIdToContent.put(newContent.getId(), newContent);
1142 return oldIdToNewContent.get(content.getId()).getId();
1153 if (abstractFile.getMIMEType() == null || abstractFile.getMIMEType().isEmpty()) {
1158 if (cat.getMediaTypes().contains(abstractFile.getMIMEType())) {
1159 return cat.getDisplayName();
1184 return Paths.get(installPath,
"bin", exeName);
1194 return appName +
"64.exe";
1205 private void copyApplication(Path sourceFolder, String destBaseFolder)
throws IOException {
1209 if (!destAppFolder.toFile().exists() && !destAppFolder.toFile().mkdirs()) {
1210 throw new IOException(
"Failed to create directory " + destAppFolder.toString());
1214 FileUtils.copyDirectory(sourceFolder.toFile(), destAppFolder.toFile());
1225 Path filePath = Paths.get(destBaseFolder,
"open.bat");
1228 String casePath =
"..\\" +
caseName;
1229 try (FileWriter writer =
new FileWriter(filePath.toFile())) {
1230 writer.write(exePath +
" \"" + casePath +
"\"");
1238 oldIdToNewContent.clear();
1239 newIdToContent.clear();
1240 oldTagNameToNewTagName.clear();
1241 oldArtTypeIdToNewArtTypeId.clear();
1243 oldArtifactIdToNewArtifact.clear();
1249 copiedFilesFolder = null;
1256 if (portableSkCase != null) {
1257 portableSkCase.close();
1258 portableSkCase = null;
1280 Long maxId = rs.getLong(
"max_id");
1281 String query =
" (table_name, max_id) VALUES ('" + tableName +
"', '" + maxId +
"')";
1282 portableSkCase.getCaseDbAccessManager().insert(MAX_ID_TABLE_NAME, query);
1284 }
catch (SQLException ex) {
1285 logger.log(Level.WARNING,
"Unable to get maximum ID from result set", ex);
1286 }
catch (TskCoreException ex) {
1287 logger.log(Level.WARNING,
"Unable to save maximum ID from result set", ex);
1291 }
catch (SQLException ex) {
1292 logger.log(Level.WARNING,
"Failed to get maximum ID from result set", ex);
1297 @NbBundle.Messages({
1298 "PortableCaseReportModule.compressCase.errorFinding7zip=Could not locate 7-Zip executable",
1299 "# {0} - Temp folder path",
1300 "PortableCaseReportModule.compressCase.errorCreatingTempFolder=Could not create temporary folder {0}",
1301 "PortableCaseReportModule.compressCase.errorCompressingCase=Error compressing case",
1302 "PortableCaseReportModule.compressCase.canceled=Compression canceled by user",})
1308 Path dirToCompress = Paths.get(folderToCompress);
1309 File tempZipFolder = Paths.get(dirToCompress.getParent().toString(),
"temp",
"portableCase" + System.currentTimeMillis()).toFile();
1310 if (!tempZipFolder.mkdirs()) {
1311 handleError(
"Error creating temporary folder " + tempZipFolder.toString(),
1312 Bundle.PortableCaseReportModule_compressCase_errorCreatingTempFolder(tempZipFolder.toString()), null, progressPanel);
1318 if (sevenZipExe == null) {
1319 handleError(
"Error finding 7-Zip exectuable", Bundle.PortableCaseReportModule_compressCase_errorFinding7zip(), null, progressPanel);
1324 String chunkOption =
"";
1329 File zipFile = Paths.get(tempZipFolder.getAbsolutePath(), caseName +
".zip").toFile();
1330 ProcessBuilder procBuilder =
new ProcessBuilder();
1331 procBuilder.command(
1332 sevenZipExe.getAbsolutePath(),
1334 zipFile.getAbsolutePath(),
1335 dirToCompress.toAbsolutePath().toString(),
1340 Process process = procBuilder.start();
1342 while (process.isAlive()) {
1349 int exitCode = process.exitValue();
1350 if (exitCode != 0) {
1352 StringBuilder sb =
new StringBuilder();
1353 try (BufferedReader br =
new BufferedReader(
new InputStreamReader(process.getErrorStream()))) {
1355 while ((line = br.readLine()) != null) {
1356 sb.append(line).append(System.getProperty(
"line.separator"));
1360 handleError(
"Error compressing case\n7-Zip output: " + sb.toString(), Bundle.PortableCaseReportModule_compressCase_errorCompressingCase(), null, progressPanel);
1363 }
catch (IOException | InterruptedException ex) {
1364 handleError(
"Error compressing case", Bundle.PortableCaseReportModule_compressCase_errorCompressingCase(), ex, progressPanel);
1370 FileUtils.cleanDirectory(dirToCompress.toFile());
1371 FileUtils.copyDirectory(tempZipFolder, dirToCompress.toFile());
1372 FileUtils.deleteDirectory(
new File(tempZipFolder.getParent()));
1373 }
catch (IOException ex) {
1374 handleError(
"Error compressing case", Bundle.PortableCaseReportModule_compressCase_errorCompressingCase(), ex, progressPanel);
1391 String executableToFindName = Paths.get(
"7-Zip",
"7z.exe").toString();
1393 if (null == exeFile) {
1397 if (!exeFile.canExecute()) {
1410 private final Map<String, Long>
setCounts =
new HashMap<>();
1417 Long setCount = rs.getLong(
"set_count");
1418 String setName = rs.getString(
"set_name");
1420 setCounts.put(setName, setCount);
1422 }
catch (SQLException ex) {
1423 logger.log(Level.WARNING,
"Unable to get data_source_obj_id or value from result set", ex);
1426 }
catch (SQLException ex) {
1427 logger.log(Level.WARNING,
"Failed to get next result for values by datasource", ex);
boolean includeApplication()
final Map< Integer, Integer > oldArtTypeIdToNewArtTypeId
void handleError(String logWarning, String dialogWarning, Exception ex, ReportProgressPanel progressPanel)
long copyContent(Content content)
static final Logger logger
int getNewArtifactTypeId(BlackboardArtifact oldArtifact)
static final List< FileTypeCategory > FILE_TYPE_CATEGORIES
static final String MAX_ID_TABLE_NAME
void process(ResultSet rs)
final Map< TagName, TagName > oldTagNameToNewTagName
final Map< Long, Content > oldIdToNewContent
final Map< Long, BlackboardArtifact > oldArtifactIdToNewArtifact
PortableCaseReportModule()
String getTempDirectory()
String getAutopsyExeName()
long copyContentToPortableCase(Content content, ReportProgressPanel progressPanel)
void addArtifactsToPortableCase(TagName oldTagName, ReportProgressPanel progressPanel)
static final String FILE_FOLDER_NAME
final Map< Integer, BlackboardAttribute.Type > oldAttrTypeIdToNewAttrType
static String getAppName()
void process(ResultSet rs)
void complete(ReportStatus reportStatus)
List< TagName > getSelectedTagNames()
Map< String, Long > getSetCountMap()
static File locate7ZipExecutable()
Multimap< Long, BlackboardArtifact > getInterestingArtifactsBySetName(SleuthkitCase skCase, List< String > setNames)
static< T > long writeToFile(Content content, java.io.File outputFile, ProgressHandle progress, Future< T > worker, boolean source)
void closePortableCaseDatabase()
List< String > getAllInterestingItemsSets()
void createAppLaunchBatFile(String destBaseFolder)
static final String UNKNOWN_FILE_TYPE_FOLDER
Logger(String name, String resourceBundleName)
void setIndeterminate(boolean indeterminate)
BlackboardAttribute.Type getNewAttributeType(BlackboardAttribute oldAttribute)
void addFilesToPortableCase(TagName oldTagName, ReportProgressPanel progressPanel)
void generateReport(String reportPath, PortableCaseReportModuleSettings options, ReportProgressPanel progressPanel)
String getRelativeFilePath()
TagsManager getTagsManager()
static final String CASE_UCO_TMP_DIR
void initializeImageTags(ReportProgressPanel progressPanel)
String getExportSubfolder(AbstractFile abstractFile)
static final String TABLE_SCHEMA_SQLITE
final Map< Long, Content > newIdToContent
SleuthkitCase portableSkCase
static final String TABLE_NAME
final Map< String, Long > setCounts
SleuthkitCase getSleuthkitCase()
List< String > getSelectedSetNames()
BlackboardArtifact copyArtifact(long newContentId, BlackboardArtifact artifactToCopy)
void generateCaseUcoReport(List< TagName > tagNames, List< String > setNames, ReportProgressPanel progressPanel)
void copyApplication(Path sourceFolder, String destBaseFolder)
SleuthkitCase createPortableCase(String caseName, File portableCaseFolder)
boolean areAllTagsSelected()
boolean addUniqueFile(Content content, DataSource dataSource, Path tmpDir, Gson gson, CaseUcoExporter exporter, JsonWriter reportWriter, boolean dataSourceHasBeenIncluded)
static String escapeFileName(String fileName)
boolean compressCase(ReportProgressPanel progressPanel, String folderToCompress)
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
void updateStatusLabel(String statusMessage)
String getImageTagDataForContentTag(ContentTag tag)
static final String CASE_UCO_FILE_NAME
String getSevenZipParam()
boolean areAllSetsSelected()
void addImageTagToPortableCase(ContentTag newContentTag, String appData)
void handleCancellation(ReportProgressPanel progressPanel)
Path getApplicationBasePath()
void createCase(File outputDir, ReportProgressPanel progressPanel)
void process(ResultSet rs)
PortableCaseReportModuleSettings settings