mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-19 11:07:43 +00:00
Use streaming ingest for disk images in auto ingest
This commit is contained in:
parent
b7839b3aa9
commit
bd480827b5
@ -19,6 +19,7 @@
|
|||||||
package org.sleuthkit.autopsy.casemodule;
|
package org.sleuthkit.autopsy.casemodule;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestJob;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestStream;
|
import org.sleuthkit.autopsy.ingest.IngestStream;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestStreamClosedException;
|
import org.sleuthkit.autopsy.ingest.IngestStreamClosedException;
|
||||||
|
|
||||||
@ -36,6 +37,11 @@ class DefaultIngestStream implements IngestStream {
|
|||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IngestJob getIngestJob() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized boolean isClosed() {
|
public synchronized boolean isClosed() {
|
||||||
return isClosed;
|
return isClosed;
|
||||||
|
@ -465,6 +465,42 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
|
|||||||
doAddImageProcess(deviceId, dataSourcePath.toString(), sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, progressMonitor, callBack);
|
doAddImageProcess(deviceId, dataSourcePath.toString(), sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, progressMonitor, callBack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IngestStream processWithIngestStream(String deviceId, Path dataSourcePath, IngestJobSettings settings, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
||||||
|
this.deviceId = deviceId;
|
||||||
|
this.imagePath = dataSourcePath.toString();
|
||||||
|
this.sectorSize = 0;
|
||||||
|
this.timeZone = Calendar.getInstance().getTimeZone().getID();
|
||||||
|
this.ignoreFatOrphanFiles = false;
|
||||||
|
setDataSourceOptionsCalled = true;
|
||||||
|
|
||||||
|
// Set up the data source before creating the ingest stream
|
||||||
|
try {
|
||||||
|
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
|
||||||
|
new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
|
||||||
|
final List<String> errors = new ArrayList<>();
|
||||||
|
errors.add(ex.getMessage());
|
||||||
|
callBack.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now initialize the ingest stream
|
||||||
|
try {
|
||||||
|
ingestStream = IngestManager.getInstance().openIngestStream(image, settings);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error starting ingest modules", ex);
|
||||||
|
final List<String> errors = new ArrayList<>();
|
||||||
|
errors.add(ex.getMessage());
|
||||||
|
callBack.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
doAddImageProcess(deviceId, dataSourcePath.toString(), sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, progressMonitor, callBack);
|
||||||
|
return ingestStream;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the configuration of the data source processor without using the
|
* Sets the configuration of the data source processor without using the
|
||||||
* selection and configuration panel.
|
* selection and configuration panel.
|
||||||
|
@ -22,6 +22,8 @@ import java.nio.file.Path;
|
|||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface implemented by DataSourceProcessors in order to be supported by
|
* Interface implemented by DataSourceProcessors in order to be supported by
|
||||||
@ -66,6 +68,10 @@ public interface AutoIngestDataSourceProcessor extends DataSourceProcessor {
|
|||||||
*/
|
*/
|
||||||
void process(String deviceId, Path dataSourcePath, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack);
|
void process(String deviceId, Path dataSourcePath, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack);
|
||||||
|
|
||||||
|
default IngestStream processWithIngestStream(String deviceId, Path dataSourcePath, IngestJobSettings settings, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
||||||
|
throw new UnsupportedOperationException("Streaming ingest not supported for this data source processor");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A custom exception for the use of AutomatedIngestDataSourceProcessor.
|
* A custom exception for the use of AutomatedIngestDataSourceProcessor.
|
||||||
*/
|
*/
|
||||||
|
@ -59,6 +59,11 @@ class IngestJobInputStream implements IngestStream {
|
|||||||
ingestJob.addStreamingIngestFiles(fileObjectIds);
|
ingestJob.addStreamingIngestFiles(fileObjectIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IngestJob getIngestJob() {
|
||||||
|
return ingestJob;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void close() {
|
public synchronized void close() {
|
||||||
closed = true;
|
closed = true;
|
||||||
|
@ -35,6 +35,8 @@ public interface IngestStream {
|
|||||||
*/
|
*/
|
||||||
void addFiles(List<Long> fileObjectIds) throws IngestStreamClosedException;
|
void addFiles(List<Long> fileObjectIds) throws IngestStreamClosedException;
|
||||||
|
|
||||||
|
IngestJob getIngestJob();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the ingest stream. Should be called after all files from data
|
* Closes the ingest stream. Should be called after all files from data
|
||||||
* source have been sent to the stream.
|
* source have been sent to the stream.
|
||||||
|
@ -101,6 +101,7 @@ import org.sleuthkit.autopsy.ingest.IngestJobSettings;
|
|||||||
import org.sleuthkit.autopsy.ingest.IngestJobStartResult;
|
import org.sleuthkit.autopsy.ingest.IngestJobStartResult;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleError;
|
import org.sleuthkit.autopsy.ingest.IngestModuleError;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestStream;
|
||||||
import org.sleuthkit.autopsy.keywordsearch.KeywordSearchModuleException;
|
import org.sleuthkit.autopsy.keywordsearch.KeywordSearchModuleException;
|
||||||
import org.sleuthkit.autopsy.keywordsearch.Server;
|
import org.sleuthkit.autopsy.keywordsearch.Server;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
@ -165,6 +166,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
private AutoIngestJob currentJob;
|
private AutoIngestJob currentJob;
|
||||||
@GuardedBy("jobsLock")
|
@GuardedBy("jobsLock")
|
||||||
private List<AutoIngestJob> completedJobs;
|
private List<AutoIngestJob> completedJobs;
|
||||||
|
private IngestStream currentIngestStream = null;
|
||||||
private CoordinationService coordinationService;
|
private CoordinationService coordinationService;
|
||||||
private JobProcessingTask jobProcessingTask;
|
private JobProcessingTask jobProcessingTask;
|
||||||
private Future<?> jobProcessingTaskFuture;
|
private Future<?> jobProcessingTaskFuture;
|
||||||
@ -2443,6 +2445,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentIngestStream = null;
|
||||||
runDataSourceProcessor(caseForJob, dataSource);
|
runDataSourceProcessor(caseForJob, dataSource);
|
||||||
if (dataSource.getContent().isEmpty()) {
|
if (dataSource.getContent().isEmpty()) {
|
||||||
currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED, Date.from(Instant.now()));
|
currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED, Date.from(Instant.now()));
|
||||||
@ -2558,7 +2561,13 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
caseForJob.notifyAddingDataSource(taskId);
|
caseForJob.notifyAddingDataSource(taskId);
|
||||||
jobLogger.logDataSourceProcessorSelected(selectedProcessor.getDataSourceType());
|
jobLogger.logDataSourceProcessorSelected(selectedProcessor.getDataSourceType());
|
||||||
sysLogger.log(Level.INFO, "Identified data source type for {0} as {1}", new Object[]{manifestPath, selectedProcessor.getDataSourceType()});
|
sysLogger.log(Level.INFO, "Identified data source type for {0} as {1}", new Object[]{manifestPath, selectedProcessor.getDataSourceType()});
|
||||||
|
if (selectedProcessor.supportsIngestStream()) {
|
||||||
|
IngestJobSettings ingestJobSettings = new IngestJobSettings(AutoIngestUserPreferences.getAutoModeIngestModuleContextString());
|
||||||
|
// TODO check for settings errors
|
||||||
|
currentIngestStream = selectedProcessor.processWithIngestStream(dataSource.getDeviceId(), dataSource.getPath(), ingestJobSettings, progressMonitor, callBack);
|
||||||
|
} else {
|
||||||
selectedProcessor.process(dataSource.getDeviceId(), dataSource.getPath(), progressMonitor, callBack);
|
selectedProcessor.process(dataSource.getDeviceId(), dataSource.getPath(), progressMonitor, callBack);
|
||||||
|
}
|
||||||
ingestLock.wait();
|
ingestLock.wait();
|
||||||
|
|
||||||
// at this point we got the content object(s) from the current DSP.
|
// at this point we got the content object(s) from the current DSP.
|
||||||
@ -2674,11 +2683,19 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, ingestJobEventListener);
|
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, ingestJobEventListener);
|
||||||
try {
|
try {
|
||||||
synchronized (ingestLock) {
|
synchronized (ingestLock) {
|
||||||
|
// TODO don't do all this
|
||||||
IngestJobSettings ingestJobSettings = new IngestJobSettings(AutoIngestUserPreferences.getAutoModeIngestModuleContextString());
|
IngestJobSettings ingestJobSettings = new IngestJobSettings(AutoIngestUserPreferences.getAutoModeIngestModuleContextString());
|
||||||
List<String> settingsWarnings = ingestJobSettings.getWarnings();
|
List<String> settingsWarnings = ingestJobSettings.getWarnings();
|
||||||
if (settingsWarnings.isEmpty()) {
|
if (settingsWarnings.isEmpty()) {
|
||||||
IngestJobStartResult ingestJobStartResult = IngestManager.getInstance().beginIngestJob(dataSource.getContent(), ingestJobSettings);
|
|
||||||
IngestJob ingestJob = ingestJobStartResult.getJob();
|
IngestJobStartResult ingestJobStartResult = null;
|
||||||
|
IngestJob ingestJob;
|
||||||
|
if (currentIngestStream == null) {
|
||||||
|
ingestJobStartResult = IngestManager.getInstance().beginIngestJob(dataSource.getContent(), ingestJobSettings);
|
||||||
|
ingestJob = ingestJobStartResult.getJob();
|
||||||
|
} else {
|
||||||
|
ingestJob = currentIngestStream.getIngestJob();
|
||||||
|
}
|
||||||
if (null != ingestJob) {
|
if (null != ingestJob) {
|
||||||
currentJob.setIngestJob(ingestJob);
|
currentJob.setIngestJob(ingestJob);
|
||||||
/*
|
/*
|
||||||
@ -2714,7 +2731,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!ingestJobStartResult.getModuleErrors().isEmpty()) {
|
} else if (ingestJobStartResult != null && !ingestJobStartResult.getModuleErrors().isEmpty()) {
|
||||||
for (IngestModuleError error : ingestJobStartResult.getModuleErrors()) {
|
for (IngestModuleError error : ingestJobStartResult.getModuleErrors()) {
|
||||||
sysLogger.log(Level.SEVERE, String.format("%s ingest module startup error for %s", error.getModuleDisplayName(), manifestPath), error.getThrowable());
|
sysLogger.log(Level.SEVERE, String.format("%s ingest module startup error for %s", error.getModuleDisplayName(), manifestPath), error.getThrowable());
|
||||||
}
|
}
|
||||||
@ -2722,7 +2739,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
setErrorsOccurredFlagForCase(caseDirectoryPath);
|
setErrorsOccurredFlagForCase(caseDirectoryPath);
|
||||||
jobLogger.logIngestModuleStartupErrors();
|
jobLogger.logIngestModuleStartupErrors();
|
||||||
throw new AnalysisStartupException(String.format("Error(s) during ingest module startup for %s", manifestPath));
|
throw new AnalysisStartupException(String.format("Error(s) during ingest module startup for %s", manifestPath));
|
||||||
} else {
|
} else if (ingestJobStartResult != null) {
|
||||||
sysLogger.log(Level.SEVERE, String.format("Ingest manager ingest job start error for %s", manifestPath), ingestJobStartResult.getStartupException());
|
sysLogger.log(Level.SEVERE, String.format("Ingest manager ingest job start error for %s", manifestPath), ingestJobStartResult.getStartupException());
|
||||||
currentJob.setErrorsOccurred(true);
|
currentJob.setErrorsOccurred(true);
|
||||||
setErrorsOccurredFlagForCase(caseDirectoryPath);
|
setErrorsOccurredFlagForCase(caseDirectoryPath);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user