allow adding directories as Logical File Set

This commit is contained in:
Joe Ho 2019-08-13 10:14:59 -04:00
parent c74d1373d3
commit fe0e1b4cf1
5 changed files with 74 additions and 37 deletions

View File

@ -22,12 +22,12 @@ import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.LocalFilesDataSource;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskDataException;
@ -37,7 +37,7 @@ import org.sleuthkit.datamodel.TskDataException;
* case database, grouped under a virtual directory that serves as the data
* source.
*/
class AddLocalFilesTask implements Runnable {
public class AddLocalFilesTask implements Runnable {
private static final Logger LOGGER = Logger.getLogger(AddLocalFilesTask.class.getName());
private final String deviceId;
@ -68,7 +68,7 @@ class AddLocalFilesTask implements Runnable {
* during processing.
* @param callback Callback to call when processing is done.
*/
AddLocalFilesTask(String deviceId, String rootVirtualDirectoryName, List<String> localFilePaths, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
public AddLocalFilesTask(String deviceId, String rootVirtualDirectoryName, List<String> localFilePaths, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
this.deviceId = deviceId;
this.rootVirtualDirectoryName = rootVirtualDirectoryName;
this.localFilePaths = localFilePaths;
@ -88,7 +88,7 @@ class AddLocalFilesTask implements Runnable {
try {
progress.setIndeterminate(true);
FileManager fileManager = Case.getCurrentCaseThrows().getServices().getFileManager();
LocalFilesDataSource newDataSource = fileManager.addLocalFilesDataSource(deviceId, rootVirtualDirectoryName, "", localFilePaths, new ProgressUpdater());
LocalFilesDataSource newDataSource = fileManager.addLocalFilesDataSource(deviceId, "", "", localFilePaths, new ProgressUpdater());
newDataSources.add(newDataSource);
} catch (TskDataException | TskCoreException | NoCurrentCaseException ex) {
errors.add(ex.getMessage());

View File

@ -19,13 +19,11 @@
package org.sleuthkit.autopsy.logicalimager.dsp;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.apache.commons.io.FileUtils;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
@ -80,20 +78,7 @@ final class AddLogicalImageTask extends AddMultipleImageTask {
List<String> errorList = new ArrayList<>();
List<Content> emptyDataSources = new ArrayList<>();
try {
progressMonitor.setProgressText(Bundle.AddLogicalImageTask_copyingImageFromTo(src.toString(), dest.toString()));
FileUtils.copyDirectory(src, dest);
progressMonitor.setProgressText(Bundle.AddLogicalImageTask_doneCopying());
} catch (IOException ex) {
// Copy directory failed
String msg = Bundle.AddLogicalImageTask_failedToCopyDirectory(src.toString(), dest.toString());
errorList.add(msg);
logger.log(Level.SEVERE, String.format("Failed to copy directory %s to %s", src.toString(), dest.toString()), ex);
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
return;
}
// Add the alert.txt and users.txt to the case report
// Add the alert.txt and users.txt to the case report
progressMonitor.setProgressText(Bundle.AddLogicalImageTask_addingToReport(ALERT_TXT));
String status = addReport(Paths.get(dest.toString(), ALERT_TXT), ALERT_TXT + " " + src.getName());
if (status != null) {

View File

@ -39,6 +39,8 @@ AddMultipleImageTask.nonCriticalErrorAdding=Non-critical error adding {0} for de
LogicalImagerDSProcessor.dataSourceType=Autopsy Logical Imager Results
# {0} - directory
LogicalImagerDSProcessor.directoryAlreadyExists=Directory {0} already exists
# {0} - sparseImageDirectory
LogicalImagerDSProcessor.directoryDoesNotContainSparseImage=Directory {0} does not contain any images
# {0} - directory
LogicalImagerDSProcessor.failToCreateDirectory=Failed to create directory {0}
# {0} - file

View File

@ -19,6 +19,7 @@
package org.sleuthkit.autopsy.logicalimager.dsp;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
@ -27,9 +28,11 @@ import java.util.Calendar;
import java.util.List;
import java.util.UUID;
import javax.swing.JPanel;
import org.apache.commons.io.FileUtils;
import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.ServiceProvider;
import org.openide.util.lookup.ServiceProviders;
import org.sleuthkit.autopsy.casemodule.AddLocalFilesTask;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
@ -131,7 +134,10 @@ public final class LogicalImagerDSProcessor implements DataSourceProcessor {
"# {0} - directory", "LogicalImagerDSProcessor.failToCreateDirectory=Failed to create directory {0}",
"# {0} - directory", "LogicalImagerDSProcessor.directoryAlreadyExists=Directory {0} already exists",
"# {0} - file", "LogicalImagerDSProcessor.failToGetCanonicalPath=Fail to get canonical path for {0}",
"LogicalImagerDSProcessor.noCurrentCase=No current case",})
"LogicalImagerDSProcessor.noCurrentCase=No current case",
"# {0} - sparseImageDirectory", "LogicalImagerDSProcessor.directoryDoesNotContainSparseImage=Directory {0} does not contain any images",
})
@Override
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
configPanel.storeSettings();
@ -170,9 +176,21 @@ public final class LogicalImagerDSProcessor implements DataSourceProcessor {
}
File src = imageDirPath.toFile();
try {
progressMonitor.setProgressText(Bundle.AddLogicalImageTask_copyingImageFromTo(src.toString(), dest.toString()));
FileUtils.copyDirectory(src, dest);
progressMonitor.setProgressText(Bundle.AddLogicalImageTask_doneCopying());
} catch (IOException ex) {
// Copy directory failed
String msg = Bundle.AddLogicalImageTask_failedToCopyDirectory(src.toString(), dest.toString());
errorList.add(msg);
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
return;
}
// Get all VHD files in the src directory
List<String> imagePaths = new ArrayList<>();
for (File f : src.listFiles()) {
for (File f : dest.listFiles()) {
if (f.getName().endsWith(".vhd")) {
try {
imagePaths.add(f.getCanonicalPath());
@ -184,17 +202,39 @@ public final class LogicalImagerDSProcessor implements DataSourceProcessor {
}
}
}
try {
String deviceId = UUID.randomUUID().toString();
String timeZone = Calendar.getInstance().getTimeZone().getID();
run(deviceId, imagePaths,
timeZone, src, dest,
progressMonitor, callback);
} catch (NoCurrentCaseException ex) {
String msg = Bundle.LogicalImagerDSProcessor_noCurrentCase();
errorList.add(msg);
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
return;
String deviceId = UUID.randomUUID().toString();
if (imagePaths.isEmpty()) {
// No VHD in src directory, try ingest directories using Logical File Set
String[] directories = dest.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return Paths.get(dir.toString(), name).toFile().isDirectory();
}
});
for (String dir : directories) {
imagePaths.add(Paths.get(dest.toString(), dir).toFile().getAbsolutePath());
}
if (imagePaths.isEmpty()) {
String msg = Bundle.LogicalImagerDSProcessor_directoryDoesNotContainSparseImage(dest);
errorList.add(msg);
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
return;
}
// ingest the directories
new Thread(new AddLocalFilesTask(deviceId, null, imagePaths, progressMonitor, callback)).start();
} else {
try {
String timeZone = Calendar.getInstance().getTimeZone().getID();
run(deviceId, imagePaths,
timeZone, src, dest,
progressMonitor, callback);
} catch (NoCurrentCaseException ex) {
String msg = Bundle.LogicalImagerDSProcessor_noCurrentCase();
errorList.add(msg);
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
}
}
}

View File

@ -333,9 +333,19 @@ final class LogicalImagerPanel extends JPanel implements DocumentListener {
}
});
if (vhdFiles.length == 0) {
setErrorMessage(Bundle.LogicalImagerPanel_messageLabel_directoryDoesNotContainSparseImage(path));
firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), true, false);
return;
// No VHD files, try directories for individual files
String[] directories = dir.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return Paths.get(dir.toString(), name).toFile().isDirectory();
}
});
if (directories.length == 0) {
// No directories, bail
setErrorMessage(Bundle.LogicalImagerPanel_messageLabel_directoryDoesNotContainSparseImage(path));
firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), true, false);
return;
}
}
manualImageDirPath = Paths.get(path);
setNormalMessage(path);