19 package org.sleuthkit.autopsy.report.modules.portablecase;
21 import com.google.common.collect.ArrayListMultimap;
22 import com.google.common.collect.Multimap;
24 import java.util.logging.Level;
25 import java.io.BufferedReader;
27 import java.io.InputStreamReader;
28 import java.io.IOException;
29 import java.nio.file.Files;
30 import java.nio.file.Path;
31 import java.nio.file.Paths;
32 import java.sql.ResultSet;
33 import java.sql.SQLException;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.HashMap;
37 import java.util.List;
39 import org.apache.commons.io.FileUtils;
40 import org.openide.modules.InstalledFileLocator;
41 import org.openide.util.NbBundle;
66 import org.
sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction;
68 import org.
sleuthkit.datamodel.TaggingManager.ContentTagChange;
119 "PortableCaseReportModule.getName.name=Portable Case"
123 return Bundle.PortableCaseReportModule_getName_name();
127 "PortableCaseReportModule.getDescription.description=Copies selected items to a new single-user case that can be easily shared"
131 return Bundle.PortableCaseReportModule_getDescription_description();
151 logger.log(Level.INFO,
"Portable case creation canceled by user");
169 logger.log(Level.WARNING, logWarning);
171 logger.log(Level.SEVERE, logWarning, ex);
179 "PortableCaseReportModule.generateReport.verifying=Verifying selected parameters...",
180 "PortableCaseReportModule.generateReport.creatingCase=Creating portable case database...",
181 "PortableCaseReportModule.generateReport.copyingTags=Copying tags...",
183 "PortableCaseReportModule.generateReport.copyingFiles=Copying files tagged as {0}...",
185 "PortableCaseReportModule.generateReport.copyingArtifacts=Copying artifacts tagged as {0}...",
186 "# {0} - output folder",
187 "PortableCaseReportModule.generateReport.outputDirDoesNotExist=Output folder {0} does not exist",
188 "# {0} - output folder",
189 "PortableCaseReportModule.generateReport.outputDirIsNotDir=Output folder {0} is not a folder",
190 "PortableCaseReportModule.generateReport.caseClosed=Current case has been closed",
191 "PortableCaseReportModule.generateReport.interestingItemError=Error loading intersting items",
192 "PortableCaseReportModule.generateReport.errorReadingTags=Error while reading tags from case database",
193 "PortableCaseReportModule.generateReport.errorReadingSets=Error while reading interesting items sets from case database",
194 "PortableCaseReportModule.generateReport.noContentToCopy=No interesting files, results, or tagged items to copy",
195 "PortableCaseReportModule.generateReport.errorCopyingTags=Error copying tags",
196 "PortableCaseReportModule.generateReport.errorCopyingFiles=Error copying tagged files",
197 "PortableCaseReportModule.generateReport.errorCopyingArtifacts=Error copying tagged artifacts",
198 "PortableCaseReportModule.generateReport.errorCopyingInterestingFiles=Error copying interesting files",
199 "PortableCaseReportModule.generateReport.errorCopyingInterestingResults=Error copying interesting results",
200 "PortableCaseReportModule.generateReport.errorCreatingImageTagTable=Error creating image tags table",
201 "# {0} - attribute type name",
202 "PortableCaseReportModule.generateReport.errorLookingUpAttrType=Error looking up attribute type {0}",
203 "PortableCaseReportModule.generateReport.compressingCase=Compressing case..."
207 this.settings = options;
209 progressPanel.
start();
210 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateReport_verifying());
216 File outputDir =
new File(reportPath);
217 if (! outputDir.exists()) {
218 handleError(
"Output folder " + outputDir.toString() +
" does not exist",
219 Bundle.PortableCaseReportModule_generateReport_outputDirDoesNotExist(outputDir.toString()), null, progressPanel);
223 if (! outputDir.isDirectory()) {
224 handleError(
"Output folder " + outputDir.toString() +
" is not a folder",
225 Bundle.PortableCaseReportModule_generateReport_outputDirIsNotDir(outputDir.toString()), null, progressPanel);
235 Bundle.PortableCaseReportModule_generateReport_caseClosed(), null, progressPanel);
240 List<TagName> tagNames;
246 Bundle.PortableCaseReportModule_generateReport_errorReadingTags(), ex, progressPanel);
253 List<String> setNames;
258 handleError(
"Unable to get all interesting items sets",
259 Bundle.PortableCaseReportModule_generateReport_errorReadingSets(), ex, progressPanel);
266 if (tagNames.isEmpty() && setNames.isEmpty()) {
268 Bundle.PortableCaseReportModule_generateReport_noContentToCopy(), null, progressPanel);
274 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateReport_creatingCase());
276 if (portableSkCase == null) {
290 }
catch (TskCoreException ex) {
291 handleError(
"Error creating image tag table", Bundle.PortableCaseReportModule_generateReport_errorCreatingImageTagTable(), ex, progressPanel);
296 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateReport_copyingTags());
298 for(TagName tagName:tagNames) {
299 TagName newTagName = portableSkCase.addOrUpdateTagName(tagName.getDisplayName(), tagName.getDescription(), tagName.getColor(), tagName.getKnownStatus());
300 oldTagNameToNewTagName.put(tagName, newTagName);
302 }
catch (TskCoreException ex) {
303 handleError(
"Error copying tags", Bundle.PortableCaseReportModule_generateReport_errorCopyingTags(), ex, progressPanel);
308 for (BlackboardArtifact.ARTIFACT_TYPE type:BlackboardArtifact.ARTIFACT_TYPE.values()) {
309 oldArtTypeIdToNewArtTypeId.put(type.getTypeID(), type.getTypeID());
311 for (BlackboardAttribute.ATTRIBUTE_TYPE type:BlackboardAttribute.ATTRIBUTE_TYPE.values()) {
314 }
catch (TskCoreException ex) {
315 handleError(
"Error looking up attribute name " + type.getLabel(),
316 Bundle.PortableCaseReportModule_generateReport_errorLookingUpAttrType(type.getLabel()),
323 for(TagName tagName:tagNames) {
329 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateReport_copyingFiles(tagName.getDisplayName()));
338 }
catch (TskCoreException ex) {
339 handleError(
"Error copying tagged files", Bundle.PortableCaseReportModule_generateReport_errorCopyingFiles(), ex, progressPanel);
345 for(TagName tagName:tagNames) {
351 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateReport_copyingArtifacts(tagName.getDisplayName()));
360 }
catch (TskCoreException ex) {
361 handleError(
"Error copying tagged artifacts", Bundle.PortableCaseReportModule_generateReport_errorCopyingArtifacts(), ex, progressPanel);
366 if (! setNames.isEmpty()) {
368 List<BlackboardArtifact> interestingFiles = currentCase.
getSleuthkitCase().getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT);
369 for (BlackboardArtifact art:interestingFiles) {
376 BlackboardAttribute setAttr = art.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME));
377 if (setNames.contains(setAttr.getValueString())) {
381 }
catch (TskCoreException ex) {
382 handleError(
"Error copying interesting files", Bundle.PortableCaseReportModule_generateReport_errorCopyingInterestingFiles(), ex, progressPanel);
387 List<BlackboardArtifact> interestingResults = currentCase.
getSleuthkitCase().getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT);
388 for (BlackboardArtifact art:interestingResults) {
394 BlackboardAttribute setAttr = art.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME));
395 if (setNames.contains(setAttr.getValueString())) {
399 }
catch (TskCoreException ex) {
400 handleError(
"Error copying interesting results", Bundle.PortableCaseReportModule_generateReport_errorCopyingInterestingResults(), ex, progressPanel);
416 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateReport_compressingCase());
451 "PortableCaseReportModule.generateCaseUcoReport.errorCreatingReportFolder=Could not make report folder",
452 "PortableCaseReportModule.generateCaseUcoReport.errorGeneratingCaseUcoReport=Problem while generating CASE-UCO report",
453 "PortableCaseReportModule.generateCaseUcoReport.startCaseUcoReportGeneration=Creating a CASE-UCO report of the portable case",
454 "PortableCaseReportModule.generateCaseUcoReport.successCaseUcoReportGeneration=Successfully created a CASE-UCO report of the portable case"
458 Path reportsDirectory = Paths.get(caseFolder.toString(),
"Reports");
459 if(!reportsDirectory.toFile().mkdir()) {
460 logger.log(Level.SEVERE,
"Could not make the report folder... skipping "
461 +
"CASE-UCO report generation for the portable case");
467 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateCaseUcoReport_startCaseUcoReportGeneration());
476 Path tmpDir = Paths.get(caseTempDirectory, CASE_UCO_TMP_DIR);
477 FileUtils.deleteDirectory(tmpDir.toFile());
478 Files.createDirectory(tmpDir);
480 reportGenerator.
addCase(currentCase);
495 boolean dataSourceHasBeenIncluded =
false;
497 for (TagName tagName : tagNames) {
500 dataSource, tmpDir, reportGenerator, dataSourceHasBeenIncluded);
504 dataSource, tmpDir, reportGenerator, dataSourceHasBeenIncluded);
508 for(BlackboardArtifact bArt : artifactsWithSetName.get(dataSource.getId())) {
509 Content sourceContent = bArt.getParent();
510 dataSourceHasBeenIncluded |=
addUniqueFile(sourceContent, dataSource,
511 tmpDir, reportGenerator, dataSourceHasBeenIncluded);
517 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateCaseUcoReport_successCaseUcoReportGeneration());
518 }
catch (IOException | TskCoreException ex) {
519 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_generateCaseUcoReport_errorGeneratingCaseUcoReport());
520 logger.log(Level.SEVERE,
"Error encountered while trying to create "
521 +
"CASE-UCO output for portable case.. the portable case will be "
522 +
"completed without a CASE-UCO report.", ex);
532 Multimap<Long, BlackboardArtifact> artifactsWithSetName = ArrayListMultimap.create();
533 if(!setNames.isEmpty()) {
534 List<BlackboardArtifact> allArtifacts = skCase.getBlackboardArtifacts(
535 BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT);
536 allArtifacts.addAll(skCase.getBlackboardArtifacts(
537 BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT));
539 for(BlackboardArtifact bArt : allArtifacts) {
540 BlackboardAttribute setAttr = bArt.getAttribute(
541 new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME));
542 if (setNames.contains(setAttr.getValueString())) {
543 artifactsWithSetName.put(bArt.getDataSource().getId(), bArt);
547 return artifactsWithSetName;
566 boolean dataSourceHasBeenIncluded)
throws IOException, TskCoreException {
567 if (content instanceof AbstractFile && !(content instanceof DataSource)) {
568 AbstractFile absFile = (AbstractFile) content;
569 Path filePath = tmpDir.resolve(Long.toString(absFile.getId()));
570 if (!absFile.isDir() && !Files.exists(filePath)) {
571 if(!dataSourceHasBeenIncluded) {
572 reportGenerator.addDataSource(dataSource, currentCase);
576 reportGenerator.addFile(absFile, dataSource, Paths.get(FILE_FOLDER_NAME, subFolder, fileName));
577 Files.createFile(filePath);
587 List<String> setNames =
new ArrayList<>();
588 Map<String, Long> setCounts;
592 String innerSelect =
"SELECT (value_text) AS set_name FROM blackboard_attributes WHERE (artifact_type_id = '"
593 + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() +
"' OR artifact_type_id = '"
594 + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID() +
"') AND attribute_type_id = '"
595 + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() +
"'";
598 String query =
"set_name, count(1) AS set_count FROM (" + innerSelect +
") set_names GROUP BY set_name";
603 setNames.addAll(setCounts.keySet());
616 "# {0} - case folder",
617 "PortableCaseReportModule.createCase.caseDirExists=Case folder {0} already exists",
618 "PortableCaseReportModule.createCase.errorCreatingCase=Error creating case",
620 "PortableCaseReportModule.createCase.errorCreatingFolder=Error creating folder {0}",
621 "PortableCaseReportModule.createCase.errorStoringMaxIds=Error storing maximum database IDs",
626 caseFolder = Paths.get(outputDir.toString(),
caseName).toFile();
628 if (caseFolder.exists()) {
629 handleError(
"Case folder " + caseFolder.toString() +
" already exists",
630 Bundle.PortableCaseReportModule_createCase_caseDirExists(caseFolder.toString()), null, progressPanel);
637 }
catch (TskCoreException ex) {
638 handleError(
"Error creating case " + caseName +
" in folder " + caseFolder.toString(),
639 Bundle.PortableCaseReportModule_createCase_errorCreatingCase(), ex, progressPanel);
646 }
catch (TskCoreException ex) {
648 Bundle.PortableCaseReportModule_createCase_errorStoringMaxIds(), ex, progressPanel);
653 copiedFilesFolder = Paths.get(caseFolder.toString(),
FILE_FOLDER_NAME).toFile();
654 if (! copiedFilesFolder.mkdir()) {
655 handleError(
"Error creating folder " + copiedFilesFolder.toString(),
656 Bundle.PortableCaseReportModule_createCase_errorCreatingFolder(copiedFilesFolder.toString()), null, progressPanel);
662 File subFolder = Paths.get(copiedFilesFolder.toString(), cat.getDisplayName()).toFile();
663 if (! subFolder.mkdir()) {
664 handleError(
"Error creating folder " + subFolder.toString(),
665 Bundle.PortableCaseReportModule_createCase_errorCreatingFolder(subFolder.toString()), null, progressPanel);
670 if (! unknownTypeFolder.mkdir()) {
671 handleError(
"Error creating folder " + unknownTypeFolder.toString(),
672 Bundle.PortableCaseReportModule_createCase_errorCreatingFolder(unknownTypeFolder.toString()), null, progressPanel);
685 CaseDbAccessManager currentCaseDbManager = currentCase.
getSleuthkitCase().getCaseDbAccessManager();
687 String tableSchema =
"( table_name TEXT PRIMARY KEY, "
690 portableSkCase.getCaseDbAccessManager().createTable(MAX_ID_TABLE_NAME, tableSchema);
692 currentCaseDbManager.select(
"max(obj_id) as max_id from tsk_objects",
new StoreMaxIdCallback(
"tsk_objects"));
693 currentCaseDbManager.select(
"max(tag_id) as max_id from content_tags",
new StoreMaxIdCallback(
"content_tags"));
694 currentCaseDbManager.select(
"max(tag_id) as max_id from blackboard_artifact_tags",
new StoreMaxIdCallback(
"blackboard_artifact_tags"));
695 currentCaseDbManager.select(
"max(examiner_id) as max_id from tsk_examiners",
new StoreMaxIdCallback(
"tsk_examiners"));
708 CaseDbAccessManager portableDbAccessManager = portableSkCase.getCaseDbAccessManager();
728 for (ContentTag tag : tags) {
735 Content content = tag.getContent();
736 if (content instanceof AbstractFile) {
741 if (! oldTagNameToNewTagName.containsKey(tag.getName())) {
742 throw new TskCoreException(
"TagName map is missing entry for ID " + tag.getName().getId() +
" with display name " + tag.getName().getDisplayName());
744 ContentTagChange newContentTag = portableSkCase.getTaggingManager().addContentTag(newIdToContent.get(newFileId), oldTagNameToNewTagName.get(tag.getName()), tag.getComment(), tag.getBeginByteOffset(), tag.getEndByteOffset());
749 if (! appData.isEmpty()) {
769 currentCase.
getSleuthkitCase().getCaseDbAccessManager().select(query, callback);
770 return callback.getAppData();
786 appData = rs.getString(
"app_data");
787 }
catch (SQLException ex) {
788 logger.log(Level.WARNING,
"Unable to get app_data from result set", ex);
791 }
catch (SQLException ex) {
792 logger.log(Level.WARNING,
"Failed to get next result for app_data", ex);
801 String getAppData() {
815 String insert =
"(content_tag_id, app_data) VALUES (" + newContentTag.getId() +
", '" + appData +
"')";
833 for (BlackboardArtifactTag tag : tags) {
841 Content content = tag.getContent();
845 BlackboardArtifact newArtifact =
copyArtifact(newContentId, tag.getArtifact());
848 if (! oldTagNameToNewTagName.containsKey(tag.getName())) {
849 throw new TskCoreException(
"TagName map is missing entry for ID " + tag.getName().getId() +
" with display name " + tag.getName().getDisplayName());
851 portableSkCase.getTaggingManager().addArtifactTag(newArtifact, oldTagNameToNewTagName.get(tag.getName()), tag.getComment());
865 private BlackboardArtifact
copyArtifact(
long newContentId, BlackboardArtifact artifactToCopy)
throws TskCoreException {
867 if (oldArtifactIdToNewArtifact.containsKey(artifactToCopy.getArtifactID())) {
868 return oldArtifactIdToNewArtifact.get(artifactToCopy.getArtifactID());
872 BlackboardAttribute oldAssociatedAttribute = artifactToCopy.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
873 List<BlackboardAttribute> newAttrs =
new ArrayList<>();
874 if (oldAssociatedAttribute != null) {
875 BlackboardArtifact oldAssociatedArtifact = currentCase.
getSleuthkitCase().getBlackboardArtifact(oldAssociatedAttribute.getValueLong());
876 BlackboardArtifact newAssociatedArtifact =
copyArtifact(newContentId, oldAssociatedArtifact);
877 newAttrs.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
878 String.join(
",", oldAssociatedAttribute.getSources()), newAssociatedArtifact.getArtifactID()));
883 BlackboardArtifact newArtifact = portableSkCase.newBlackboardArtifact(newArtifactTypeId, newContentId);
884 List<BlackboardAttribute> oldAttrs = artifactToCopy.getAttributes();
887 for (BlackboardAttribute oldAttr:oldAttrs) {
890 if (oldAttr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
895 switch (oldAttr.getValueType()) {
897 newAttrs.add(
new BlackboardAttribute(newAttributeType, String.join(
",", oldAttr.getSources()),
898 oldAttr.getValueBytes()));
901 newAttrs.add(
new BlackboardAttribute(newAttributeType, String.join(
",", oldAttr.getSources()),
902 oldAttr.getValueDouble()));
905 newAttrs.add(
new BlackboardAttribute(newAttributeType, String.join(
",", oldAttr.getSources()),
906 oldAttr.getValueInt()));
910 newAttrs.add(
new BlackboardAttribute(newAttributeType, String.join(
",", oldAttr.getSources()),
911 oldAttr.getValueLong()));
915 newAttrs.add(
new BlackboardAttribute(newAttributeType, String.join(
",", oldAttr.getSources()),
916 oldAttr.getValueString()));
919 throw new TskCoreException(
"Unexpected attribute value type found: " + oldAttr.getValueType().getLabel());
923 newArtifact.addAttributes(newAttrs);
925 oldArtifactIdToNewArtifact.put(artifactToCopy.getArtifactID(), newArtifact);
938 if (oldArtTypeIdToNewArtTypeId.containsKey(oldArtifact.getArtifactTypeID())) {
939 return oldArtTypeIdToNewArtTypeId.get(oldArtifact.getArtifactTypeID());
942 BlackboardArtifact.Type oldCustomType = currentCase.
getSleuthkitCase().getArtifactType(oldArtifact.getArtifactTypeName());
944 BlackboardArtifact.Type newCustomType = portableSkCase.addBlackboardArtifactType(oldCustomType.getTypeName(), oldCustomType.getDisplayName());
945 oldArtTypeIdToNewArtTypeId.put(oldArtifact.getArtifactTypeID(), newCustomType.getTypeID());
946 return newCustomType.getTypeID();
947 }
catch (TskDataException ex) {
948 throw new TskCoreException(
"Error creating new artifact type " + oldCustomType.getTypeName(), ex);
960 private BlackboardAttribute.Type
getNewAttributeType(BlackboardAttribute oldAttribute)
throws TskCoreException {
961 BlackboardAttribute.Type oldAttrType = oldAttribute.getAttributeType();
967 BlackboardAttribute.Type newCustomType = portableSkCase.addArtifactAttributeType(oldAttrType.getTypeName(),
968 oldAttrType.getValueType(), oldAttrType.getDisplayName());
970 return newCustomType;
971 }
catch (TskDataException ex) {
972 throw new TskCoreException(
"Error creating new attribute type " + oldAttrType.getTypeName(), ex);
988 "PortableCaseReportModule.copyContentToPortableCase.copyingFile=Copying file {0}",
991 progressPanel.
updateStatusLabel(Bundle.PortableCaseReportModule_copyContentToPortableCase_copyingFile(content.getUniquePath()));
1007 if (oldIdToNewContent.containsKey(content.getId())) {
1008 return oldIdToNewContent.get(content.getId()).getId();
1015 if (content.getParent() != null) {
1020 if (content instanceof BlackboardArtifact) {
1021 BlackboardArtifact artifactToCopy = (BlackboardArtifact)content;
1024 CaseDbTransaction trans = portableSkCase.beginTransaction();
1026 if (content instanceof Image) {
1027 Image image = (Image)content;
1028 newContent = portableSkCase.addImage(image.getType(), image.getSsize(), image.getSize(), image.getName(),
1029 new ArrayList<>(), image.getTimeZone(), image.getMd5(), image.getSha1(), image.getSha256(), image.getDeviceId(), trans);
1030 }
else if (content instanceof VolumeSystem) {
1031 VolumeSystem vs = (VolumeSystem)content;
1032 newContent = portableSkCase.addVolumeSystem(parentId, vs.getType(), vs.getOffset(), vs.getBlockSize(), trans);
1033 }
else if (content instanceof Volume) {
1034 Volume vs = (Volume)content;
1035 newContent = portableSkCase.addVolume(parentId, vs.getAddr(), vs.getStart(), vs.getLength(),
1036 vs.getDescription(), vs.getFlags(), trans);
1037 }
else if (content instanceof Pool) {
1038 Pool pool = (Pool)content;
1039 newContent = portableSkCase.addPool(parentId, pool.getType(), trans);
1040 }
else if (content instanceof FileSystem) {
1041 FileSystem fs = (FileSystem)content;
1042 newContent = portableSkCase.addFileSystem(parentId, fs.getImageOffset(), fs.getFsType(), fs.getBlock_size(),
1043 fs.getBlock_count(), fs.getRoot_inum(), fs.getFirst_inum(), fs.getLastInum(),
1044 fs.getName(), trans);
1045 }
else if (content instanceof BlackboardArtifact) {
1046 BlackboardArtifact artifactToCopy = (BlackboardArtifact)content;
1048 }
else if (content instanceof AbstractFile) {
1049 AbstractFile abstractFile = (AbstractFile)content;
1051 if (abstractFile instanceof LocalFilesDataSource) {
1052 LocalFilesDataSource localFilesDS = (LocalFilesDataSource)abstractFile;
1053 newContent = portableSkCase.addLocalFilesDataSource(localFilesDS.getDeviceId(), localFilesDS.getName(), localFilesDS.getTimeZone(), trans);
1055 if (abstractFile.isDir()) {
1056 newContent = portableSkCase.addLocalDirectory(parentId, abstractFile.getName(), trans);
1062 File exportFolder = Paths.get(copiedFilesFolder.toString(), exportSubFolder).toFile();
1063 File localFile =
new File(exportFolder, fileName);
1067 Content oldParent = abstractFile.getParent();
1068 if (! oldIdToNewContent.containsKey(oldParent.getId())) {
1069 throw new TskCoreException(
"Parent of file with ID " + abstractFile.getId() +
" has not been created");
1071 Content newParent = oldIdToNewContent.get(oldParent.getId());
1074 String relativePath = FILE_FOLDER_NAME + File.separator + exportSubFolder + File.separator + fileName;
1076 newContent = portableSkCase.addLocalFile(abstractFile.getName(), relativePath, abstractFile.getSize(),
1077 abstractFile.getCtime(), abstractFile.getCrtime(), abstractFile.getAtime(), abstractFile.getMtime(),
1078 abstractFile.getMd5Hash(), abstractFile.getKnown(), abstractFile.getMIMEType(),
1079 true, TskData.EncodingType.NONE,
1081 }
catch (IOException ex) {
1082 throw new TskCoreException(
"Error copying file " + abstractFile.getName() +
" with original obj ID "
1083 + abstractFile.getId(), ex);
1088 throw new TskCoreException(
"Trying to copy unexpected Content type " + content.getClass().getName());
1091 }
catch (TskCoreException ex) {
1098 oldIdToNewContent.put(content.getId(), newContent);
1099 newIdToContent.put(newContent.getId(), newContent);
1100 return oldIdToNewContent.get(content.getId()).getId();
1111 if (abstractFile.getMIMEType() == null || abstractFile.getMIMEType().isEmpty()) {
1116 if (cat.getMediaTypes().contains(abstractFile.getMIMEType())) {
1117 return cat.getDisplayName();
1127 oldIdToNewContent.clear();
1128 newIdToContent.clear();
1129 oldTagNameToNewTagName.clear();
1130 oldArtTypeIdToNewArtTypeId.clear();
1132 oldArtifactIdToNewArtifact.clear();
1138 copiedFilesFolder = null;
1145 if (portableSkCase != null) {
1146 portableSkCase.close();
1147 portableSkCase = null;
1171 Long maxId = rs.getLong(
"max_id");
1172 String query =
" (table_name, max_id) VALUES ('" + tableName +
"', '" + maxId +
"')";
1173 portableSkCase.getCaseDbAccessManager().insert(MAX_ID_TABLE_NAME, query);
1175 }
catch (SQLException ex) {
1176 logger.log(Level.WARNING,
"Unable to get maximum ID from result set", ex);
1177 }
catch (TskCoreException ex) {
1178 logger.log(Level.WARNING,
"Unable to save maximum ID from result set", ex);
1182 }
catch (SQLException ex) {
1183 logger.log(Level.WARNING,
"Failed to get maximum ID from result set", ex);
1188 @NbBundle.Messages({
1189 "PortableCaseReportModule.compressCase.errorFinding7zip=Could not locate 7-Zip executable",
1190 "# {0} - Temp folder path",
1191 "PortableCaseReportModule.compressCase.errorCreatingTempFolder=Could not create temporary folder {0}",
1192 "PortableCaseReportModule.compressCase.errorCompressingCase=Error compressing case",
1193 "PortableCaseReportModule.compressCase.canceled=Compression canceled by user",
1201 File tempZipFolder = Paths.get(currentCase.
getTempDirectory(),
"portableCase" + System.currentTimeMillis()).toFile();
1202 if (! tempZipFolder.mkdir()) {
1203 handleError(
"Error creating temporary folder " + tempZipFolder.toString(),
1204 Bundle.PortableCaseReportModule_compressCase_errorCreatingTempFolder(tempZipFolder.toString()), null, progressPanel);
1210 if (sevenZipExe == null) {
1211 handleError(
"Error finding 7-Zip exectuable", Bundle.PortableCaseReportModule_compressCase_errorFinding7zip(), null, progressPanel);
1216 String chunkOption =
"";
1221 File zipFile = Paths.get(tempZipFolder.getAbsolutePath(), caseName +
".zip").toFile();
1222 ProcessBuilder procBuilder =
new ProcessBuilder();
1223 procBuilder.command(
1224 sevenZipExe.getAbsolutePath(),
1226 zipFile.getAbsolutePath(),
1227 caseFolder.getAbsolutePath(),
1232 Process process = procBuilder.start();
1234 while (process.isAlive()) {
1241 int exitCode = process.exitValue();
1242 if (exitCode != 0) {
1244 StringBuilder sb =
new StringBuilder();
1245 try (BufferedReader br =
new BufferedReader(
new InputStreamReader(process.getErrorStream()))) {
1247 while ((line = br.readLine()) != null) {
1248 sb.append(line).append(System.getProperty(
"line.separator"));
1252 handleError(
"Error compressing case\n7-Zip output: " + sb.toString(), Bundle.PortableCaseReportModule_compressCase_errorCompressingCase(), null, progressPanel);
1255 }
catch (IOException | InterruptedException ex) {
1256 handleError(
"Error compressing case", Bundle.PortableCaseReportModule_compressCase_errorCompressingCase(), ex, progressPanel);
1262 FileUtils.cleanDirectory(caseFolder);
1263 FileUtils.copyDirectory(tempZipFolder, caseFolder);
1264 FileUtils.deleteDirectory(tempZipFolder);
1265 }
catch (IOException ex) {
1266 handleError(
"Error compressing case", Bundle.PortableCaseReportModule_compressCase_errorCompressingCase(), ex, progressPanel);
1283 String executableToFindName = Paths.get(
"7-Zip",
"7z.exe").toString();
1285 if (null == exeFile) {
1289 if (!exeFile.canExecute()) {
1302 private final Map<String, Long>
setCounts =
new HashMap<>();
1309 Long setCount = rs.getLong(
"set_count");
1310 String setName = rs.getString(
"set_name");
1312 setCounts.put(setName, setCount);
1314 }
catch (SQLException ex) {
1315 logger.log(Level.WARNING,
"Unable to get data_source_obj_id or value from result set", ex);
1318 }
catch (SQLException ex) {
1319 logger.log(Level.WARNING,
"Failed to get next result for values by datasource", ex);
List< Content > getDataSources()
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()
void addCase(Case caseObj)
String getTempDirectory()
boolean compressCase(ReportProgressPanel progressPanel)
long copyContentToPortableCase(Content content, ReportProgressPanel progressPanel)
void addArtifactsToPortableCase(TagName oldTagName, ReportProgressPanel progressPanel)
static final String FILE_FOLDER_NAME
final Map< Integer, BlackboardAttribute.Type > oldAttrTypeIdToNewAttrType
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()
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)
SleuthkitCase createPortableCase(String caseName, File portableCaseFolder)
boolean areAllTagsSelected()
static String escapeFileName(String fileName)
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 addUniqueFile(Content content, Content dataSource, Path tmpDir, CaseUcoReportGenerator reportGenerator, boolean dataSourceHasBeenIncluded)
boolean areAllSetsSelected()
void addImageTagToPortableCase(ContentTag newContentTag, String appData)
void handleCancellation(ReportProgressPanel progressPanel)
void createCase(File outputDir, ReportProgressPanel progressPanel)
void process(ResultSet rs)
PortableCaseReportModuleSettings settings