devices) throws InterruptedException, PauseRequiredException {
- Path deviceFolderPath = currentJob.getImageFolderPath();
- Path caseFolderPath = currentJob.getCaseFolderPath();
-
- FileExporter fileExporter;
- try {
- fileExporter = new FileExporter();
- } catch (FileExportException ex) {
- logger.log(Level.SEVERE, String.format("Error initializing File Exporter when processing %s", currentJob.getImageFolderPath()), ex);
- writeErrorStateFiles(currentJob);
- new AutoIngestJobLogger(deviceFolderPath, caseFolderPath).logfileExportStartupError(ex);
- // failed to load file exporter settings, pause AIM
- throw new PauseRequiredException("Failed to load File Exporter settings", Event.PAUSED_FAILED_TO_START_FILE_EXPORTER);
- }
-
- // check whether File Exporter is enabled
- if (!fileExporter.isEnabled()) {
- new AutoIngestJobLogger(deviceFolderPath, caseFolderPath).logFileExportDisabled();
- return;
- }
-
- logger.log(Level.INFO, "Automated ingest exporting files for {0}", currentJob.getImageFolderPath());
- currentJob.getIngestStatus().setStatus(JobIngestStatus.IngestStatus.EXPORTING_FILES);
- for (DataSourceInfo device : devices) {
- try {
- fileExporter.process(device.getDeviceId(), device.getDataSourceContent());
- } catch (FileExportException ex) {
- logger.log(Level.SEVERE, String.format("Error exporting files when processing %s", currentJob.getImageFolderPath()), ex);
- writeErrorStateFiles(currentJob);
- new AutoIngestJobLogger(deviceFolderPath, caseFolderPath).logFileExportError(device.getFileName(), ex);
- }
- }
- }
-
- /*
- * Exception thrown when a user or system event requires suspension of
- * the job processing loop in the override of the run method. The
- * exception has an event field to indicate the event triggering the
- * pause.
- */
- private final class PauseRequiredException extends Exception {
-
- private static final long serialVersionUID = 1L;
- private final Event event;
-
- /**
- * Constructs a pause required exception.
- *
- * @param message A message explaining the exception.
- * @param event The event associated with the exception.
- */
- private PauseRequiredException(String message, Event event) {
- super(message);
- this.event = event;
- }
-
- /**
- * Constructs a pause required exception.
- *
- * @param message A message explaining the exception.
- * @param cause The exception that caused this exception.
- * @param event The event associated with the exception.
- */
- private PauseRequiredException(String message, Throwable cause, Event event) {
- super(message, cause);
- this.event = event;
- }
-
- /**
- * Gets the event associated with this pause required exception
- *
- * @return The event.
- */
- private Event getEvent() {
- return event;
- }
-
- }
-
- }
-
- /**
- * A representation of a data source being processed. Its methods are
- * synchronized because instances are published to code that runs in the
- * both the auto ingest task thread and in data source processor task
- * threads (see DataSourceProcessorCallback implementation in
- * AutoIngestTask).
- *
- * Instances of this class are thread-safe.
- */
- private final static class DataSourceInfo {
-
- private enum Type {
-
- CELLEBRITE_REPORT_HANDSET,
- CELLEBRITE_REPORT_SIM,
- DISK_IMAGE,
- PHONE_IMAGE,
- CELLEBRITE_ANDROID_ZIP
- }
-
- final Type type;
- final String fileName;
- final String dataSourceFolderPath;
- boolean dspCompleted;
- DataSourceProcessorCallback.DataSourceProcessorResult result;
- final List content;
- final List errorMessages;
- private String deviceId;
-
- DataSourceInfo(Type type, String fileName, String dataSourceFolderPath) {
- this.type = type;
- this.fileName = fileName;
- this.dataSourceFolderPath = dataSourceFolderPath;
- dspCompleted = false;
- result = DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS;
- content = new ArrayList<>();
- errorMessages = new ArrayList<>();
- deviceId = "";
- }
-
- String getFileName() {
- return fileName;
- }
-
- Type getType() {
- return type;
- }
-
- void setDataSourceProcessorResult(DataSourceProcessorCallback.DataSourceProcessorResult result, List errorMessages, List content) {
- dspCompleted = true;
- this.result = result;
- this.errorMessages.addAll(errorMessages);
- this.content.addAll(content);
- }
-
- boolean dataSourceProcessorCompleted() {
- return dspCompleted;
- }
-
- DataSourceProcessorCallback.DataSourceProcessorResult getDataSourceProcessorResult() {
- return result;
- }
-
- List getErrorMessages() {
- return new ArrayList<>(errorMessages);
- }
-
- List getDataSourceContent() {
- return new ArrayList<>(content);
- }
-
- String getDeviceId() {
- return deviceId;
- }
-
- void setDeviceID(String deviceId) {
- this.deviceId = deviceId;
- }
-
- String getDataSourceFolderPath() {
- return dataSourceFolderPath;
- }
- }
-
- private final static class FileFilters {
-
- private static final List CELLEBRITE_EXTS = Arrays.asList(new String[]{".bin"});
- private static final GeneralFilter binImageFilter = new GeneralFilter(CELLEBRITE_EXTS, "");
- private static final List cellebriteImageFiltersList = new ArrayList<>();
-
- static {
- cellebriteImageFiltersList.add(binImageFilter);
- }
-
- private static final GeneralFilter rawImageFilter = new GeneralFilter(GeneralFilter.RAW_IMAGE_EXTS, GeneralFilter.RAW_IMAGE_DESC);
- private static final GeneralFilter encaseImageFilter = new GeneralFilter(GeneralFilter.ENCASE_IMAGE_EXTS, GeneralFilter.ENCASE_IMAGE_DESC);
- private static final List imageFiltersList = new ArrayList<>();
-
- static {
- imageFiltersList.add(rawImageFilter);
- imageFiltersList.add(encaseImageFilter);
- }
-
- private static final List cellebriteXmlFiltersList = CellebriteXMLProcessor.getFileFilterList();
-
- private static final List ARCHIVE_EXTS = Arrays.asList(new String[]{".zip"});
- private static final GeneralFilter archiveFilter = new GeneralFilter(ARCHIVE_EXTS, "");
- private static final List archiveFiltersList = new ArrayList<>();
-
- static {
- archiveFiltersList.add(archiveFilter);
- }
-
- /**
- * Tests whether or not a file name is the name of a Cellebrite report
- * file.
- *
- * @param fileName The file name.
- * @param folderPath full path to folder containing the XML file
- *
- * @return Type of Cellebrite report if input is valid Cellebrite XML
- * report, null otherwise
- */
- private static DataSourceInfo.Type getCellebriteXmlReportType(String fileName, Path folderPath) {
- if (!isAcceptedByFiler(new File(fileName), cellebriteXmlFiltersList)) {
- return null;
- }
-
- File cellebriteXmlFile = Paths.get(folderPath.toString(), fileName).toFile();
- // read XML header info that is common for both handset and SIM Cellebrite v3.0 reports
- String report_type;
- try {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- DocumentBuilder builder = factory.newDocumentBuilder();
- Document doc = builder.parse(cellebriteXmlFile);
- XPathFactory xPathfactory = XPathFactory.newInstance();
- XPath xpath = xPathfactory.newXPath();
- XPathExpression expr = xpath.compile("/reports/report/general_information/report_type/text()");
- report_type = (String) expr.evaluate(doc, XPathConstants.STRING);
- if (report_type.equalsIgnoreCase("sim")) {
- return DataSourceInfo.Type.CELLEBRITE_REPORT_SIM;
- } else if (report_type.equalsIgnoreCase("cell")) {
- return DataSourceInfo.Type.CELLEBRITE_REPORT_HANDSET;
- } else {
- return null;
- }
- } catch (Exception ignore) {
- // not a valid cellebrite XML file
- return null;
- }
- }
-
- private static boolean isFirstFileOfDiskOrPhoneImage(String fileName) {
-
- // is file a disk image or phone image (and is NOT part of split image)
- if (!isAcceptedByFiler(new File(fileName), imageFiltersList)) {
- return false;
- }
-
- return !isPartOfSplitCellebriteImage(fileName);
- }
-
- private static boolean isAcceptedByFiler(File file, List filters) {
-
- for (FileFilter filter : filters) {
- if (filter.accept(file)) {
- return true;
- }
- }
- return false;
- }
-
- private static boolean isPartOfSplitCellebriteImage(String fileName) {
-
- // only need to worry about ".bin" images
- if (!isAcceptedByFiler(new File(fileName), cellebriteImageFiltersList)) {
- return false;
- }
-
- // this needs to identify and handle different Cellebrite scenarios:
- // i single image in a single file
- // ii. Single image split over multiple files - just need to pass the first to TSK and it will combine the split image files.
- // Note there may be more than than one split images in a single dir,
- // e.g. blk0_mmcblk0.bin, blk0_mmcblk0(1).bin......, and blk24_mmcblk1.bin, blk24_mmcblk1(1).bin......
- //iii. Multiple image files - one per volume - need to handle each one separately
- // e.g. blk0_mmcblk0.bin, mtd0_system.bin, mtd1_cache.bin, mtd2_userdata.bin
- String fNameNoExt = FilenameUtils.removeExtension(fileName.toLowerCase());
- return fNameNoExt.matches("\\w+\\(\\d+\\)");
- }
-
- private static String[] getAllFilesInFolder(String path) {
- // only returns files, skips folders
- File file = new File(path);
- String[] files = file.list((File current, String name) -> new File(current, name).isFile());
- return files;
- }
-
- private FileFilters() {
- }
- }
-
-}
diff --git a/Experimental/src/org/sleuthkit/autopsy/autoingest/DurationCellRenderer.java b/Experimental/src/org/sleuthkit/autopsy/autoingest/DurationCellRenderer.java
index 6059dfa6df..f0f5e9aa92 100644
--- a/Experimental/src/org/sleuthkit/autopsy/autoingest/DurationCellRenderer.java
+++ b/Experimental/src/org/sleuthkit/autopsy/autoingest/DurationCellRenderer.java
@@ -5,7 +5,7 @@
* Copyright (c) 2013-2015 Basis Technology Corporation.
* Contact: brianc@basistech.com
*/
-package viking.autoingest;
+package org.sleuthkit.autopsy.autoingest;
import java.awt.Component;
import java.time.Duration;