19 package org.sleuthkit.autopsy.modules.embeddedfileextractor;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.OutputStream;
25 import java.nio.file.Files;
26 import java.nio.file.Paths;
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.Date;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.logging.Level;
33 import net.sf.sevenzipjbinding.ArchiveFormat;
34 import static net.sf.sevenzipjbinding.ArchiveFormat.RAR;
35 import net.sf.sevenzipjbinding.ISequentialOutStream;
36 import net.sf.sevenzipjbinding.ISevenZipInArchive;
37 import net.sf.sevenzipjbinding.SevenZip;
38 import net.sf.sevenzipjbinding.SevenZipException;
39 import net.sf.sevenzipjbinding.SevenZipNativeInitializationException;
40 import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
41 import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;
42 import net.sf.sevenzipjbinding.ExtractOperationResult;
43 import org.netbeans.api.progress.ProgressHandle;
44 import org.openide.util.NbBundle;
45 import org.openide.util.NbBundle.Messages;
70 class SevenZipExtractor {
72 private static final Logger logger = Logger.getLogger(SevenZipExtractor.class.getName());
73 private IngestServices services = IngestServices.getInstance();
74 private final IngestJobContext context;
75 private final FileTypeDetector fileTypeDetector;
76 static final String[] SUPPORTED_EXTENSIONS = {
"zip",
"rar",
"arj",
"7z",
"7zip",
"gzip",
"gz",
"bzip2",
"tar",
"tgz",};
78 private static final String ENCRYPTION_FILE_LEVEL = NbBundle.getMessage(EmbeddedFileExtractorIngestModule.class,
79 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.encryptionFileLevel");
80 private static final String ENCRYPTION_FULL = NbBundle.getMessage(EmbeddedFileExtractorIngestModule.class,
81 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.encryptionFull");
83 private static final int MAX_DEPTH = 4;
84 private static final int MAX_COMPRESSION_RATIO = 600;
85 private static final long MIN_COMPRESSION_RATIO_SIZE = 500 * 1000000L;
86 private static final long MIN_FREE_DISK_SPACE = 1 * 1000 * 1000000L;
88 private ArchiveDepthCountTree archiveDepthCountTree;
90 private String moduleDirRelative;
91 private String moduleDirAbsolute;
93 private Blackboard blackboard;
95 private String getLocalRootAbsPath(String uniqueArchiveFileName) {
96 return moduleDirAbsolute + File.separator + uniqueArchiveFileName;
111 XRAR(
"application/x-rar-compressed");
116 this.mimeType = mimeType;
121 return this.mimeType;
126 SevenZipExtractor(
IngestJobContext context,
FileTypeDetector fileTypeDetector, String moduleDirRelative, String moduleDirAbsolute)
throws SevenZipNativeInitializationException {
127 if (!SevenZip.isInitializedSuccessfully() && (SevenZip.getLastInitializationException() == null)) {
128 SevenZip.initSevenZipFromPlatformJAR();
130 this.context = context;
131 this.fileTypeDetector = fileTypeDetector;
132 this.moduleDirRelative = moduleDirRelative;
133 this.moduleDirAbsolute = moduleDirAbsolute;
134 this.archiveDepthCountTree =
new ArchiveDepthCountTree();
145 boolean isSevenZipExtractionSupported(AbstractFile file) {
146 String fileMimeType = fileTypeDetector.getMIMEType(file);
147 for (SupportedArchiveExtractionFormats mimeType : SupportedArchiveExtractionFormats.values()) {
148 if (mimeType.toString().equals(fileMimeType)) {
167 private boolean isZipBombArchiveItemCheck(AbstractFile archiveFile, ISimpleInArchiveItem archiveFileItem) {
169 final Long archiveItemSize = archiveFileItem.getSize();
172 if (archiveItemSize == null || archiveItemSize < MIN_COMPRESSION_RATIO_SIZE) {
176 final Long archiveItemPackedSize = archiveFileItem.getPackedSize();
178 if (archiveItemPackedSize == null || archiveItemPackedSize <= 0) {
179 logger.log(Level.WARNING,
"Cannot getting compression ratio, cannot detect if zipbomb: {0}, item: {1}",
new Object[]{archiveFile.getName(), archiveFileItem.getPath()});
183 int cRatio = (int) (archiveItemSize / archiveItemPackedSize);
185 if (cRatio >= MAX_COMPRESSION_RATIO) {
186 String itemName = archiveFileItem.getPath();
187 logger.log(Level.INFO,
"Possible zip bomb detected, compression ration: {0} for in archive item: {1}",
new Object[]{cRatio, itemName});
188 String msg = NbBundle.getMessage(SevenZipExtractor.class,
189 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnMsg", archiveFile.getName(), itemName);
192 path = archiveFile.getUniquePath();
193 }
catch (TskCoreException ex) {
194 path = archiveFile.getParentPath() + archiveFile.getName();
196 String details = NbBundle.getMessage(SevenZipExtractor.class,
197 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnDetails", cRatio, path);
199 services.postMessage(IngestMessage.createWarningMessage(EmbeddedFileExtractorModuleFactory.getModuleName(), msg, details));
205 }
catch (SevenZipException ex) {
206 logger.log(Level.WARNING,
"Error getting archive item size and cannot detect if zipbomb. ", ex);
219 private ArchiveFormat get7ZipOptions(AbstractFile archiveFile) {
221 String detectedFormat = null;
222 detectedFormat = archiveFile.getMIMEType();
224 if (detectedFormat == null) {
225 logger.log(Level.WARNING,
"Could not detect format for file: {0}", archiveFile);
228 String extension = archiveFile.getNameExtension();
229 if (
"rar".equals(extension))
238 }
else if (detectedFormat.contains(
"application/x-rar-compressed"))
259 private long getRootArchiveId(AbstractFile file)
throws TskCoreException {
260 long id = file.getId();
261 Content parentContent = file.getParent();
262 while (parentContent != null) {
263 id = parentContent.getId();
264 parentContent = parentContent.getParent();
283 private List<AbstractFile> getAlreadyExtractedFiles(AbstractFile archiveFile, String archiveFilePath)
throws TskCoreException, NoCurrentCaseException {
286 if (archiveFile.hasChildren() &&
new File(moduleDirAbsolute, EmbeddedFileExtractorIngestModule.getUniqueName(archiveFile)).exists()) {
287 return Case.getOpenCase().getServices().getFileManager().findFilesByParentPath(getRootArchiveId(archiveFile), archiveFilePath);
289 return new ArrayList<>();
299 private String getArchiveFilePath(AbstractFile archiveFile) {
301 return archiveFile.getUniquePath();
302 }
catch (TskCoreException ex) {
303 return archiveFile.getParentPath() + archiveFile.getName();
313 private void makeLocalDirectories(String uniqueArchiveFileName) {
314 final String localRootAbsPath = getLocalRootAbsPath(uniqueArchiveFileName);
315 final File localRoot =
new File(localRootAbsPath);
316 if (!localRoot.exists()) {
333 private String getPathInArchive(ISimpleInArchiveItem item,
int itemNumber, AbstractFile archiveFile)
throws SevenZipException {
334 String pathInArchive = item.getPath();
336 if (pathInArchive == null || pathInArchive.isEmpty()) {
342 String archName = archiveFile.getName();
343 int dotI = archName.lastIndexOf(
".");
344 String useName = null;
346 String base = archName.substring(0, dotI);
347 String ext = archName.substring(dotI);
348 int colonIndex = ext.lastIndexOf(
":");
349 if (colonIndex != -1) {
352 ext = ext.substring(0, colonIndex);
359 useName = base +
".tar";
366 if (useName == null) {
367 pathInArchive =
"/" + archName +
"/" + Integer.toString(itemNumber);
369 pathInArchive =
"/" + useName;
371 String msg = NbBundle.getMessage(SevenZipExtractor.class,
372 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.unknownPath.msg",
373 getArchiveFilePath(archiveFile), pathInArchive);
374 logger.log(Level.WARNING, msg);
376 return pathInArchive;
383 private String getKeyAbstractFile(AbstractFile fileInDatabase) {
384 return fileInDatabase == null ? null : fileInDatabase.getParentPath() + fileInDatabase.getName();
391 private String getKeyFromUnpackedNode(UnpackedTree.UnpackedNode node, String archiveFilePath) {
392 return node == null ? null : archiveFilePath +
"/" + node.getFileName();
409 private SevenZipExtractor.UnpackedTree.UnpackedNode unpackNode(ISimpleInArchiveItem item, SevenZipExtractor.UnpackedTree.UnpackedNode unpackedNode, String password,
long freeDiskSpace, String uniqueExtractedName)
throws SevenZipException {
411 final String localAbsPath = moduleDirAbsolute + File.separator + uniqueExtractedName;
412 final String localRelPath = moduleDirRelative + File.separator + uniqueExtractedName;
413 final Date createTime = item.getCreationTime();
414 final Date accessTime = item.getLastAccessTime();
415 final Date writeTime = item.getLastWriteTime();
416 final long createtime = createTime == null ? 0L : createTime.getTime() / 1000;
417 final long modtime = writeTime == null ? 0L : writeTime.getTime() / 1000;
418 final long accesstime = accessTime == null ? 0L : accessTime.getTime() / 1000;
419 SevenZipExtractor.UnpackStream unpackStream = null;
420 boolean isDir = item.isFolder();
425 if (item.getSize() != null) {
426 unpackStream =
new SevenZipExtractor.KnownSizeUnpackStream(localAbsPath, item.getSize());
428 unpackStream =
new SevenZipExtractor.UnknownSizeUnpackStream(localAbsPath, freeDiskSpace);
430 ExtractOperationResult result;
431 if (password == null) {
432 result = item.extractSlow(unpackStream);
434 result = item.extractSlow(unpackStream, password);
436 if (result != ExtractOperationResult.OK) {
437 logger.log(Level.WARNING,
"Extraction of : " + localAbsPath +
" encountered error " + result);
441 }
catch (Exception e) {
443 logger.log(Level.WARNING,
"Could not extract file from archive: " + localAbsPath, e);
445 if (unpackStream != null) {
447 unpackedNode.addDerivedInfo(unpackStream.getSize(), !isDir,
448 0L, createtime, accesstime, modtime, localRelPath);
449 unpackStream.close();
453 unpackedNode.addDerivedInfo(0, !isDir, 0L, createtime, accesstime, modtime, localRelPath);
465 void unpack(AbstractFile archiveFile) {
466 unpack(archiveFile, null);
478 @Messages({
"SevenZipExtractor.indexError.message=Failed to index encryption detected artifact for keyword search."})
479 boolean unpack(AbstractFile archiveFile, String password) {
480 boolean unpackSuccessful =
true;
481 boolean hasEncrypted =
false;
482 boolean fullEncryption =
true;
483 boolean progressStarted =
false;
484 int processedItems = 0;
485 final String archiveFilePath = getArchiveFilePath(archiveFile);
486 final String escapedArchiveFilePath = FileUtil.escapeFileName(archiveFilePath);
487 HashMap<String, ZipFileStatusWrapper> statusMap =
new HashMap<>();
488 List<AbstractFile> unpackedFiles = Collections.<AbstractFile>emptyList();
489 ISevenZipInArchive inArchive = null;
491 SevenZipContentReadStream stream = null;
492 final ProgressHandle progress = ProgressHandle.createHandle(Bundle.EmbeddedFileExtractorIngestModule_ArchiveExtractor_moduleName());
494 final long archiveId = archiveFile.getId();
495 SevenZipExtractor.ArchiveDepthCountTree.Archive parentAr = null;
497 blackboard = Case.getOpenCase().getServices().getBlackboard();
498 }
catch (NoCurrentCaseException ex) {
499 logger.log(Level.INFO,
"Exception while getting open case.", ex);
500 unpackSuccessful =
false;
501 return unpackSuccessful;
505 List<AbstractFile> existingFiles = getAlreadyExtractedFiles(archiveFile, archiveFilePath);
506 for (AbstractFile file : existingFiles) {
507 statusMap.put(getKeyAbstractFile(file),
new ZipFileStatusWrapper(file, ZipFileStatus.EXISTS));
509 }
catch (TskCoreException e) {
510 logger.log(Level.INFO,
"Error checking if file already has been processed, skipping: {0}", escapedArchiveFilePath);
511 unpackSuccessful =
false;
512 return unpackSuccessful;
513 }
catch (NoCurrentCaseException ex) {
514 logger.log(Level.INFO,
"No open case was found while trying to unpack the archive file {0}", escapedArchiveFilePath);
515 unpackSuccessful =
false;
516 return unpackSuccessful;
518 parentAr = archiveDepthCountTree.findArchive(archiveId);
519 if (parentAr == null) {
520 parentAr = archiveDepthCountTree.addArchive(null, archiveId);
522 }
else if (parentAr.getDepth() == MAX_DEPTH) {
523 String msg = NbBundle.getMessage(SevenZipExtractor.class,
524 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnMsg.zipBomb", archiveFile.getName());
525 String details = NbBundle.getMessage(SevenZipExtractor.class,
526 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnDetails.zipBomb",
527 parentAr.getDepth(), escapedArchiveFilePath);
529 services.postMessage(IngestMessage.createWarningMessage(EmbeddedFileExtractorModuleFactory.getModuleName(), msg, details));
530 unpackSuccessful =
false;
531 return unpackSuccessful;
534 stream =
new SevenZipContentReadStream(
new ReadContentInputStream(archiveFile));
538 ArchiveFormat options = get7ZipOptions(archiveFile);
539 if (password == null) {
540 inArchive = SevenZip.openInArchive(options, stream);
542 inArchive = SevenZip.openInArchive(options, stream, password);
544 int numItems = inArchive.getNumberOfItems();
545 logger.log(Level.INFO,
"Count of items in archive: {0}: {1}",
new Object[]{escapedArchiveFilePath, numItems});
546 progress.start(numItems);
547 progressStarted =
true;
548 final ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
551 final String uniqueArchiveFileName = FileUtil.escapeFileName(EmbeddedFileExtractorIngestModule.getUniqueName(archiveFile));
553 makeLocalDirectories(uniqueArchiveFileName);
554 }
catch (SecurityException e) {
555 logger.log(Level.SEVERE,
"Error setting up output path for archive root: {0}", getLocalRootAbsPath(uniqueArchiveFileName));
557 unpackSuccessful =
false;
558 return unpackSuccessful;
562 SevenZipExtractor.UnpackedTree unpackedTree =
new SevenZipExtractor.UnpackedTree(moduleDirRelative +
"/" + uniqueArchiveFileName, archiveFile);
566 freeDiskSpace = services.getFreeDiskSpace();
567 }
catch (NullPointerException ex) {
570 freeDiskSpace = IngestMonitor.DISK_FREE_SPACE_UNKNOWN;
575 for (ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
576 String pathInArchive = getPathInArchive(item, itemNumber, archiveFile);
582 if (isZipBombArchiveItemCheck(archiveFile, item)) {
585 SevenZipExtractor.UnpackedTree.UnpackedNode unpackedNode = unpackedTree.addNode(pathInArchive);
587 progress.progress(archiveFile.getName() +
": " + item.getPath(), processedItems);
589 final boolean isEncrypted = item.isEncrypted();
591 if (isEncrypted && password == null) {
592 logger.log(Level.WARNING,
"Skipping encrypted file in archive: {0}", pathInArchive);
594 unpackSuccessful =
false;
597 fullEncryption =
false;
603 if (freeDiskSpace != IngestMonitor.DISK_FREE_SPACE_UNKNOWN && item.getSize() != null && item.getSize() > 0) {
604 long newDiskSpace = freeDiskSpace - item.getSize();
605 if (newDiskSpace < MIN_FREE_DISK_SPACE) {
606 String msg = NbBundle.getMessage(SevenZipExtractor.class,
607 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.msg",
608 escapedArchiveFilePath, item.getPath());
609 String details = NbBundle.getMessage(SevenZipExtractor.class,
610 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.details");
612 services.postMessage(IngestMessage.createErrorMessage(EmbeddedFileExtractorModuleFactory.getModuleName(), msg, details));
613 logger.log(Level.INFO,
"Skipping archive item due to insufficient disk space: {0}, {1}",
new String[]{escapedArchiveFilePath, item.getPath()});
614 logger.log(Level.INFO,
"Available disk space: {0}",
new Object[]{freeDiskSpace});
615 unpackSuccessful =
false;
619 freeDiskSpace = newDiskSpace;
622 final String uniqueExtractedName = FileUtil.escapeFileName(uniqueArchiveFileName + File.separator + (item.getItemIndex() / 1000) + File.separator + item.getItemIndex() +
"_" +
new File(pathInArchive).getName());
625 File localFile =
new java.io.File(moduleDirAbsolute + File.separator + uniqueExtractedName);
627 if (!localFile.exists()) {
629 if (item.isFolder()) {
632 localFile.getParentFile().mkdirs();
634 localFile.createNewFile();
635 }
catch (IOException e) {
636 logger.log(Level.SEVERE,
"Error creating extracted file: " + localFile.getAbsolutePath(), e);
639 }
catch (SecurityException e) {
640 logger.log(Level.SEVERE,
"Error setting up output path for unpacked file: {0}", pathInArchive);
645 if (localFile.exists() ==
false) {
649 unpackedNode = unpackNode(item, unpackedNode, password,
650 freeDiskSpace, uniqueExtractedName);
651 if (unpackedNode == null) {
652 unpackSuccessful =
false;
661 unpackedTree.updateOrAddFileToCaseRec(statusMap, archiveFilePath);
662 unpackedFiles = unpackedTree.getAllFileObjects();
664 for (AbstractFile unpackedFile : unpackedFiles) {
665 if (unpackedFile == null) {
668 if (isSevenZipExtractionSupported(unpackedFile)) {
669 archiveDepthCountTree.addArchive(parentAr, unpackedFile.getId());
673 }
catch (TskCoreException | NoCurrentCaseException e) {
674 logger.log(Level.SEVERE,
"Error populating complete derived file hierarchy from the unpacked dir structure", e);
678 }
catch (SevenZipException ex) {
679 logger.log(Level.WARNING,
"Error unpacking file: " + archiveFile, ex);
683 if (archiveFile.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC)) {
684 String msg = NbBundle.getMessage(SevenZipExtractor.class,
685 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.errUnpacking.msg",
686 archiveFile.getName());
687 String details = NbBundle.getMessage(SevenZipExtractor.class,
688 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.errUnpacking.details",
689 escapedArchiveFilePath, ex.getMessage());
690 services.postMessage(IngestMessage.createErrorMessage(EmbeddedFileExtractorModuleFactory.getModuleName(), msg, details));
693 if (inArchive != null) {
696 }
catch (SevenZipException e) {
697 logger.log(Level.SEVERE,
"Error closing archive: " + archiveFile, e);
701 if (stream != null) {
704 }
catch (IOException ex) {
705 logger.log(Level.SEVERE,
"Error closing stream after unpacking archive: " + archiveFile, ex);
710 if (progressStarted) {
717 String encryptionType = fullEncryption ? ENCRYPTION_FULL : ENCRYPTION_FILE_LEVEL;
719 BlackboardArtifact artifact = archiveFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED);
720 artifact.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, EmbeddedFileExtractorModuleFactory.getModuleName(), encryptionType));
724 blackboard.indexArtifact(artifact);
725 }
catch (Blackboard.BlackboardException ex) {
726 logger.log(Level.SEVERE,
"Unable to index blackboard artifact " + artifact.getArtifactID(), ex);
727 MessageNotifyUtil.Notify.error(
728 Bundle.SevenZipExtractor_indexError_message(), artifact.getDisplayName());
731 services.fireModuleDataEvent(
new ModuleDataEvent(EmbeddedFileExtractorModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED));
732 }
catch (TskCoreException ex) {
733 logger.log(Level.SEVERE,
"Error creating blackboard artifact for encryption detected for file: " + escapedArchiveFilePath, ex);
736 String msg = NbBundle.getMessage(SevenZipExtractor.class,
737 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.encrFileDetected.msg");
738 String details = NbBundle.getMessage(SevenZipExtractor.class,
739 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.encrFileDetected.details",
740 archiveFile.getName(), EmbeddedFileExtractorModuleFactory.getModuleName());
741 services.postMessage(IngestMessage.createWarningMessage(EmbeddedFileExtractorModuleFactory.getModuleName(), msg, details));
745 if (!unpackedFiles.isEmpty()) {
747 services.fireModuleContentEvent(
new ModuleContentEvent(archiveFile));
748 if (context != null) {
749 context.addFilesToJob(unpackedFiles);
752 return unpackSuccessful;
758 private abstract static class UnpackStream implements ISequentialOutStream {
766 output =
new EncodedFileOutputStream(
new FileOutputStream(localAbsPath), TskData.EncodingType.XOR1);
767 }
catch (IOException ex) {
768 logger.log(Level.SEVERE,
"Error writing extracted file: " + localAbsPath, ex);
773 public abstract long getSize();
775 OutputStream getOutput() {
779 String getLocalAbsPath() {
784 if (output != null) {
788 }
catch (IOException e) {
789 logger.log(Level.SEVERE,
"Error closing unpack stream for file: {0}", localAbsPath);
815 public int write(byte[] bytes)
throws SevenZipException {
821 getOutput().write(bytes);
825 this.bytesWritten += bytes.length;
826 this.freeDiskSpace -= bytes.length;
828 this.outOfSpace =
true;
829 logger.log(Level.INFO, NbBundle.getMessage(
830 SevenZipExtractor.class,
831 "EmbeddedFileExtractorIngestModule.ArchiveExtractor.UnpackStream.write.noSpace.msg"));
832 throw new SevenZipException(
833 NbBundle.getMessage(SevenZipExtractor.class,
"EmbeddedFileExtractorIngestModule.ArchiveExtractor.UnpackStream.write.noSpace.msg"));
835 }
catch (IOException ex) {
836 throw new SevenZipException(
837 NbBundle.getMessage(SevenZipExtractor.class,
"EmbeddedFileExtractorIngestModule.ArchiveExtractor.UnpackStream.write.exception.msg",
838 getLocalAbsPath()), ex);
845 if (getOutput() != null) {
849 if (this.outOfSpace) {
850 Files.delete(Paths.get(getLocalAbsPath()));
852 }
catch (IOException e) {
853 logger.log(Level.SEVERE,
"Error closing unpack stream for file: {0}", getLocalAbsPath());
877 public int write(byte[] bytes)
throws SevenZipException {
879 getOutput().write(bytes);
880 }
catch (IOException ex) {
881 throw new SevenZipException(
882 NbBundle.getMessage(SevenZipExtractor.class,
"EmbeddedFileExtractorIngestModule.ArchiveExtractor.UnpackStream.write.exception.msg",
883 getLocalAbsPath()), ex);
907 UnpackedTree(String localPathRoot, AbstractFile archiveFile) {
909 this.rootNode.setFile(archiveFile);
924 String[] toks = filePath.split(
"[\\/\\\\]");
925 List<String> tokens =
new ArrayList<>();
926 for (
int i = 0; i < toks.length; ++i) {
927 if (!toks[i].isEmpty()) {
931 return addNode(rootNode, tokens);
944 if (tokenPath.isEmpty()) {
949 String childName = tokenPath.remove(0);
957 return addNode(child, tokenPath);
966 List<AbstractFile> getRootFileObjects() {
967 List<AbstractFile> ret =
new ArrayList<>();
968 for (UnpackedNode child : rootNode.
children) {
969 ret.add(child.getFile());
980 List<AbstractFile> getAllFileObjects() {
981 List<AbstractFile> ret =
new ArrayList<>();
982 for (UnpackedNode child : rootNode.
children) {
999 void updateOrAddFileToCaseRec(HashMap<String, ZipFileStatusWrapper> statusMap, String archiveFilePath)
throws TskCoreException,
NoCurrentCaseException {
1001 for (UnpackedNode child : rootNode.
children) {
1002 updateOrAddFileToCaseRec(child, fileManager, statusMap, archiveFilePath);
1023 String nameInDatabase = getKeyFromUnpackedNode(node, archiveFilePath);
1024 ZipFileStatusWrapper existingFile = nameInDatabase == null ? null : statusMap.get(nameInDatabase);
1025 if (existingFile == null) {
1026 df = fileManager.
addDerivedFile(node.getFileName(), node.getLocalRelPath(), node.getSize(),
1027 node.getCtime(), node.getCrtime(), node.getAtime(), node.getMtime(),
1029 "",
"", TskData.EncodingType.XOR1);
1032 String key = getKeyAbstractFile(existingFile.
getFile());
1035 statusMap.put(key, existingFile);
1039 String mimeType = existingFile.
getFile().getMIMEType().equalsIgnoreCase(
"application/octet-stream") ? null : existingFile.
getFile().getMIMEType();
1041 node.getCtime(), node.getCrtime(), node.getAtime(), node.getMtime(),
1043 "",
"", TskData.EncodingType.XOR1);
1047 df = (DerivedFile) existingFile.
getFile();
1051 }
catch (TskCoreException ex) {
1052 logger.log(Level.SEVERE,
"Error adding a derived file to db:" + node.getFileName(), ex);
1053 throw new TskCoreException(
1054 NbBundle.getMessage(SevenZipExtractor.class,
"EmbeddedFileExtractorIngestModule.ArchiveExtractor.UnpackedTree.exception.msg",
1055 node.getFileName()), ex);
1059 updateOrAddFileToCaseRec(child, fileManager, statusMap, getKeyFromUnpackedNode(node, archiveFilePath));
1070 private List<UnpackedNode>
children =
new ArrayList<>();
1071 private String localRelPath =
"";
1073 private long ctime, crtime, atime, mtime;
1114 void addDerivedInfo(
long size,
1116 long ctime,
long crtime,
long atime,
long mtime, String relLocalPath) {
1120 this.crtime = crtime;
1123 this.localRelPath = relLocalPath;
1126 void setFile(AbstractFile file) {
1137 UnpackedNode getChild(String childFileName) {
1138 UnpackedNode ret = null;
1139 for (UnpackedNode child : children) {
1140 if (child.fileName.equals(childFileName)) {
1176 private final List<Archive>
archives =
new ArrayList<>();
1185 Archive findArchive(
long objectId) {
1187 if (ar.objectId == objectId) {
1203 Archive addArchive(Archive parent,
long objectId) {
1204 Archive child =
new Archive(parent, objectId);
1205 archives.add(child);
1214 List<Archive> children;
1217 this.parent = parent;
1218 this.objectId = objectId;
1219 children =
new ArrayList<>();
1220 if (parent != null) {
1221 parent.children.add(
this);
1222 this.depth = parent.depth + 1;
1256 abstractFile = file;
FileManager getFileManager()
static Case getOpenCase()
synchronized DerivedFile addDerivedFile(String fileName, String localPath, long size, long ctime, long crtime, long atime, long mtime, boolean isFile, Content parentObj, String rederiveDetails, String toolName, String toolVersion, String otherDetails, TskData.EncodingType encodingType)
static final int DISK_FREE_SPACE_UNKNOWN
synchronized DerivedFile updateDerivedFile(DerivedFile derivedFile, String localPath, long size, long ctime, long crtime, long atime, long mtime, boolean isFile, String mimeType, String rederiveDetails, String toolName, String toolVersion, String otherDetails, TskData.EncodingType encodingType)