updates for auto ingest

This commit is contained in:
Greg DiCristofaro 2025-01-16 20:24:35 -05:00
parent ab5e8e1cfd
commit 5d527e712c
No known key found for this signature in database
5 changed files with 88 additions and 11 deletions

View File

@ -53,7 +53,7 @@ public class CommandLineOptionProcessor extends OptionProcessor {
private final Option dataSourcePathOption = Option.requiredArgument('s', "dataSourcePath"); private final Option dataSourcePathOption = Option.requiredArgument('s', "dataSourcePath");
private final Option dataSourceObjectIdOption = Option.requiredArgument('i', "dataSourceObjectId"); private final Option dataSourceObjectIdOption = Option.requiredArgument('i', "dataSourceObjectId");
private final Option addDataSourceCommandOption = Option.withoutArgument('a', "addDataSource"); private final Option addDataSourceCommandOption = Option.withoutArgument('a', "addDataSource");
private final Option bitlockerKeyCommandOption = Option.withoutArgument('k', "key"); private final Option bitlockerKeyCommandOption = Option.requiredArgument('k', "key");
private final Option runIngestCommandOption = Option.optionalArgument('r', "runIngest"); private final Option runIngestCommandOption = Option.optionalArgument('r', "runIngest");
private final Option listAllDataSourcesCommandOption = Option.withoutArgument('l', "listAllDataSources"); private final Option listAllDataSourcesCommandOption = Option.withoutArgument('l', "listAllDataSources");
private final Option generateReportsOption = Option.optionalArgument('g', "generateReports"); private final Option generateReportsOption = Option.optionalArgument('g', "generateReports");

View File

@ -22,12 +22,14 @@ import org.sleuthkit.datamodel.SleuthkitJNI;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.logging.Level;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
/** /**
* Utility methods for working with data sources. * Utility methods for working with data sources.
*/ */
public class DataSourceUtils { public class DataSourceUtils {
private static final Logger logger = Logger.getLogger(DataSourceUtils.class.getName());
/** /**
* Calls TSK to determine whether a * Calls TSK to determine whether a
@ -44,24 +46,37 @@ public class DataSourceUtils {
return SleuthkitJNI.isImageSupported(dataSourcePath.toString()); return SleuthkitJNI.isImageSupported(dataSourcePath.toString());
} }
/**
* Calls TSK to determine whether a
* potential data source has a file system.
*
* @param dataSourcePath The path to the data source.
* @param password The password to decrypt the image.
*
* @return True or false.
*
* @throws IOException if an error occurs while trying to determine if the
* data source has a file system.
*/
public static boolean imageHasFileSystem(Path dataSourcePath, String password) throws IOException { public static boolean imageHasFileSystem(Path dataSourcePath, String password) throws IOException {
try { try {
// LOGGER.info("Testing if disk image {} can be opened", hostPath);
SleuthkitJNI.TestOpenImageResult openImageResult = SleuthkitJNI.testOpenImage(dataSourcePath.toString(), password); SleuthkitJNI.TestOpenImageResult openImageResult = SleuthkitJNI.testOpenImage(dataSourcePath.toString(), password);
if (!openImageResult.wasSuccessful()) { if (openImageResult.wasSuccessful()) {
return true;
} else {
String message = MessageFormat.format("An error occurred while opening {0}: {1}", String message = MessageFormat.format("An error occurred while opening {0}: {1}",
dataSourcePath.toString(), dataSourcePath.toString(),
openImageResult == null || StringUtils.isBlank(openImageResult.getMessage()) openImageResult == null || StringUtils.isBlank(openImageResult.getMessage())
? "<unknown>" ? "<unknown>"
: openImageResult.getMessage()); : openImageResult.getMessage());
logger.log(Level.INFO, message);
return false; return false;
} }
} catch (Throwable ex) { } catch (Throwable ex) {
String message = "An error occurred while opening " + dataSourcePath.toString(); String message = "An error occurred while opening " + dataSourcePath.toString();
logger.log(Level.WARNING, message);
return false; return false;
} }
return SleuthkitJNI.isImageSupported(dataSourcePath.toString());
} }
} }

View File

@ -157,7 +157,7 @@ public class DataSourceProcessorUtility {
* org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException * org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException
*/ */
public static List<AutoIngestDataSourceProcessor> getOrderedListOfDataSourceProcessors(Path dataSourcePath, String password, Collection<? extends AutoIngestDataSourceProcessor> processorCandidates) throws AutoIngestDataSourceProcessorException { public static List<AutoIngestDataSourceProcessor> getOrderedListOfDataSourceProcessors(Path dataSourcePath, String password, Collection<? extends AutoIngestDataSourceProcessor> processorCandidates) throws AutoIngestDataSourceProcessorException {
Map<AutoIngestDataSourceProcessor, Integer> validDataSourceProcessorsMap = getDataSourceProcessorForFile(dataSourcePath, processorCandidates); Map<AutoIngestDataSourceProcessor, Integer> validDataSourceProcessorsMap = getDataSourceProcessorForFile(dataSourcePath, password, processorCandidates);
return orderDataSourceProcessorsByConfidence(validDataSourceProcessorsMap); return orderDataSourceProcessorsByConfidence(validDataSourceProcessorsMap);
} }

View File

@ -106,6 +106,12 @@ final class AutoIngestJob implements Comparable<AutoIngestJob>, IngestProgressSn
*/ */
private boolean ocrEnabled; private boolean ocrEnabled;
/**
* Version 5 fields
*/
@GuardedBy("this")
private String password;
/** /**
* Constructs a new automated ingest job. All job state not specified in the * Constructs a new automated ingest job. All job state not specified in the
* job manifest is set to the default state for a new job. * job manifest is set to the default state for a new job.
@ -166,7 +172,7 @@ final class AutoIngestJob implements Comparable<AutoIngestJob>, IngestProgressSn
/* /*
* Version 0 fields. * Version 0 fields.
*/ */
this.manifest = new Manifest(nodeData.getManifestFilePath(), nodeData.getManifestFileDate(), nodeData.getCaseName(), nodeData.getDeviceId(), nodeData.getDataSourcePath(), Collections.emptyMap()); this.manifest = new Manifest(nodeData.getManifestFilePath(), nodeData.getManifestFileDate(), nodeData.getCaseName(), nodeData.getDeviceId(), nodeData.getDataSourcePath(), nodeData.getPassword(), Collections.emptyMap());
this.nodeName = nodeData.getProcessingHostName(); this.nodeName = nodeData.getProcessingHostName();
this.caseDirectoryPath = nodeData.getCaseDirectoryPath().toString(); this.caseDirectoryPath = nodeData.getCaseDirectoryPath().toString();
this.priority = nodeData.getPriority(); this.priority = nodeData.getPriority();
@ -204,6 +210,11 @@ final class AutoIngestJob implements Comparable<AutoIngestJob>, IngestProgressSn
*/ */
this.ocrEnabled = nodeData.getOcrEnabled(); this.ocrEnabled = nodeData.getOcrEnabled();
/**
* Version 5 fields
*/
this.password = nodeData.getPassword();
} catch (Exception ex) { } catch (Exception ex) {
throw new AutoIngestJobException(String.format("Error creating automated ingest job"), ex); throw new AutoIngestJobException(String.format("Error creating automated ingest job"), ex);
} }
@ -282,6 +293,21 @@ final class AutoIngestJob implements Comparable<AutoIngestJob>, IngestProgressSn
this.ocrEnabled = enabled; this.ocrEnabled = enabled;
} }
/**
* @return The password to decrypt the image.
*/
synchronized String getPassword() {
return password;
}
/**
* @param password The password to decrypt the image.
*/
synchronized void setPassword(String password) {
this.password = password;
}
/** /**
* Sets the processing stage of the job. The start date/time for the stage * Sets the processing stage of the job. The start date/time for the stage
* is set when the stage is set. * is set when the stage is set.

View File

@ -24,6 +24,7 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Date; import java.util.Date;
import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeKind;
import org.apache.commons.lang3.StringUtils;
/** /**
* An object that converts auto ingest job data for an auto ingest job * An object that converts auto ingest job data for an auto ingest job
@ -31,7 +32,7 @@ import javax.lang.model.type.TypeKind;
*/ */
final class AutoIngestJobNodeData { final class AutoIngestJobNodeData {
private static final int CURRENT_VERSION = 3; private static final int CURRENT_VERSION = 4;
private static final int DEFAULT_PRIORITY = 0; private static final int DEFAULT_PRIORITY = 0;
/* /*
@ -84,6 +85,12 @@ final class AutoIngestJobNodeData {
*/ */
private boolean ocrEnabled; private boolean ocrEnabled;
/**
* Version 4 fields.
*/
private String password; // password to decrypt the image
/** /**
* Gets the current version of the auto ingest job coordination service node * Gets the current version of the auto ingest job coordination service node
* data. * data.
@ -121,6 +128,7 @@ final class AutoIngestJobNodeData {
setProcessingStageDetails(job.getProcessingStageDetails()); setProcessingStageDetails(job.getProcessingStageDetails());
setDataSourceSize(job.getDataSourceSize()); setDataSourceSize(job.getDataSourceSize());
setOcrEnabled(job.getOcrEnabled()); setOcrEnabled(job.getOcrEnabled());
setPassword(manifest.getPassword());
} }
/** /**
@ -157,6 +165,7 @@ final class AutoIngestJobNodeData {
this.processingStageDetailsStartDate = 0L; this.processingStageDetailsStartDate = 0L;
this.dataSourceSize = 0L; this.dataSourceSize = 0L;
this.ocrEnabled = false; this.ocrEnabled = false;
this.password = "";
/* /*
* Get fields from node data. * Get fields from node data.
@ -208,6 +217,13 @@ final class AutoIngestJobNodeData {
this.ocrEnabled = (1 == ocrFlag); this.ocrEnabled = (1 == ocrFlag);
} }
if (buffer.hasRemaining()) {
/*
* Get version 4 fields.
*/
setPassword(getStringFromBuffer(buffer, TypeKind.SHORT));
}
} catch (BufferUnderflowException ex) { } catch (BufferUnderflowException ex) {
throw new InvalidDataException("Node data is incomplete", ex); throw new InvalidDataException("Node data is incomplete", ex);
} }
@ -471,6 +487,22 @@ final class AutoIngestJobNodeData {
} }
} }
/**
* @return The password to decrypt the image. Empty indicates no password.
*/
public String getPassword() {
return password;
}
/**
* @param password The password to decrypt the image.
*/
public void setPassword(String password) {
this.password = StringUtils.defaultString(password);
}
/** /**
* Get the processing stage of the job. * Get the processing stage of the job.
* *
@ -604,6 +636,10 @@ final class AutoIngestJobNodeData {
if (this.version >= 3) { if (this.version >= 3) {
buffer.putInt(this.ocrEnabled ? 1 : 0); buffer.putInt(this.ocrEnabled ? 1 : 0);
} }
if (this.version >= 4) {
putStringIntoBuffer(this.password, buffer, TypeKind.SHORT);
}
} }
// Prepare the array // Prepare the array