mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
updates for auto ingest
This commit is contained in:
parent
b0a26d14c6
commit
f875da5c12
@ -27,6 +27,7 @@ import java.util.List;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import javax.swing.filechooser.FileFilter;
|
import javax.swing.filechooser.FileFilter;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.openide.util.lookup.ServiceProviders;
|
import org.openide.util.lookup.ServiceProviders;
|
||||||
@ -184,7 +185,7 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
||||||
run(null, progressMonitor, callback);
|
run(null, null, progressMonitor, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,9 +205,16 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
public void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
||||||
|
run(null, host, progressMonitor, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(String password, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
||||||
ingestStream = new DefaultIngestStream();
|
ingestStream = new DefaultIngestStream();
|
||||||
readConfigSettings();
|
readConfigSettings();
|
||||||
this.host = host;
|
this.host = host;
|
||||||
|
this.password = StringUtils.defaultString(password, this.password);
|
||||||
try {
|
try {
|
||||||
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
|
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
|
||||||
new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, this.password, this.host);
|
new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, this.password, this.host);
|
||||||
@ -221,6 +229,46 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
|
|||||||
doAddImageProcess(deviceId, imagePath, sectorSize, timeZone, ignoreFatOrphanFiles, md5, sha1, sha256, this.password, progressMonitor, callback);
|
doAddImageProcess(deviceId, imagePath, sectorSize, timeZone, ignoreFatOrphanFiles, md5, sha1, sha256, this.password, progressMonitor, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a data source to the case database using a background task in a
|
||||||
|
* separate thread and the given settings instead of those provided by the
|
||||||
|
* selection and configuration panel. Returns as soon as the background task
|
||||||
|
* is started and uses the callback object to signal task completion and
|
||||||
|
* return results.
|
||||||
|
*
|
||||||
|
* @param deviceId An ASCII-printable identifier for the device
|
||||||
|
* associated with the data source that is
|
||||||
|
* intended to be unique across multiple cases
|
||||||
|
* (e.g., a UUID).
|
||||||
|
* @param imagePath Path to the image file.
|
||||||
|
* @param timeZone The time zone to use when processing dates
|
||||||
|
* and times for the image, obtained from
|
||||||
|
* java.util.TimeZone.getID.
|
||||||
|
* @param ignoreFatOrphanFiles Whether to parse orphans if the image has a
|
||||||
|
* FAT filesystem.
|
||||||
|
* @param progressMonitor Progress monitor for reporting progress
|
||||||
|
* during processing.
|
||||||
|
* @param callback Callback to call when processing is done.
|
||||||
|
*/
|
||||||
|
public void run(String deviceId, String imagePath, String timeZone, boolean ignoreFatOrphanFiles, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
||||||
|
ingestStream = new DefaultIngestStream();
|
||||||
|
try {
|
||||||
|
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
|
||||||
|
new String[]{imagePath}, sectorSize, timeZone, "", "", "", deviceId, null, null);
|
||||||
|
} 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
doAddImageProcess(deviceId, imagePath, 0, timeZone, ignoreFatOrphanFiles, null, null, null, this.password, progressMonitor, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a data source to the case database using a background task in a
|
* Adds a data source to the case database using a background task in a
|
||||||
* separate thread and the settings provided by the selection and
|
* separate thread and the settings provided by the selection and
|
||||||
@ -241,7 +289,7 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
|
|||||||
@Override
|
@Override
|
||||||
public void runWithIngestStream(IngestJobSettings settings, DataSourceProcessorProgressMonitor progress,
|
public void runWithIngestStream(IngestJobSettings settings, DataSourceProcessorProgressMonitor progress,
|
||||||
DataSourceProcessorCallback callBack) {
|
DataSourceProcessorCallback callBack) {
|
||||||
runWithIngestStream(null, settings, progress, callBack);
|
runWithIngestStream(null, null, settings, progress, callBack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -265,10 +313,18 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
|
|||||||
@Override
|
@Override
|
||||||
public void runWithIngestStream(Host host, IngestJobSettings settings, DataSourceProcessorProgressMonitor progress,
|
public void runWithIngestStream(Host host, IngestJobSettings settings, DataSourceProcessorProgressMonitor progress,
|
||||||
DataSourceProcessorCallback callBack) {
|
DataSourceProcessorCallback callBack) {
|
||||||
|
runWithIngestStream(null, host, settings, progress, callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runWithIngestStream(String password, Host host, IngestJobSettings settings,
|
||||||
|
DataSourceProcessorProgressMonitor progress, DataSourceProcessorCallback callBack) {
|
||||||
|
|
||||||
// Read the settings from the wizard
|
// Read the settings from the wizard
|
||||||
readConfigSettings();
|
readConfigSettings();
|
||||||
this.host = host;
|
this.host = host;
|
||||||
|
this.password = StringUtils.defaultIfEmpty(password, this.password);
|
||||||
|
|
||||||
// Set up the data source before creating the ingest stream
|
// Set up the data source before creating the ingest stream
|
||||||
try {
|
try {
|
||||||
@ -296,6 +352,7 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
|
|||||||
doAddImageProcess(deviceId, imagePath, sectorSize, timeZone, ignoreFatOrphanFiles, md5, sha1, sha256, this.password, progress, callBack);
|
doAddImageProcess(deviceId, imagePath, sectorSize, timeZone, ignoreFatOrphanFiles, md5, sha1, sha256, this.password, progress, callBack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store the options from the config panel.
|
* Store the options from the config panel.
|
||||||
*/
|
*/
|
||||||
@ -334,42 +391,6 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a data source to the case database using a background task in a
|
|
||||||
* separate thread and the given settings instead of those provided by the
|
|
||||||
* selection and configuration panel. Returns as soon as the background task
|
|
||||||
* is started and uses the callback object to signal task completion and
|
|
||||||
* return results.
|
|
||||||
*
|
|
||||||
* @param deviceId An ASCII-printable identifier for the device
|
|
||||||
* associated with the data source that is
|
|
||||||
* intended to be unique across multiple cases
|
|
||||||
* (e.g., a UUID).
|
|
||||||
* @param imagePath Path to the image file.
|
|
||||||
* @param timeZone The time zone to use when processing dates
|
|
||||||
* and times for the image, obtained from
|
|
||||||
* java.util.TimeZone.getID.
|
|
||||||
* @param ignoreFatOrphanFiles Whether to parse orphans if the image has a
|
|
||||||
* FAT filesystem.
|
|
||||||
* @param progressMonitor Progress monitor for reporting progress
|
|
||||||
* during processing.
|
|
||||||
* @param callback Callback to call when processing is done.
|
|
||||||
*/
|
|
||||||
public void run(String deviceId, String imagePath, String timeZone, boolean ignoreFatOrphanFiles, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
|
||||||
ingestStream = new DefaultIngestStream();
|
|
||||||
try {
|
|
||||||
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
|
|
||||||
new String[]{imagePath}, sectorSize, timeZone, "", "", "", deviceId, this.password, null);
|
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
doAddImageProcess(deviceId, imagePath, 0, timeZone, ignoreFatOrphanFiles, null, null, null, this.password, progressMonitor, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a data source to the case database using a background task in a
|
* Adds a data source to the case database using a background task in a
|
||||||
@ -472,6 +493,13 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int canProcess(Path dataSourcePath) throws AutoIngestDataSourceProcessorException {
|
public int canProcess(Path dataSourcePath) throws AutoIngestDataSourceProcessorException {
|
||||||
|
return canProcess(dataSourcePath, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int canProcess(Path dataSourcePath, String password) throws AutoIngestDataSourceProcessorException {
|
||||||
|
|
||||||
// check file extension for supported types
|
// check file extension for supported types
|
||||||
if (!isAcceptedByFiler(dataSourcePath.toFile(), filtersList)) {
|
if (!isAcceptedByFiler(dataSourcePath.toFile(), filtersList)) {
|
||||||
@ -504,23 +532,29 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(String deviceId, Path dataSourcePath, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
public void process(String deviceId, Path dataSourcePath, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
||||||
process(deviceId, dataSourcePath, null, progressMonitor, callBack);
|
process(deviceId, dataSourcePath, this.password, null, progressMonitor, callBack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(String deviceId, Path dataSourcePath, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
public void process(String deviceId, Path dataSourcePath, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
||||||
|
process(deviceId, dataSourcePath, this.password, host, progressMonitor, callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(String deviceId, Path dataSourcePath, String password, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
||||||
// this method does not use the config panel
|
// this method does not use the config panel
|
||||||
this.deviceId = deviceId;
|
this.deviceId = deviceId;
|
||||||
this.imagePath = dataSourcePath.toString();
|
this.imagePath = dataSourcePath.toString();
|
||||||
this.sectorSize = 0;
|
this.sectorSize = 0;
|
||||||
this.timeZone = Calendar.getInstance().getTimeZone().getID();
|
this.timeZone = Calendar.getInstance().getTimeZone().getID();
|
||||||
|
this.password = password;
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.ignoreFatOrphanFiles = false;
|
this.ignoreFatOrphanFiles = false;
|
||||||
|
|
||||||
ingestStream = new DefaultIngestStream();
|
ingestStream = new DefaultIngestStream();
|
||||||
try {
|
try {
|
||||||
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
|
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
|
||||||
new String[]{imagePath}, sectorSize, timeZone, "", "", "", deviceId, this.password, host);
|
new String[]{imagePath}, sectorSize, timeZone, "", "", "", deviceId, password, host);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
|
logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
|
||||||
final List<String> errors = new ArrayList<>();
|
final List<String> errors = new ArrayList<>();
|
||||||
@ -529,28 +563,36 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
doAddImageProcess(deviceId, dataSourcePath.toString(), sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, null, progressMonitor, callBack);
|
doAddImageProcess(deviceId, dataSourcePath.toString(), sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, password, progressMonitor, callBack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IngestStream processWithIngestStream(String deviceId, Path dataSourcePath, IngestJobSettings settings, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
public IngestStream processWithIngestStream(String deviceId, Path dataSourcePath, IngestJobSettings settings, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
||||||
return processWithIngestStream(deviceId, dataSourcePath, null, settings, progressMonitor, callBack);
|
return processWithIngestStream(deviceId, dataSourcePath, this.password, null, settings, progressMonitor, callBack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IngestStream processWithIngestStream(String deviceId, Path dataSourcePath, Host host, IngestJobSettings settings, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
public IngestStream processWithIngestStream(String deviceId, Path dataSourcePath, Host host, IngestJobSettings settings, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
||||||
|
return processWithIngestStream(deviceId, dataSourcePath, this.password, host, settings, progressMonitor, callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IngestStream processWithIngestStream(String deviceId, Path dataSourcePath, String password, Host host, IngestJobSettings settings, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
||||||
// this method does not use the config panel
|
// this method does not use the config panel
|
||||||
this.deviceId = deviceId;
|
this.deviceId = deviceId;
|
||||||
this.imagePath = dataSourcePath.toString();
|
this.imagePath = dataSourcePath.toString();
|
||||||
this.sectorSize = 0;
|
this.sectorSize = 0;
|
||||||
this.timeZone = Calendar.getInstance().getTimeZone().getID();
|
this.timeZone = Calendar.getInstance().getTimeZone().getID();
|
||||||
this.host = host;
|
this.host = host;
|
||||||
|
this.password = password;
|
||||||
this.ignoreFatOrphanFiles = false;
|
this.ignoreFatOrphanFiles = false;
|
||||||
|
|
||||||
// Set up the data source before creating the ingest stream
|
// Set up the data source before creating the ingest stream
|
||||||
try {
|
try {
|
||||||
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
|
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
|
||||||
new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, this.password, host);
|
new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, password, host);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
|
logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
|
||||||
final List<String> errors = new ArrayList<>();
|
final List<String> errors = new ArrayList<>();
|
||||||
@ -570,8 +612,10 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
doAddImageProcess(deviceId, dataSourcePath.toString(), sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, null, progressMonitor, callBack);
|
doAddImageProcess(deviceId, dataSourcePath.toString(), sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, password, progressMonitor, callBack);
|
||||||
|
|
||||||
return ingestStream;
|
return ingestStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,12 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
||||||
run(null, progressMonitor, callback);
|
run(null, null, progressMonitor, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
||||||
|
run(null, host, progressMonitor, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -155,7 +160,7 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
|
|||||||
* to return results.
|
* to return results.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
public void run(String password, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
||||||
deviceId = UUID.randomUUID().toString();
|
deviceId = UUID.randomUUID().toString();
|
||||||
drivePath = configPanel.getContentPath();
|
drivePath = configPanel.getContentPath();
|
||||||
sectorSize = configPanel.getSectorSize();
|
sectorSize = configPanel.getSectorSize();
|
||||||
@ -168,12 +173,13 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.host = host;
|
this.host = host;
|
||||||
|
this.password = password;
|
||||||
|
|
||||||
Image image;
|
Image image;
|
||||||
try {
|
try {
|
||||||
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
|
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
|
||||||
new String[]{drivePath}, sectorSize,
|
new String[]{drivePath}, sectorSize,
|
||||||
timeZone, null, null, null, deviceId, this.host);
|
timeZone, null, null, null, deviceId, this.password, this.host);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Error adding local disk with path " + drivePath + " to database", ex);
|
logger.log(Level.SEVERE, "Error adding local disk with path " + drivePath + " to database", ex);
|
||||||
final List<String> errors = new ArrayList<>();
|
final List<String> errors = new ArrayList<>();
|
||||||
@ -183,7 +189,7 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addDiskTask = new AddImageTask(
|
addDiskTask = new AddImageTask(
|
||||||
new AddImageTask.ImageDetails(deviceId, image, sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, imageWriterSettings, password),
|
new AddImageTask.ImageDetails(deviceId, image, sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, imageWriterSettings, this.password),
|
||||||
progressMonitor,
|
progressMonitor,
|
||||||
new StreamingAddDataSourceCallbacks(new DefaultIngestStream()),
|
new StreamingAddDataSourceCallbacks(new DefaultIngestStream()),
|
||||||
new StreamingAddImageTaskCallback(new DefaultIngestStream(), callback));
|
new StreamingAddImageTaskCallback(new DefaultIngestStream(), callback));
|
||||||
@ -242,7 +248,7 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
|
|||||||
try {
|
try {
|
||||||
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
|
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
|
||||||
new String[]{drivePath}, sectorSize,
|
new String[]{drivePath}, sectorSize,
|
||||||
timeZone, null, null, null, deviceId);
|
timeZone, null, null, null, deviceId, this.password, null);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Error adding local disk with path " + drivePath + " to database", ex);
|
logger.log(Level.SEVERE, "Error adding local disk with path " + drivePath + " to database", ex);
|
||||||
final List<String> errors = new ArrayList<>();
|
final List<String> errors = new ArrayList<>();
|
||||||
@ -251,7 +257,7 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
addDiskTask = new AddImageTask(new AddImageTask.ImageDetails(deviceId, image, sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, imageWriterSettings, password),
|
addDiskTask = new AddImageTask(new AddImageTask.ImageDetails(deviceId, image, sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, imageWriterSettings, this.password),
|
||||||
progressMonitor,
|
progressMonitor,
|
||||||
new StreamingAddDataSourceCallbacks(new DefaultIngestStream()),
|
new StreamingAddDataSourceCallbacks(new DefaultIngestStream()),
|
||||||
new StreamingAddImageTaskCallback(new DefaultIngestStream(), callback));
|
new StreamingAddImageTaskCallback(new DefaultIngestStream(), callback));
|
||||||
|
@ -49,7 +49,9 @@ class CommandLineCommand {
|
|||||||
DATA_SOURCE_PATH,
|
DATA_SOURCE_PATH,
|
||||||
DATA_SOURCE_ID,
|
DATA_SOURCE_ID,
|
||||||
INGEST_PROFILE_NAME,
|
INGEST_PROFILE_NAME,
|
||||||
REPORT_PROFILE_NAME;
|
REPORT_PROFILE_NAME,
|
||||||
|
BITLOCKER_KEY,
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final CommandType type;
|
private final CommandType type;
|
||||||
|
@ -198,7 +198,8 @@ public class CommandLineIngestManager extends CommandLineManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String dataSourcePath = inputs.get(CommandLineCommand.InputType.DATA_SOURCE_PATH.name());
|
String dataSourcePath = inputs.get(CommandLineCommand.InputType.DATA_SOURCE_PATH.name());
|
||||||
dataSource = new AutoIngestDataSource(UUID.randomUUID().toString(), Paths.get(dataSourcePath));
|
String password = inputs.get(CommandLineCommand.InputType.BITLOCKER_KEY.name());
|
||||||
|
dataSource = new AutoIngestDataSource(UUID.randomUUID().toString(), Paths.get(dataSourcePath), password);
|
||||||
runDataSourceProcessor(caseForJob, dataSource);
|
runDataSourceProcessor(caseForJob, dataSource);
|
||||||
|
|
||||||
String outputDirPath = getOutputDirPath(caseForJob);
|
String outputDirPath = getOutputDirPath(caseForJob);
|
||||||
@ -406,7 +407,7 @@ public class CommandLineIngestManager extends CommandLineManager {
|
|||||||
// Get an ordered list of data source processors to try
|
// Get an ordered list of data source processors to try
|
||||||
List<AutoIngestDataSourceProcessor> validDataSourceProcessors;
|
List<AutoIngestDataSourceProcessor> validDataSourceProcessors;
|
||||||
try {
|
try {
|
||||||
validDataSourceProcessors = DataSourceProcessorUtility.getOrderedListOfDataSourceProcessors(dataSource.getPath());
|
validDataSourceProcessors = DataSourceProcessorUtility.getOrderedListOfDataSourceProcessors(dataSource.getPath(), dataSource.getPassword());
|
||||||
} catch (AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException ex) {
|
} catch (AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Exception while determining best data source processor for {0}", dataSource.getPath());
|
LOGGER.log(Level.SEVERE, "Exception while determining best data source processor for {0}", dataSource.getPath());
|
||||||
// rethrow the exception.
|
// rethrow the exception.
|
||||||
@ -429,7 +430,7 @@ public class CommandLineIngestManager extends CommandLineManager {
|
|||||||
DataSourceProcessorCallback callBack = new AddDataSourceCallback(caseForJob, dataSource, taskId, ingestLock);
|
DataSourceProcessorCallback callBack = new AddDataSourceCallback(caseForJob, dataSource, taskId, ingestLock);
|
||||||
caseForJob.notifyAddingDataSource(taskId);
|
caseForJob.notifyAddingDataSource(taskId);
|
||||||
LOGGER.log(Level.INFO, "Identified data source type for {0} as {1}", new Object[]{dataSource.getPath(), selectedProcessor.getDataSourceType()});
|
LOGGER.log(Level.INFO, "Identified data source type for {0} as {1}", new Object[]{dataSource.getPath(), selectedProcessor.getDataSourceType()});
|
||||||
selectedProcessor.process(dataSource.getDeviceId(), dataSource.getPath(), progressMonitor, callBack);
|
selectedProcessor.process(dataSource.getDeviceId(), dataSource.getPath(), dataSource.getPassword(), null, 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.
|
||||||
|
@ -30,6 +30,7 @@ import java.util.Set;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.netbeans.api.sendopts.CommandException;
|
import org.netbeans.api.sendopts.CommandException;
|
||||||
import org.netbeans.spi.sendopts.Env;
|
import org.netbeans.spi.sendopts.Env;
|
||||||
@ -52,6 +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 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");
|
||||||
@ -81,20 +83,21 @@ public class CommandLineOptionProcessor extends OptionProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Set<Option> getOptions() {
|
protected Set<Option> getOptions() {
|
||||||
Set<Option> set = new HashSet<>();
|
return Set.of(
|
||||||
set.add(createCaseCommandOption);
|
createCaseCommandOption,
|
||||||
set.add(caseNameOption);
|
caseNameOption,
|
||||||
set.add(caseTypeOption);
|
caseTypeOption,
|
||||||
set.add(caseBaseDirOption);
|
caseBaseDirOption,
|
||||||
set.add(dataSourcePathOption);
|
dataSourcePathOption,
|
||||||
set.add(addDataSourceCommandOption);
|
addDataSourceCommandOption,
|
||||||
set.add(dataSourceObjectIdOption);
|
bitlockerKeyCommandOption,
|
||||||
set.add(runIngestCommandOption);
|
dataSourceObjectIdOption,
|
||||||
set.add(listAllDataSourcesCommandOption);
|
runIngestCommandOption,
|
||||||
set.add(generateReportsOption);
|
listAllDataSourcesCommandOption,
|
||||||
set.add(listAllIngestProfileOption);
|
generateReportsOption,
|
||||||
set.add(defaultArgument);
|
listAllIngestProfileOption,
|
||||||
return set;
|
defaultArgument
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -203,6 +206,9 @@ public class CommandLineOptionProcessor extends OptionProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String[] keysArgs = values.get(bitlockerKeyCommandOption);
|
||||||
|
String bitlockerKey = ArrayUtils.isNotEmpty(keysArgs) ? keysArgs[0] : null;
|
||||||
|
|
||||||
String dataSourceId = "";
|
String dataSourceId = "";
|
||||||
if (values.containsKey(dataSourceObjectIdOption)) {
|
if (values.containsKey(dataSourceObjectIdOption)) {
|
||||||
|
|
||||||
@ -247,6 +253,11 @@ public class CommandLineOptionProcessor extends OptionProcessor {
|
|||||||
newCommand.addInputValue(CommandLineCommand.InputType.CASE_NAME.name(), inputCaseName);
|
newCommand.addInputValue(CommandLineCommand.InputType.CASE_NAME.name(), inputCaseName);
|
||||||
newCommand.addInputValue(CommandLineCommand.InputType.CASES_BASE_DIR_PATH.name(), caseBaseDir);
|
newCommand.addInputValue(CommandLineCommand.InputType.CASES_BASE_DIR_PATH.name(), caseBaseDir);
|
||||||
newCommand.addInputValue(CommandLineCommand.InputType.DATA_SOURCE_PATH.name(), dataSourcePath);
|
newCommand.addInputValue(CommandLineCommand.InputType.DATA_SOURCE_PATH.name(), dataSourcePath);
|
||||||
|
|
||||||
|
if (bitlockerKey != null) {
|
||||||
|
newCommand.addInputValue(CommandLineCommand.InputType.BITLOCKER_KEY.name(), bitlockerKey);
|
||||||
|
}
|
||||||
|
|
||||||
commands.add(newCommand);
|
commands.add(newCommand);
|
||||||
runFromCommandLine(true);
|
runFromCommandLine(true);
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,27 @@ public interface DataSourceProcessor {
|
|||||||
run(progressMonitor, callback);
|
run(progressMonitor, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a data source to the case database using a background task in a
|
||||||
|
* separate thread and the settings provided by the selection and
|
||||||
|
* configuration panel. Returns as soon as the background task is started.
|
||||||
|
* The background task uses a callback object to signal task completion and
|
||||||
|
* return results.
|
||||||
|
*
|
||||||
|
* This method should not be called unless isPanelValid returns true.
|
||||||
|
*
|
||||||
|
* @param password The password
|
||||||
|
* @param host Host for the data source.
|
||||||
|
* @param progressMonitor Progress monitor that will be used by the
|
||||||
|
* background task to report progress.
|
||||||
|
* @param callback Callback that will be used by the background task
|
||||||
|
* to return results.
|
||||||
|
*/
|
||||||
|
default void run(String password, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
||||||
|
run(host, progressMonitor, callback);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a data source to the case database using a background task in a
|
* Adds a data source to the case database using a background task in a
|
||||||
* separate thread and the settings provided by the selection and
|
* separate thread and the settings provided by the selection and
|
||||||
@ -176,6 +197,31 @@ public interface DataSourceProcessor {
|
|||||||
runWithIngestStream(settings, progress, callBack);
|
runWithIngestStream(settings, progress, callBack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a data source to the case database using a background task in a
|
||||||
|
* separate thread and the settings provided by the selection and
|
||||||
|
* configuration panel. Files found during ingest will be sent directly to
|
||||||
|
* the IngestStream provided. Returns as soon as the background task is
|
||||||
|
* started. The background task uses a callback object to signal task
|
||||||
|
* completion and return results.
|
||||||
|
*
|
||||||
|
* This method should not be called unless isPanelValid returns true, and
|
||||||
|
* should only be called for DSPs that support ingest streams. The ingest
|
||||||
|
* settings must be complete before calling this method.
|
||||||
|
*
|
||||||
|
* @param password The password to decrypt the data source.
|
||||||
|
* @param host Host for this data source.
|
||||||
|
* @param settings The ingest job settings.
|
||||||
|
* @param progress Progress monitor that will be used by the background task
|
||||||
|
* to report progress.
|
||||||
|
* @param callBack Callback that will be used by the background task to
|
||||||
|
* return results.
|
||||||
|
*/
|
||||||
|
default void runWithIngestStream(String password, Host host, IngestJobSettings settings, DataSourceProcessorProgressMonitor progress,
|
||||||
|
DataSourceProcessorCallback callBack) {
|
||||||
|
runWithIngestStream(host, settings, progress, callBack);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if this DSP supports ingest streams.
|
* Check if this DSP supports ingest streams.
|
||||||
*
|
*
|
||||||
|
@ -30,13 +30,20 @@ public class AutoIngestDataSource {
|
|||||||
|
|
||||||
private final String deviceId;
|
private final String deviceId;
|
||||||
private final Path path;
|
private final Path path;
|
||||||
|
private final String password;
|
||||||
private DataSourceProcessorResult resultCode;
|
private DataSourceProcessorResult resultCode;
|
||||||
private List<String> errorMessages;
|
private List<String> errorMessages;
|
||||||
private List<Content> content;
|
private List<Content> content;
|
||||||
|
|
||||||
public AutoIngestDataSource(String deviceId, Path path) {
|
|
||||||
|
public AutoIngestDataSource(String deviceId, Path path, String password) {
|
||||||
this.deviceId = deviceId;
|
this.deviceId = deviceId;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AutoIngestDataSource(String deviceId, Path path) {
|
||||||
|
this(deviceId, path, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDeviceId() {
|
public String getDeviceId() {
|
||||||
@ -47,6 +54,13 @@ public class AutoIngestDataSource {
|
|||||||
return this.path;
|
return this.path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The password to decrypt the data source.
|
||||||
|
*/
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized void setDataSourceProcessorOutput(DataSourceProcessorResult result, List<String> errorMessages, List<Content> content) {
|
public synchronized void setDataSourceProcessorOutput(DataSourceProcessorResult result, List<String> errorMessages, List<Content> content) {
|
||||||
this.resultCode = result;
|
this.resultCode = result;
|
||||||
this.errorMessages = new ArrayList<>(errorMessages);
|
this.errorMessages = new ArrayList<>(errorMessages);
|
||||||
|
@ -50,6 +50,25 @@ public interface AutoIngestDataSourceProcessor extends DataSourceProcessor {
|
|||||||
*/
|
*/
|
||||||
int canProcess(Path dataSourcePath) throws AutoIngestDataSourceProcessorException;
|
int canProcess(Path dataSourcePath) throws AutoIngestDataSourceProcessorException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the DataSourceProcessor is capable of processing the
|
||||||
|
* data source. Returns a confidence value. Method can throw an exception
|
||||||
|
* for a system level problem. The exception should not be thrown for an issue
|
||||||
|
* related to bad input data.
|
||||||
|
*
|
||||||
|
* @param dataSourcePath Path to the data source.
|
||||||
|
* @param password The password to decrypt the data source.
|
||||||
|
* @return Confidence value. Values between 0 and 100 are recommended. Zero
|
||||||
|
* or less means the data source is not supported by the
|
||||||
|
* DataSourceProcessor. Value of 100 indicates high certainty in
|
||||||
|
* being able to process the data source.
|
||||||
|
* @throws org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException
|
||||||
|
*/
|
||||||
|
default int canProcess(Path dataSourcePath, String password) throws AutoIngestDataSourceProcessorException {
|
||||||
|
return canProcess(dataSourcePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a data source to the case database using a background task in a
|
* Adds a data source to the case database using a background task in a
|
||||||
* separate thread by calling DataSourceProcessor.run() method. Returns as
|
* separate thread by calling DataSourceProcessor.run() method. Returns as
|
||||||
@ -91,6 +110,30 @@ public interface AutoIngestDataSourceProcessor extends DataSourceProcessor {
|
|||||||
process(deviceId, dataSourcePath, progressMonitor, callBack);
|
process(deviceId, dataSourcePath, progressMonitor, callBack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a data source to the case database using a background task in a
|
||||||
|
* separate thread by calling DataSourceProcessor.run() method. Returns as
|
||||||
|
* soon as the background task is started. The background task uses a
|
||||||
|
* callback object to signal task completion and return results. Method can
|
||||||
|
* throw an exception for a system level problem. The exception should not
|
||||||
|
* be thrown for an issue related to bad input data.
|
||||||
|
*
|
||||||
|
* @param deviceId An ASCII-printable identifier for the device
|
||||||
|
* associated with the data source that is intended
|
||||||
|
* to be unique across multiple cases (e.g., a UUID).
|
||||||
|
* @param dataSourcePath Path to the data source.
|
||||||
|
* @param password The password to decrypt the datasource.
|
||||||
|
* @param host Host for this data source.
|
||||||
|
* @param progressMonitor Progress monitor that will be used by the
|
||||||
|
* background task to report progress.
|
||||||
|
* @param callBack Callback that will be used by the background task
|
||||||
|
* to return results.
|
||||||
|
*/
|
||||||
|
default void process(String deviceId, Path dataSourcePath, String password, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
||||||
|
process(deviceId, dataSourcePath, progressMonitor, callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a data source to the case database using a background task in a
|
* Adds a data source to the case database using a background task in a
|
||||||
* separate thread by calling DataSourceProcessor.run() method. Returns as
|
* separate thread by calling DataSourceProcessor.run() method. Returns as
|
||||||
@ -140,6 +183,33 @@ public interface AutoIngestDataSourceProcessor extends DataSourceProcessor {
|
|||||||
return processWithIngestStream(deviceId, dataSourcePath, settings, progressMonitor, callBack);
|
return processWithIngestStream(deviceId, dataSourcePath, settings, progressMonitor, callBack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a data source to the case database using a background task in a
|
||||||
|
* separate thread by calling DataSourceProcessor.run() method. Returns as
|
||||||
|
* soon as the background task is started. The background task uses a
|
||||||
|
* callback object to signal task completion and return results. Method can
|
||||||
|
* throw an exception for a system level problem. The exception should not
|
||||||
|
* be thrown for an issue related to bad input data.
|
||||||
|
*
|
||||||
|
* @param deviceId An ASCII-printable identifier for the device
|
||||||
|
* associated with the data source that is intended
|
||||||
|
* to be unique across multiple cases (e.g., a UUID).
|
||||||
|
* @param dataSourcePath Path to the data source.
|
||||||
|
* @param password The password to decrypt the datasource.
|
||||||
|
* @param host The host for this data source.
|
||||||
|
* @param settings The ingest job settings.
|
||||||
|
* @param progressMonitor Progress monitor that will be used by the
|
||||||
|
* background task to report progress.
|
||||||
|
* @param callBack Callback that will be used by the background task
|
||||||
|
* to return results.
|
||||||
|
*
|
||||||
|
* @return The new ingest stream or null if an error occurred. Errors will be handled by the callback.
|
||||||
|
*/
|
||||||
|
default IngestStream processWithIngestStream(String deviceId, Path dataSourcePath, String password, Host host, IngestJobSettings settings, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
||||||
|
return processWithIngestStream(deviceId, dataSourcePath, settings, progressMonitor, callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A custom exception for the use of AutomatedIngestDataSourceProcessor.
|
* A custom exception for the use of AutomatedIngestDataSourceProcessor.
|
||||||
*/
|
*/
|
||||||
|
@ -49,9 +49,27 @@ public class DataSourceProcessorUtility {
|
|||||||
* org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException
|
* org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException
|
||||||
*/
|
*/
|
||||||
public static Map<AutoIngestDataSourceProcessor, Integer> getDataSourceProcessorForFile(Path dataSourcePath, Collection<? extends AutoIngestDataSourceProcessor> processorCandidates) throws AutoIngestDataSourceProcessorException {
|
public static Map<AutoIngestDataSourceProcessor, Integer> getDataSourceProcessorForFile(Path dataSourcePath, Collection<? extends AutoIngestDataSourceProcessor> processorCandidates) throws AutoIngestDataSourceProcessorException {
|
||||||
|
return getDataSourceProcessorForFile(dataSourcePath, null, processorCandidates);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility method to find all Data Source Processors (DSP) that are able
|
||||||
|
* to process the input data source. Only the DSPs that implement
|
||||||
|
* AutoIngestDataSourceProcessor interface are used.
|
||||||
|
*
|
||||||
|
* @param dataSourcePath Full path to the data source
|
||||||
|
* @param password The password to decrypt the data source.
|
||||||
|
* @param processorCandidates Possible DSPs that can handle the data source
|
||||||
|
*
|
||||||
|
* @return Hash map of all DSPs that can process the data source along with
|
||||||
|
* their confidence score
|
||||||
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException
|
||||||
|
*/
|
||||||
|
public static Map<AutoIngestDataSourceProcessor, Integer> getDataSourceProcessorForFile(Path dataSourcePath, String password, Collection<? extends AutoIngestDataSourceProcessor> processorCandidates) throws AutoIngestDataSourceProcessorException {
|
||||||
Map<AutoIngestDataSourceProcessor, Integer> validDataSourceProcessorsMap = new HashMap<>();
|
Map<AutoIngestDataSourceProcessor, Integer> validDataSourceProcessorsMap = new HashMap<>();
|
||||||
for (AutoIngestDataSourceProcessor processor : processorCandidates) {
|
for (AutoIngestDataSourceProcessor processor : processorCandidates) {
|
||||||
int confidence = processor.canProcess(dataSourcePath);
|
int confidence = processor.canProcess(dataSourcePath, password);
|
||||||
if (confidence > 0) {
|
if (confidence > 0) {
|
||||||
validDataSourceProcessorsMap.put(processor, confidence);
|
validDataSourceProcessorsMap.put(processor, confidence);
|
||||||
}
|
}
|
||||||
@ -76,9 +94,29 @@ public class DataSourceProcessorUtility {
|
|||||||
* org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException
|
* org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException
|
||||||
*/
|
*/
|
||||||
public static List<AutoIngestDataSourceProcessor> getOrderedListOfDataSourceProcessors(Path dataSourcePath) throws AutoIngestDataSourceProcessorException {
|
public static List<AutoIngestDataSourceProcessor> getOrderedListOfDataSourceProcessors(Path dataSourcePath) throws AutoIngestDataSourceProcessorException {
|
||||||
|
return getOrderedListOfDataSourceProcessors(dataSourcePath, (String) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility method to find all Data Source Processors (DSP) that are able
|
||||||
|
* to process the input data source. Only the DSPs that implement
|
||||||
|
* AutoIngestDataSourceProcessor interface are used. Returns ordered list of
|
||||||
|
* data source processors. DSPs are ordered in descending order from highest
|
||||||
|
* confidence to lowest.
|
||||||
|
*
|
||||||
|
* @param dataSourcePath Full path to the data source
|
||||||
|
* @param password The password to decrypt the data source.
|
||||||
|
*
|
||||||
|
* @return Ordered list of data source processors. DSPs are ordered in
|
||||||
|
* descending order from highest confidence to lowest.
|
||||||
|
*
|
||||||
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException
|
||||||
|
*/
|
||||||
|
public static List<AutoIngestDataSourceProcessor> getOrderedListOfDataSourceProcessors(Path dataSourcePath, String password) throws AutoIngestDataSourceProcessorException {
|
||||||
// lookup all AutomatedIngestDataSourceProcessors
|
// lookup all AutomatedIngestDataSourceProcessors
|
||||||
Collection<? extends AutoIngestDataSourceProcessor> processorCandidates = Lookup.getDefault().lookupAll(AutoIngestDataSourceProcessor.class);
|
Collection<? extends AutoIngestDataSourceProcessor> processorCandidates = Lookup.getDefault().lookupAll(AutoIngestDataSourceProcessor.class);
|
||||||
return getOrderedListOfDataSourceProcessors(dataSourcePath, processorCandidates);
|
return getOrderedListOfDataSourceProcessors(dataSourcePath, password, processorCandidates);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,6 +136,27 @@ public class DataSourceProcessorUtility {
|
|||||||
* org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException
|
* org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException
|
||||||
*/
|
*/
|
||||||
public static List<AutoIngestDataSourceProcessor> getOrderedListOfDataSourceProcessors(Path dataSourcePath, Collection<? extends AutoIngestDataSourceProcessor> processorCandidates) throws AutoIngestDataSourceProcessorException {
|
public static List<AutoIngestDataSourceProcessor> getOrderedListOfDataSourceProcessors(Path dataSourcePath, Collection<? extends AutoIngestDataSourceProcessor> processorCandidates) throws AutoIngestDataSourceProcessorException {
|
||||||
|
return getOrderedListOfDataSourceProcessors(dataSourcePath, null, processorCandidates);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility method to find all Data Source Processors (DSP) that are able
|
||||||
|
* to process the input data source. Only the DSPs that implement
|
||||||
|
* AutoIngestDataSourceProcessor interface are used. Returns ordered list of
|
||||||
|
* data source processors. DSPs are ordered in descending order from highest
|
||||||
|
* confidence to lowest.
|
||||||
|
*
|
||||||
|
* @param dataSourcePath Full path to the data source
|
||||||
|
* @param password The password to decrypt the data source.
|
||||||
|
* @param processorCandidates Collection of AutoIngestDataSourceProcessor objects to use
|
||||||
|
*
|
||||||
|
* @return Ordered list of data source processors. DSPs are ordered in
|
||||||
|
* descending order from highest confidence to lowest.
|
||||||
|
*
|
||||||
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor.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, processorCandidates);
|
||||||
return orderDataSourceProcessorsByConfidence(validDataSourceProcessorsMap);
|
return orderDataSourceProcessorsByConfidence(validDataSourceProcessorsMap);
|
||||||
}
|
}
|
||||||
|
@ -2573,7 +2573,8 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String deviceId = manifest.getDeviceId();
|
String deviceId = manifest.getDeviceId();
|
||||||
return new AutoIngestDataSource(deviceId, dataSourcePath);
|
String password = manifest.getPassword();
|
||||||
|
return new AutoIngestDataSource(deviceId, dataSourcePath, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2603,7 +2604,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
// Get an ordered list of data source processors to try
|
// Get an ordered list of data source processors to try
|
||||||
List<AutoIngestDataSourceProcessor> validDataSourceProcessors;
|
List<AutoIngestDataSourceProcessor> validDataSourceProcessors;
|
||||||
try {
|
try {
|
||||||
validDataSourceProcessors = DataSourceProcessorUtility.getOrderedListOfDataSourceProcessors(dataSource.getPath());
|
validDataSourceProcessors = DataSourceProcessorUtility.getOrderedListOfDataSourceProcessors(dataSource.getPath(), dataSource.getPassword());
|
||||||
} catch (AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException ex) {
|
} catch (AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException ex) {
|
||||||
sysLogger.log(Level.SEVERE, "Exception while determining best data source processor for {0}", dataSource.getPath());
|
sysLogger.log(Level.SEVERE, "Exception while determining best data source processor for {0}", dataSource.getPath());
|
||||||
// rethrow the exception. It will get caught & handled upstream and will result in AIM auto-pause.
|
// rethrow the exception. It will get caught & handled upstream and will result in AIM auto-pause.
|
||||||
@ -2641,7 +2642,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
jobLogger.logIngestJobSettingsErrors();
|
jobLogger.logIngestJobSettingsErrors();
|
||||||
throw new AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException("Error(s) in ingest job settings for " + manifestPath);
|
throw new AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException("Error(s) in ingest job settings for " + manifestPath);
|
||||||
}
|
}
|
||||||
currentIngestStream = selectedProcessor.processWithIngestStream(dataSource.getDeviceId(), dataSource.getPath(), ingestJobSettings, progressMonitor, callBack);
|
currentIngestStream = selectedProcessor.processWithIngestStream(dataSource.getDeviceId(), dataSource.getPath(), dataSource.getPassword(), null, ingestJobSettings, progressMonitor, callBack);
|
||||||
if (currentIngestStream == null) {
|
if (currentIngestStream == null) {
|
||||||
// Either there was a failure to add the data source object to the database or the ingest settings were bad.
|
// Either there was a failure to add the data source object to the database or the ingest settings were bad.
|
||||||
// An error in the ingest settings is the more likely scenario.
|
// An error in the ingest settings is the more likely scenario.
|
||||||
@ -2651,7 +2652,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
throw new AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException("Error initializing processing for " + manifestPath + ", probably due to an ingest settings error");
|
throw new AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException("Error initializing processing for " + manifestPath + ", probably due to an ingest settings error");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
selectedProcessor.process(dataSource.getDeviceId(), dataSource.getPath(), progressMonitor, callBack);
|
selectedProcessor.process(dataSource.getDeviceId(), dataSource.getPath(), dataSource.getPassword(), null, progressMonitor, callBack);
|
||||||
}
|
}
|
||||||
ingestLock.wait();
|
ingestLock.wait();
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ public final class AutopsyManifestFileParser implements ManifestFileParser {
|
|||||||
private static final String MANIFEST_FILE_NAME_SIGNATURE = "_MANIFEST.XML";
|
private static final String MANIFEST_FILE_NAME_SIGNATURE = "_MANIFEST.XML";
|
||||||
private static final String ROOT_ELEM_TAG_NAME = "AutopsyManifest";
|
private static final String ROOT_ELEM_TAG_NAME = "AutopsyManifest";
|
||||||
private static final String CASE_NAME_XPATH = "/AutopsyManifest/CaseName/text()";
|
private static final String CASE_NAME_XPATH = "/AutopsyManifest/CaseName/text()";
|
||||||
|
private static final String PASSWORD_XPATH = "/AutopsyManifest/Password/text()";
|
||||||
private static final String DEVICE_ID_XPATH = "/AutopsyManifest/DeviceId/text()";
|
private static final String DEVICE_ID_XPATH = "/AutopsyManifest/DeviceId/text()";
|
||||||
private static final String DATA_SOURCE_NAME_XPATH = "/AutopsyManifest/DataSource/text()";
|
private static final String DATA_SOURCE_NAME_XPATH = "/AutopsyManifest/DataSource/text()";
|
||||||
private static final Logger logger = Logger.getLogger(AutopsyManifestFileParser.class.getName());
|
private static final Logger logger = Logger.getLogger(AutopsyManifestFileParser.class.getName());
|
||||||
@ -102,7 +103,10 @@ public final class AutopsyManifestFileParser implements ManifestFileParser {
|
|||||||
}
|
}
|
||||||
Path dataSourcePath = filePath.getParent().resolve(dataSourceName);
|
Path dataSourcePath = filePath.getParent().resolve(dataSourceName);
|
||||||
|
|
||||||
return new Manifest(filePath, dateFileCreated, caseName, deviceId, dataSourcePath, new HashMap<>());
|
expr = xpath.compile(PASSWORD_XPATH);
|
||||||
|
String password = (String) expr.evaluate(doc, XPathConstants.STRING);
|
||||||
|
|
||||||
|
return new Manifest(filePath, dateFileCreated, caseName, deviceId, dataSourcePath, password, new HashMap<>());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new ManifestFileParserException(String.format("Error parsing manifest %s", filePath), ex);
|
throw new ManifestFileParserException(String.format("Error parsing manifest %s", filePath), ex);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -42,9 +42,14 @@ public final class Manifest implements Serializable {
|
|||||||
private final String caseName;
|
private final String caseName;
|
||||||
private final String deviceId;
|
private final String deviceId;
|
||||||
private final String dataSourceFileName;
|
private final String dataSourceFileName;
|
||||||
|
private final String password;
|
||||||
private final Map<String, String> manifestProperties;
|
private final Map<String, String> manifestProperties;
|
||||||
|
|
||||||
public Manifest(Path manifestFilePath, Date dateFileCreated, String caseName, String deviceId, Path dataSourcePath, Map<String, String> manifestProperties) {
|
public Manifest(Path manifestFilePath, Date dateFileCreated, String caseName, String deviceId, Path dataSourcePath, Map<String, String> manifestProperties) {
|
||||||
|
this(manifestFilePath, dateFileCreated, caseName, deviceId, dataSourcePath, null, manifestProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Manifest(Path manifestFilePath, Date dateFileCreated, String caseName, String deviceId, Path dataSourcePath, String password, Map<String, String> manifestProperties) {
|
||||||
this.filePathString = manifestFilePath.toString();
|
this.filePathString = manifestFilePath.toString();
|
||||||
this.filePath = Paths.get(filePathString);
|
this.filePath = Paths.get(filePathString);
|
||||||
|
|
||||||
@ -60,6 +65,7 @@ public final class Manifest implements Serializable {
|
|||||||
this.dataSourcePath = Paths.get("");
|
this.dataSourcePath = Paths.get("");
|
||||||
dataSourceFileName = "";
|
dataSourceFileName = "";
|
||||||
}
|
}
|
||||||
|
this.password = password;
|
||||||
this.manifestProperties = new HashMap<>(manifestProperties);
|
this.manifestProperties = new HashMap<>(manifestProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +97,13 @@ public final class Manifest implements Serializable {
|
|||||||
return dataSourcePath;
|
return dataSourcePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The password to decrypt the data source (may be null).
|
||||||
|
*/
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
public String getDataSourceFileName() {
|
public String getDataSourceFileName() {
|
||||||
return dataSourceFileName;
|
return dataSourceFileName;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user