This commit is contained in:
U-BASIS\dgrove 2018-02-23 12:20:57 -05:00
commit f180ff75b1
20 changed files with 1373 additions and 412 deletions

View File

@ -30,7 +30,10 @@
<copy todir="${basedir}/release/photorec_exec" >
<fileset dir="${thirdparty.dir}/photorec_exec"/>
</copy>
<!--Copy ewfexport to release-->
<copy todir="${basedir}/release/ewfexport_exec" >
<fileset dir="${thirdparty.dir}/ewfexport_exec"/>
</copy>
<!--Copy other jars-->
<copy file="${thirdparty.dir}/rejistry/Rejistry-1.0-SNAPSHOT.jar" todir="${ext.dir}" />
<copy file="${thirdparty.dir}/sevenzip/sevenzipjbinding.jar" todir="${ext.dir}" />

View File

@ -32,16 +32,6 @@ MissingImageDialog.selectButton.text=Select Image
MissingImageDialog.titleLabel.text=Search for missing image
MissingImageDialog.cancelButton.text=Cancel
LocalDiskPanel.errorLabel.text=Error Label
LocalFilesPanel.infoLabel.text=Add local files and folders:
LocalFilesPanel.selectButton.text=Add
LocalFilesPanel.localFileChooser.dialogTitle=Select Local Files or Folders
LocalFilesPanel.selectButton.toolTipText=Add local files and folders as logical files
LocalFilesPanel.clearButton.text=Clear
LocalFilesPanel.clearButton.toolTipText=Clears currently selected local file paths
LocalFilesPanel.selectedPaths.toolTipText=
LocalFilesPanel.localFileChooser.approveButtonText=Select
LocalFilesPanel.localFileChooser.approveButtonToolTipText=
LocalFilesPanel.selectButton.actionCommand=Add
AddImageWizardAddingProgressVisual.statusLabel.text=Data source has been added to the local database. Files are being analyzed.
AddImageWizardAddingProgressVisual.progressLabel.text=<progress>
AddImageWizardAddingProgressVisual.viewLogButton.text=View Log
@ -173,7 +163,6 @@ UpdateRecentCases.menuItem.clearRecentCases.text=Clear Recent Cases
UpdateRecentCases.menuItem.empty=-Empty-
AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel
NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on \"C:\" drive
LocalFilesPanel.errorLabel.text=Error Label
CollaborationMonitor.addingDataSourceStatus.msg={0} adding data source
CollaborationMonitor.analyzingDataSourceStatus.msg={0} analyzing {1}
MissingImageDialog.lbWarning.text=
@ -191,8 +180,6 @@ CloseCaseWhileIngesting.Warning=Ingest is running. Are you sure you want to clos
CloseCaseWhileIngesting.Warning.title=Warning\: This will close the current case
CasePropertiesForm.imagesTable.columnModel.title1=Remove
CasePropertiesForm.imagesTable.columnModel.title0=Path
LocalFilesPanel.jButton1.text=Change
LocalFilesPanel.displayNameLabel.text=Logical File Set Display Name: Default
IngestJobInfoPanel.jLabel1.text=Ingest Modules
IngestJobInfoPanel.jLabel2.text=Ingest Jobs
CaseInformationPanel.closeButton.text=Close
@ -234,3 +221,23 @@ ImageFilePanel.pathErrorLabel.text=Error Label
ImageFilePanel.sectorSizeLabel.text=Sector size:
LocalDiskPanel.sectorSizeLabel.text=Sector Size:
LocalDiskPanel.refreshTableButton.text=Refresh Local Disks
LocalFilesPanel.displayNameLabel.text=Logical File Set Display Name: Default
LocalFilesPanel.errorLabel.text=Error Label
LocalFilesPanel.selectedPaths.toolTipText=
LocalFilesPanel.clearButton.toolTipText=Clears currently selected local file paths
LocalFilesPanel.clearButton.text=Clear
LocalFilesPanel.selectButton.actionCommand=Add
LocalFilesPanel.selectButton.toolTipText=Add local files and folders as logical files
LocalFilesPanel.selectButton.text=Add
LocalFilesPanel.localFileChooser.dialogTitle=Select Local Files or Folders
LocalFilesPanel.localFileChooser.approveButtonToolTipText=
LocalFilesPanel.localFileChooser.approveButtonText=Select
LogicalEvidenceFilePanel.selectButton.actionCommand=Add
LogicalEvidenceFilePanel.selectButton.toolTipText=Add local files and folders as logical files
LogicalEvidenceFilePanel.selectButton.text=Select
LogicalEvidenceFilePanel.errorLabel.text=Error Label
LogicalEvidenceFilePanel.logicalEvidenceFileChooser.dialogTitle=Select Local Files or Folders
LogicalEvidenceFilePanel.logicalEvidenceFileChooser.approveButtonToolTipText=
LogicalEvidenceFilePanel.logicalEvidenceFileChooser.approveButtonText=Select
LogicalEvidenceFilePanel.logicalEvidencePathField.text=
LocalFilesPanel.changeNameButton.text=Change

View File

@ -27,14 +27,6 @@ MissingImageDialog.selectButton.text=\u30a4\u30e1\u30fc\u30b8\u3092\u9078\u629e
MissingImageDialog.titleLabel.text=\u6b20\u843d\u3057\u305f\u30a4\u30e1\u30fc\u30b8\u306e\u691c\u7d22
MissingImageDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
LocalDiskPanel.errorLabel.text=\u30a8\u30e9\u30fc\u30e9\u30d9\u30eb
LocalFilesPanel.infoLabel.text=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u304a\u3088\u3073\u30d5\u30a9\u30eb\u30c0\u3092\u8ffd\u52a0\uff1a
LocalFilesPanel.selectButton.text=\u8ffd\u52a0
LocalFilesPanel.localFileChooser.dialogTitle=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u307e\u305f\u306f\u30d5\u30a9\u30eb\u30c0\u3092\u9078\u629e
LocalFilesPanel.selectButton.toolTipText=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u304a\u3088\u3073\u30d5\u30a9\u30eb\u30c0\u3092\u30ed\u30b8\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u3068\u3057\u3066\u8ffd\u52a0\u3057\u307e\u3059
LocalFilesPanel.clearButton.text=\u30af\u30ea\u30a2
LocalFilesPanel.clearButton.toolTipText=\u73fe\u5728\u9078\u629e\u3055\u308c\u3066\u3044\u308b\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u304c\u30af\u30ea\u30a2\u3055\u308c\u307e\u3059
LocalFilesPanel.localFileChooser.approveButtonText=\u9078\u629e
LocalFilesPanel.selectButton.actionCommand=\u8ffd\u52a0
AddImageWizardAddingProgressVisual.statusLabel.text=\u30ed\u30fc\u30ab\u30eb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u304c\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\u3002\u30d5\u30a1\u30a4\u30eb\u3092\u89e3\u6790\u4e2d\u3067\u3059\u3002
AddImageWizardAddingProgressVisual.progressLabel.text=\uff1c\u30d7\u30ed\u30b0\u30ec\u30b9\uff1e
AddImageWizardAddingProgressVisual.viewLogButton.text=\u30ed\u30b0\u3092\u8868\u793a
@ -143,6 +135,7 @@ ImageFilePanel.noFatOrphansCheckbox.text=FAT\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9
LocalDiskPanel.noFatOrphansCheckbox.text=FAT\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u306e\u30aa\u30fc\u30d5\u30a1\u30f3\u30d5\u30a1\u30a4\u30eb\u306f\u7121\u8996
AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=\u30ad\u30e3\u30f3\u30bb\u30eb
LocalFilesPanel.errorLabel.text=\u30a8\u30e9\u30fc\u30e9\u30d9\u30eb
ImageFilePanel.errorLabel.text=\u30a8\u30e9\u30fc\u30e9\u30d9\u30eb
NewCaseVisualPanel1.caseTypeLabel.text=\u30b1\u30fc\u30b9\u30bf\u30a4\u30d7\uff1a
Case.databaseConnectionInfo.error.msg=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b5\u30fc\u30d0\u30fc\u306e\u63a5\u7d9a\u60c5\u5831\u3092\u5165\u624b\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u30c4\u30fc\u30eb\u3001\u30aa\u30d7\u30b7\u30e7\u30f3\u3001\u8907\u6570\u30e6\u30fc\u30b6\u30fc\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002
Case.open.exception.multiUserCaseNotEnabled=\u8907\u6570\u30e6\u30fc\u30b6\u30fc\u306e\u30b1\u30fc\u30b9\u304c\u6709\u52b9\u5316\u3055\u308c\u3066\u3044\u306a\u3044\u3068\u3001\u8907\u6570\u30e6\u30fc\u30b6\u30fc\u306e\u30b1\u30fc\u30b9\u306f\u958b\u3051\u307e\u305b\u3093\u3002\u30c4\u30fc\u30eb\u3001\u30aa\u30d7\u30b7\u30e7\u30f3\u3001\u8907\u6570\u30e6\u30fc\u30b6\u30fc\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002
@ -198,3 +191,17 @@ CueBannerPanel.newCaseLabel.text=\u65b0\u898f\u30b1\u30fc\u30b9\u3092\u4f5c\u621
CueBannerPanel.openCaseLabel.text=\u65e2\u5b58\u30b1\u30fc\u30b9\u3092\u958b\u304f
ImageFilePanel.pathErrorLabel.text=\u30a8\u30e9\u30fc\u30e9\u30d9\u30eb
ImageFilePanel.sectorSizeLabel.text=\u30a4\u30f3\u30d7\u30c3\u30c8\u30bf\u30a4\u30e0\u30be\u30fc\u30f3\u3092\u9078\u629e\u3057\u3066\u4e0b\u3055\u3044\uff1a
LocalFilesPanel.errorLabel.text=\u30a8\u30e9\u30fc\u30e9\u30d9\u30eb
LocalFilesPanel.clearButton.toolTipText=\u73fe\u5728\u9078\u629e\u3055\u308c\u3066\u3044\u308b\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u304c\u30af\u30ea\u30a2\u3055\u308c\u307e\u3059
LocalFilesPanel.clearButton.text=\u30af\u30ea\u30a2
LocalFilesPanel.selectButton.actionCommand=\u8ffd\u52a0
LocalFilesPanel.selectButton.toolTipText=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u304a\u3088\u3073\u30d5\u30a9\u30eb\u30c0\u3092\u30ed\u30b8\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u3068\u3057\u3066\u8ffd\u52a0\u3057\u307e\u3059
LocalFilesPanel.selectButton.text=\u8ffd\u52a0
LocalFilesPanel.localFileChooser.dialogTitle=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u307e\u305f\u306f\u30d5\u30a9\u30eb\u30c0\u3092\u9078\u629e
LocalFilesPanel.localFileChooser.approveButtonText=\u9078\u629e
LogicalEvidenceFilePanel.selectButton.actionCommand=\u8ffd\u52a0
LogicalEvidenceFilePanel.selectButton.toolTipText=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u304a\u3088\u3073\u30d5\u30a9\u30eb\u30c0\u3092\u30ed\u30b8\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u3068\u3057\u3066\u8ffd\u52a0\u3057\u307e\u3059
LogicalEvidenceFilePanel.selectButton.text=\u8ffd\u52a0
LogicalEvidenceFilePanel.errorLabel.text=\u30a8\u30e9\u30fc\u30e9\u30d9\u30eb
LogicalEvidenceFilePanel.logicalEvidenceFileChooser.dialogTitle=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u307e\u305f\u306f\u30d5\u30a9\u30eb\u30c0\u3092\u9078\u629e
LogicalEvidenceFilePanel.logicalEvidenceFileChooser.approveButtonText=\u9078\u629e

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -18,33 +18,60 @@
*/
package org.sleuthkit.autopsy.casemodule;
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.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import javax.swing.JPanel;
import javax.swing.filechooser.FileFilter;
import org.apache.commons.io.FilenameUtils;
import org.openide.modules.InstalledFileLocator;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.ServiceProvider;
import org.openide.util.lookup.ServiceProviders;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
import org.sleuthkit.autopsy.coreutils.ExecUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor;
/**
* A local/logical files and/or directories data source processor that
* implements the DataSourceProcessor service provider interface to allow
* integration with the add data source wizard. It also provides a run method
* overload to allow it to be used independently of the wizard.
* A local/logical files/logical evidence file(.lo1)/or directories data source
* processor that implements the DataSourceProcessor service provider interface
* to allow integration with the add data source wizard. It also provides a run
* method overload to allow it to be used independently of the wizard.
*/
@ServiceProviders(value = {
@ServiceProvider(service=DataSourceProcessor.class),
@ServiceProvider(service = DataSourceProcessor.class)
,
@ServiceProvider(service = AutoIngestDataSourceProcessor.class)}
)
@Messages({
"LocalFilesDSProcessor.logicalEvidenceFilter.desc=Logical Evidence Files (L01)"
})
public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDataSourceProcessor {
private static final String DATA_SOURCE_TYPE = NbBundle.getMessage(LocalFilesDSProcessor.class, "LocalFilesDSProcessor.dsType");
private final LocalFilesPanel configPanel;
private static final Logger logger = Logger.getLogger(LocalFilesDSProcessor.class.getName());
private final LogicalFilesDspPanel configPanel;
private static final String L01_EXTRACTION_DIR = "L01";
private static final String UNIQUENESS_CONSTRAINT_SEPERATOR = "_";
private static final String EWFEXPORT_DIR = "ewfexport_exec"; // NON-NLS
private static final String EWFEXPORT_32_BIT_DIR = "32-bit"; // NON-NLS
private static final String EWFEXPORT_64_BIT_DIR = "64-bit"; // NON-NLS
private static final String EWFEXPORT_WINDOWS_EXE = "ewfexport.exe"; // NON-NLS
private static final String LOG_FILE_EXTENSION = ".txt";
private static final List<String> LOGICAL_EVIDENCE_EXTENSIONS = Arrays.asList(".l01");
private static final String LOGICAL_EVIDENCE_DESC = Bundle.LocalFilesDSProcessor_logicalEvidenceFilter_desc();
private static final GeneralFilter LOGICAL_EVIDENCE_FILTER = new GeneralFilter(LOGICAL_EVIDENCE_EXTENSIONS, LOGICAL_EVIDENCE_DESC);
/*
* TODO: Remove the setDataSourceOptionsCalled flag and the settings fields
* when the deprecated method setDataSourceOptions is removed.
@ -59,7 +86,7 @@ public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDat
* method overload to allow it to be used independently of the wizard.
*/
public LocalFilesDSProcessor() {
configPanel = LocalFilesPanel.getDefault();
configPanel = LogicalFilesDspPanel.getDefault();
}
/**
@ -129,10 +156,133 @@ public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDat
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
if (!setDataSourceOptionsCalled) {
localFilePaths = configPanel.getContentPaths();
if (configPanel.subTypeIsLogicalEvidencePanel()) {
try {
//if the L01 option was chosen
localFilePaths = extractLogicalEvidenceFileContents(localFilePaths);
} catch (L01Exception ex) {
//contents of l01 could not be extracted don't add data source or run ingest
final List<String> errors = new ArrayList<>();
errors.add(ex.getMessage());
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
return;
}
}
}
run(UUID.randomUUID().toString(), configPanel.getFileSetName(), localFilePaths, progressMonitor, callback);
}
/**
* Extract the contents of the logical evidence files and return the paths
* to those extracted files.
*
* @param logicalEvidenceFilePaths
*
* @return extractedPaths - the paths to all the files extracted from the
* logical evidence files
*
* @throws
* org.sleuthkit.autopsy.casemodule.LocalFilesDSProcessor.L01Exception
*/
private List<String> extractLogicalEvidenceFileContents(final List<String> logicalEvidenceFilePaths) throws L01Exception {
final List<String> extractedPaths = new ArrayList<>();
Path ewfexportPath;
ewfexportPath = locateEwfexportExecutable();
List<String> command = new ArrayList<>();
for (final String l01Path : logicalEvidenceFilePaths) {
command.clear();
command.add(ewfexportPath.toAbsolutePath().toString());
command.add("-f");
command.add("files");
command.add("-t");
File l01Dir = new File(Case.getCurrentCase().getModuleDirectory(), L01_EXTRACTION_DIR); //WJS-TODO change to getOpenCase() when that method exists
if (!l01Dir.exists()) {
l01Dir.mkdirs();
}
Path dirPath = Paths.get(FilenameUtils.getBaseName(l01Path) + UNIQUENESS_CONSTRAINT_SEPERATOR + System.currentTimeMillis());
command.add(dirPath.toString());
command.add(l01Path);
ProcessBuilder processBuilder = new ProcessBuilder(command);
processBuilder.directory(l01Dir);
try {
//redirect ewfexport stdout and stderr to txt file
Path logFileName = Paths.get(l01Dir.toString(), dirPath.toString() + LOG_FILE_EXTENSION);
File logFile = new File(logFileName.toString());
Path errFileName = Paths.get(l01Dir.toString(), dirPath.toString() + LOG_FILE_EXTENSION);
File errFile = new File(errFileName.toString());
processBuilder.redirectError(ProcessBuilder.Redirect.appendTo(errFile));
processBuilder.redirectOutput(ProcessBuilder.Redirect.appendTo(logFile));
// open the file with ewfexport to extract its contents
ExecUtil.execute(processBuilder, new ExecUtil.TimedProcessTerminator());
if (l01Dir.toPath().resolve(dirPath).toFile().exists()) {
extractedPaths.add(l01Dir.toPath().resolve(dirPath).toString());
} else { //if we failed to extract anything let the user know the L01 file was unable to be processed
throw new L01Exception("Can not process the selected L01 file, ewfExport was unable to extract any files from it.");
}
} catch (SecurityException ex) {
throw new L01Exception("Security exception occcured while trying to extract l01 contents", ex);
} catch (IOException ex) {
throw new L01Exception("IOException occcured while trying to extract l01 contents", ex);
}
}
return extractedPaths;
}
/**
* Get a file filter for logical evidence files.
*
* @return LOGICAL_EVIDENCE_FILTER
*/
static FileFilter getLogicalEvidenceFilter() {
return LOGICAL_EVIDENCE_FILTER;
}
/**
* Gets the path for the ewfexport executable.
*
* @return the path to ewfexport.exe
*
* @throws
* org.sleuthkit.autopsy.casemodule.LocalFilesDSProcessor.L01Exception
*/
private Path locateEwfexportExecutable() throws L01Exception {
// Must be running under a Windows operating system.
if (!PlatformUtil.isWindowsOS()) {
throw new L01Exception("L01 files are only supported on windows currently");
}
// Build the expected path to either the 32-bit or 64-bit version of the
// ewfexport executable.
final File ewfRoot = InstalledFileLocator.getDefault().locate(EWFEXPORT_DIR, LocalFilesDSProcessor.class.getPackage().getName(), false);
Path executablePath;
if (PlatformUtil.is64BitOS()) {
executablePath = Paths.get(
ewfRoot.getAbsolutePath(),
EWFEXPORT_64_BIT_DIR,
EWFEXPORT_WINDOWS_EXE);
} else {
executablePath = Paths.get(
ewfRoot.getAbsolutePath(),
EWFEXPORT_32_BIT_DIR,
EWFEXPORT_WINDOWS_EXE);
}
// Make sure the executable exists at the expected location and that it
// can be run.
final File ewfexport = executablePath.toFile();
if (null == ewfexport || !ewfexport.exists()) {
throw new LocalFilesDSProcessor.L01Exception("EWF export executable was not found");
}
if (!ewfexport.canExecute()) {
throw new LocalFilesDSProcessor.L01Exception("EWF export executable can not be executed");
}
return executablePath;
}
/**
* 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
@ -180,7 +330,7 @@ public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDat
*/
@Override
public void reset() {
configPanel.reset();
configPanel.select();
localFilePaths = null;
setDataSourceOptionsCalled = false;
}
@ -190,12 +340,29 @@ public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDat
// Local files DSP can process any file by simply adding it as a logical file.
// It should return lowest possible non-zero confidence level and be treated
// as the "option of last resort" for auto ingest purposes
this.localFilePaths = Arrays.asList(new String[]{dataSourcePath.toString()});
//If there is only 1 file check if it is an L01 file and if it is extract the
//contents and replace the paths, if the contents can't be extracted return 0
if (localFilePaths.size() == 1) {
for (final String path : localFilePaths) {
if (LOGICAL_EVIDENCE_FILTER.accept(new File(path))) {
try {
//if the L01 option was chosen
localFilePaths = extractLogicalEvidenceFileContents(localFilePaths);
} catch (L01Exception ex) {
logger.log(Level.WARNING, "File extension was .l01 but contents of logical evidence file were unable to be extracted", ex);
//contents of l01 could not be extracted don't add data source or run ingest
return 0;
}
}
}
}
return 1;
}
@Override
public void process(String deviceId, Path dataSourcePath, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) throws AutoIngestDataSourceProcessorException {
this.localFilePaths = Arrays.asList(new String[]{dataSourcePath.toString()});
run(deviceId, deviceId, this.localFilePaths, progressMonitor, callBack);
}
@ -220,4 +387,20 @@ public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDat
setDataSourceOptionsCalled = true;
}
/**
* A custom exception for the L01 processing.
*/
private final class L01Exception extends Exception {
private static final long serialVersionUID = 1L;
L01Exception(final String message) {
super(message);
}
L01Exception(final String message, final Throwable cause) {
super(message, cause);
}
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<NonVisualComponents>
<Component class="javax.swing.JFileChooser" name="localFileChooser">
<Properties>
@ -16,21 +16,6 @@
<Property name="fileSelectionMode" type="int" value="2"/>
</Properties>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="jTextArea1">
<Properties>
<Property name="columns" type="int" value="20"/>
<Property name="rows" type="int" value="5"/>
</Properties>
</Component>
</SubComponents>
</Container>
</NonVisualComponents>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
@ -47,55 +32,68 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="jPanel1" min="-2" max="-2" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jPanel1" min="-2" max="-2" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="jPanel1">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="infoLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Component id="jScrollPane2" pref="389" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="selectedPathsScrollPane" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="selectButton" max="32767" attributes="0"/>
<Component id="clearButton" pref="69" max="32767" attributes="0"/>
<Component id="selectButton" linkSize="1" alignment="0" max="32767" attributes="0"/>
<Component id="clearButton" linkSize="1" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
<Group type="102" attributes="0">
<Component id="displayNameLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="jButton1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="changeNameButton" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="errorLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="infoLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="selectButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="36" max="-2" attributes="0"/>
<Component id="clearButton" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="jScrollPane2" min="-2" pref="82" max="-2" attributes="0"/>
<Component id="selectedPathsScrollPane" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jButton1" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
<Component id="changeNameButton" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
<Component id="displayNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="13" max="-2" attributes="0"/>
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="7" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -112,18 +110,20 @@
<Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="LocalFilesPanel.selectButton.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="selectButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="infoLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="LocalFilesPanel.infoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="clearButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
@ -132,12 +132,26 @@
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="LocalFilesPanel.clearButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="clearButtonActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
<Container class="javax.swing.JScrollPane" name="selectedPathsScrollPane">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[379, 96]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
@ -166,14 +180,14 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="jButton1">
<Component class="javax.swing.JButton" name="changeNameButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="LocalFilesPanel.jButton1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="LocalFilesPanel.changeNameButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton1ActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changeNameButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="displayNameLabel">
@ -184,4 +198,6 @@
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Copyright 2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -24,44 +24,34 @@ import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PathValidator;
/**
* Add input wizard subpanel for adding local files / dirs to the case
* A panel which allows the user to select local files and/or directories.
*/
final class LocalFilesPanel extends JPanel {
final class LocalFilesPanel extends javax.swing.JPanel {
private static final long serialVersionUID = 1L;
private final Set<File> currentFiles = new TreeSet<>(); //keep currents in a set to disallow duplicates per add
private boolean enableNext = false;
private static LocalFilesPanel instance;
private static final Logger logger = Logger.getLogger(LocalFilesPanel.class.getName());
private String displayName = "";
/**
* Creates new form LocalFilesPanel
*/
private LocalFilesPanel() {
LocalFilesPanel() {
initComponents();
customInit();
}
static synchronized LocalFilesPanel getDefault() {
if (instance == null) {
instance = new LocalFilesPanel();
}
return instance;
}
private void customInit() {
localFileChooser.setMultiSelectionEnabled(true);
errorLabel.setVisible(false);
@ -69,69 +59,6 @@ final class LocalFilesPanel extends JPanel {
this.displayNameLabel.setText(NbBundle.getMessage(this.getClass(), "LocalFilesPanel.displayNameLabel.text"));
}
public List<String> getContentPaths() {
List<String> pathsList = new ArrayList<>();
if (currentFiles == null) {
return pathsList;
}
for (File f : currentFiles) {
pathsList.add(f.getAbsolutePath());
}
return pathsList;
}
public String getContentType() {
return NbBundle.getMessage(this.getClass(), "LocalFilesPanel.contentType.text");
}
public boolean validatePanel() {
// display warning if there is one (but don't disable "next" button)
warnIfPathIsInvalid(getContentPaths());
return enableNext;
}
/**
* Validates path to selected data source and displays warning if it is
* invalid.
*
* @param paths Absolute paths to the selected data source
*/
private void warnIfPathIsInvalid(List<String> pathsList) {
errorLabel.setVisible(false);
CaseType currentCaseType = Case.getCurrentCase().getCaseType();
for (String currentPath : pathsList) {
if (!PathValidator.isValid(currentPath, currentCaseType)) {
errorLabel.setVisible(true);
errorLabel.setText(NbBundle.getMessage(this.getClass(), "DataSourceOnCDriveError.text"));
return;
}
}
}
public void select() {
reset();
}
public void reset() {
currentFiles.clear();
selectedPaths.setText("");
enableNext = false;
errorLabel.setVisible(false);
displayName = "";
this.displayNameLabel.setText(NbBundle.getMessage(this.getClass(), "LocalFilesPanel.displayNameLabel.text"));
}
public String getFileSetName() {
return this.displayName;
}
@Override
public String toString() {
return NbBundle.getMessage(this.getClass(), "LocalFilesDSProcessor.toString.text");
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
@ -142,15 +69,13 @@ final class LocalFilesPanel extends JPanel {
private void initComponents() {
localFileChooser = new javax.swing.JFileChooser();
jScrollPane1 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();
jPanel1 = new javax.swing.JPanel();
selectButton = new javax.swing.JButton();
infoLabel = new javax.swing.JLabel();
clearButton = new javax.swing.JButton();
jScrollPane2 = new javax.swing.JScrollPane();
selectedPathsScrollPane = new javax.swing.JScrollPane();
selectedPaths = new javax.swing.JTextArea();
errorLabel = new javax.swing.JLabel();
jButton1 = new javax.swing.JButton();
changeNameButton = new javax.swing.JButton();
displayNameLabel = new javax.swing.JLabel();
localFileChooser.setApproveButtonText(org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.localFileChooser.approveButtonText")); // NOI18N
@ -158,103 +83,115 @@ final class LocalFilesPanel extends JPanel {
localFileChooser.setDialogTitle(org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.localFileChooser.dialogTitle")); // NOI18N
localFileChooser.setFileSelectionMode(javax.swing.JFileChooser.FILES_AND_DIRECTORIES);
jTextArea1.setColumns(20);
jTextArea1.setRows(5);
jScrollPane1.setViewportView(jTextArea1);
org.openide.awt.Mnemonics.setLocalizedText(selectButton, org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.selectButton.text")); // NOI18N
selectButton.setToolTipText(org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.selectButton.toolTipText")); // NOI18N
selectButton.setActionCommand(org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.selectButton.actionCommand")); // NOI18N
selectButton.setMaximumSize(new java.awt.Dimension(70, 23));
selectButton.setMinimumSize(new java.awt.Dimension(70, 23));
selectButton.setPreferredSize(new java.awt.Dimension(70, 23));
selectButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
selectButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(infoLabel, org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.infoLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(clearButton, org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.clearButton.text")); // NOI18N
clearButton.setToolTipText(org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.clearButton.toolTipText")); // NOI18N
clearButton.setMaximumSize(new java.awt.Dimension(70, 23));
clearButton.setMinimumSize(new java.awt.Dimension(70, 23));
clearButton.setPreferredSize(new java.awt.Dimension(70, 23));
clearButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
clearButtonActionPerformed(evt);
}
});
selectedPathsScrollPane.setPreferredSize(new java.awt.Dimension(379, 96));
selectedPaths.setEditable(false);
selectedPaths.setColumns(20);
selectedPaths.setRows(5);
selectedPaths.setToolTipText(org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.selectedPaths.toolTipText")); // NOI18N
jScrollPane2.setViewportView(selectedPaths);
selectedPathsScrollPane.setViewportView(selectedPaths);
errorLabel.setForeground(new java.awt.Color(255, 0, 0));
org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.errorLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.jButton1.text")); // NOI18N
jButton1.addActionListener(new java.awt.event.ActionListener() {
org.openide.awt.Mnemonics.setLocalizedText(changeNameButton, org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.changeNameButton.text")); // NOI18N
changeNameButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
changeNameButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(displayNameLabel, org.openide.util.NbBundle.getMessage(LocalFilesPanel.class, "LocalFilesPanel.displayNameLabel.text")); // NOI18N
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addComponent(selectedPathsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(selectButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(clearButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGap(2, 2, 2))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(displayNameLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(changeNameButton))
.addComponent(errorLabel))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
);
jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {clearButton, selectButton});
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(selectButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(36, 36, 36)
.addComponent(clearButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(selectedPathsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(changeNameButton, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(displayNameLabel))
.addGap(13, 13, 13)
.addComponent(errorLabel)
.addContainerGap())
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(infoLabel)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 389, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(selectButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(clearButton, javax.swing.GroupLayout.DEFAULT_SIZE, 69, Short.MAX_VALUE))
.addGap(2, 2, 2))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(errorLabel)
.addGroup(layout.createSequentialGroup()
.addComponent(displayNameLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jButton1)))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(infoLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addComponent(selectButton)
.addGap(36, 36, 36)
.addComponent(clearButton))
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(displayNameLabel))
.addGap(13, 13, 13)
.addComponent(errorLabel)
.addGap(7, 7, 7))
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
);
}// </editor-fold>//GEN-END:initComponents
private void selectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectButtonActionPerformed
int returnVal = localFileChooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File[] files = localFileChooser.getSelectedFiles();
StringBuilder allPaths = new StringBuilder();
for (File f : files) {
currentFiles.add(f);
}
//update label
StringBuilder allPaths = new StringBuilder();
for (File f : currentFiles) {
allPaths.append(f.getAbsolutePath()).append("\n");
}
this.selectedPaths.setText(allPaths.toString());
@ -275,28 +212,101 @@ final class LocalFilesPanel extends JPanel {
private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearButtonActionPerformed
reset();
}//GEN-LAST:event_clearButtonActionPerformed
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
String displayName = JOptionPane.showInputDialog("New Display Name: ");
if (displayName != null && !displayName.equals("")) {
this.displayName = displayName;
private void changeNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_changeNameButtonActionPerformed
final String selectedDisplayName = JOptionPane.showInputDialog("New Display Name: ");
if (selectedDisplayName != null && !selectedDisplayName.isEmpty()) {
this.displayName = selectedDisplayName;
this.displayNameLabel.setText("Display Name: " + this.displayName);
}
}//GEN-LAST:event_jButton1ActionPerformed
}//GEN-LAST:event_changeNameButtonActionPerformed
/**
* Clear the fields and undo any selection of files.
*/
void reset() {
currentFiles.clear();
selectedPaths.setText("");
enableNext = false;
errorLabel.setVisible(false);
displayName = "";
this.displayNameLabel.setText(NbBundle.getMessage(this.getClass(), "LocalFilesPanel.displayNameLabel.text"));
try {
firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
} catch (Exception e) {
logger.log(Level.SEVERE, "LocalFilesPanel listener threw exception", e); //NON-NLS
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "LocalFilesPanel.moduleErr"),
NbBundle.getMessage(this.getClass(), "LocalFilesPanel.moduleErr.msg"),
MessageNotifyUtil.MessageType.ERROR);
}
}
/**
* Get the path(s) which have been selected on this panel
*
* @return a List of Strings representing the path(s) for the selected files or directories
*/
List<String> getContentPaths() {
List<String> pathsList = new ArrayList<>();
if (currentFiles == null) {
return pathsList;
}
for (File f : currentFiles) {
pathsList.add(f.getAbsolutePath());
}
return pathsList;
}
/**
* Validates path to selected data source and displays warning if it is
* invalid.
*
* @return enableNext - true if the panel is valid, false if invalid
*/
boolean validatePanel() {
// display warning if there is one (but don't disable "next" button)
warnIfPathIsInvalid(getContentPaths());
return enableNext;
}
/**
* Validates path to selected data source and displays warning if it is
* invalid.
*
* @param paths Absolute paths to the selected data source
*/
private void warnIfPathIsInvalid(final List<String> pathsList) {
errorLabel.setVisible(false);
final Case.CaseType currentCaseType = Case.getCurrentCase().getCaseType();
for (String currentPath : pathsList) {
if (!PathValidator.isValid(currentPath, currentCaseType)) {
errorLabel.setVisible(true);
errorLabel.setText(NbBundle.getMessage(this.getClass(), "DataSourceOnCDriveError.text"));
return;
}
}
}
/**
* Get the name given to this collection of local files and directories
*
* @return a String which is the name for the file set.
*/
String getFileSetName() {
return this.displayName;
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton changeNameButton;
private javax.swing.JButton clearButton;
private javax.swing.JLabel displayNameLabel;
private javax.swing.JLabel errorLabel;
private javax.swing.JLabel infoLabel;
private javax.swing.JButton jButton1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTextArea jTextArea1;
private javax.swing.JPanel jPanel1;
private javax.swing.JFileChooser localFileChooser;
private javax.swing.JButton selectButton;
private javax.swing.JTextArea selectedPaths;
private javax.swing.JScrollPane selectedPathsScrollPane;
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<NonVisualComponents>
<Component class="javax.swing.JFileChooser" name="logicalEvidenceFileChooser">
<Properties>
<Property name="approveButtonText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="LogicalEvidenceFilePanel.logicalEvidenceFileChooser.approveButtonText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="approveButtonToolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="LogicalEvidenceFilePanel.logicalEvidenceFileChooser.approveButtonToolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="dialogTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="LogicalEvidenceFilePanel.logicalEvidenceFileChooser.dialogTitle" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="fileSelectionMode" type="int" value="2"/>
</Properties>
</Component>
</NonVisualComponents>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="errorLabel" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Component id="logicalEvidencePathField" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="selectButton" min="-2" pref="68" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="selectButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="logicalEvidencePathField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="105" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="selectButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="LogicalEvidenceFilePanel.selectButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="LogicalEvidenceFilePanel.selectButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="LogicalEvidenceFilePanel.selectButton.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="selectButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="logicalEvidencePathField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="LogicalEvidenceFilePanel.logicalEvidencePathField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[379, 20]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="errorLabel">
<Properties>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="0" green="0" red="ff" type="rgb"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="LogicalEvidenceFilePanel.errorLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,260 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import javax.swing.JFileChooser;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import java.util.logging.Level;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PathValidator;
/**
* A panel which allows the user to select a Logical Evidence File (L01)
*/
final class LogicalEvidenceFilePanel extends javax.swing.JPanel implements DocumentListener {
private static final long serialVersionUID = 1L;
private final Set<File> currentFiles = new TreeSet<>(); //keep currents in a set to disallow duplicates per add
private static final Logger logger = Logger.getLogger(LocalFilesPanel.class.getName());
private String displayName = "";
/**
* Creates new form LogicalEvidenceFilePanel
*/
private LogicalEvidenceFilePanel() {
initComponents();
logicalEvidenceFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
logicalEvidenceFileChooser.setAcceptAllFileFilterUsed(false);
logicalEvidenceFileChooser.setMultiSelectionEnabled(false);
logicalEvidenceFileChooser.setFileFilter(LocalFilesDSProcessor.getLogicalEvidenceFilter());
}
/**
* Create a new LogicalEvidencePanel.
*
* @return
*/
static LogicalEvidenceFilePanel createInstance() {
synchronized (LogicalEvidenceFilePanel.class) {
final LogicalEvidenceFilePanel instance = new LogicalEvidenceFilePanel();
// post-constructor initialization of listener support without leaking references of uninitialized objects
instance.logicalEvidencePathField.getDocument().addDocumentListener(instance);
return instance;
}
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
logicalEvidenceFileChooser = new javax.swing.JFileChooser();
selectButton = new javax.swing.JButton();
logicalEvidencePathField = new javax.swing.JTextField();
errorLabel = new javax.swing.JLabel();
logicalEvidenceFileChooser.setApproveButtonText(org.openide.util.NbBundle.getMessage(LogicalEvidenceFilePanel.class, "LogicalEvidenceFilePanel.logicalEvidenceFileChooser.approveButtonText")); // NOI18N
logicalEvidenceFileChooser.setApproveButtonToolTipText(org.openide.util.NbBundle.getMessage(LogicalEvidenceFilePanel.class, "LogicalEvidenceFilePanel.logicalEvidenceFileChooser.approveButtonToolTipText")); // NOI18N
logicalEvidenceFileChooser.setDialogTitle(org.openide.util.NbBundle.getMessage(LogicalEvidenceFilePanel.class, "LogicalEvidenceFilePanel.logicalEvidenceFileChooser.dialogTitle")); // NOI18N
logicalEvidenceFileChooser.setFileSelectionMode(javax.swing.JFileChooser.FILES_AND_DIRECTORIES);
org.openide.awt.Mnemonics.setLocalizedText(selectButton, org.openide.util.NbBundle.getMessage(LogicalEvidenceFilePanel.class, "LogicalEvidenceFilePanel.selectButton.text")); // NOI18N
selectButton.setToolTipText(org.openide.util.NbBundle.getMessage(LogicalEvidenceFilePanel.class, "LogicalEvidenceFilePanel.selectButton.toolTipText")); // NOI18N
selectButton.setActionCommand(org.openide.util.NbBundle.getMessage(LogicalEvidenceFilePanel.class, "LogicalEvidenceFilePanel.selectButton.actionCommand")); // NOI18N
selectButton.setMaximumSize(new java.awt.Dimension(70, 23));
selectButton.setMinimumSize(new java.awt.Dimension(70, 23));
selectButton.setPreferredSize(new java.awt.Dimension(70, 23));
selectButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
selectButtonActionPerformed(evt);
}
});
logicalEvidencePathField.setText(org.openide.util.NbBundle.getMessage(LogicalEvidenceFilePanel.class, "LogicalEvidenceFilePanel.logicalEvidencePathField.text")); // NOI18N
logicalEvidencePathField.setPreferredSize(new java.awt.Dimension(379, 20));
errorLabel.setForeground(new java.awt.Color(255, 0, 0));
org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(LogicalEvidenceFilePanel.class, "LogicalEvidenceFilePanel.errorLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(errorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addComponent(logicalEvidencePathField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(selectButton, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(4, 4, 4))))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(0, 0, 0)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(selectButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(logicalEvidencePathField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(18, 18, 18)
.addComponent(errorLabel)
.addContainerGap(105, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
private void selectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectButtonActionPerformed
final int returnVal = logicalEvidenceFileChooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
final File file = logicalEvidenceFileChooser.getSelectedFile();
final StringBuilder allPaths = new StringBuilder();
currentFiles.add(file);
allPaths.append(file.getAbsolutePath());
logicalEvidencePathField.setText(allPaths.toString());
logicalEvidencePathField.setToolTipText(allPaths.toString());
}
fireChange();
}//GEN-LAST:event_selectButtonActionPerformed
/*
* Clear previously selected items on the panel.
*/
void reset() {
currentFiles.clear();
logicalEvidencePathField.setText("");
logicalEvidencePathField.setToolTipText("");
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel errorLabel;
private javax.swing.JFileChooser logicalEvidenceFileChooser;
private javax.swing.JTextField logicalEvidencePathField;
private javax.swing.JButton selectButton;
// End of variables declaration//GEN-END:variables
/**
* Check if the current selection exists and is a logical evidence file and
* therefore the panel is valid.
*
* @return true for a valid selection, false for an invalid or empty
* selection
*/
@Messages({
"LogicalEvidenceFilePanel.validatePanel.nonL01Error.text=Only files with the .l01 file extension are supported here."
})
boolean validatePanel() {
errorLabel.setVisible(false);
// display warning if there is one (but don't disable "next" button)
final String path = logicalEvidencePathField.getText();
if (StringUtils.isBlank(path)) {
return false;
}
// display warning if there is one (but don't disable "next" button)
if (!PathValidator.isValid(path, Case.getCurrentCase().getCaseType())) {
errorLabel.setVisible(true);
errorLabel.setText(Bundle.DataSourceOnCDriveError_text());
return false;
}
//check the extension incase the path was manually entered
if (!LocalFilesDSProcessor.getLogicalEvidenceFilter().accept(new File(path))) {
errorLabel.setVisible(true);
errorLabel.setText(Bundle.LogicalEvidenceFilePanel_validatePanel_nonL01Error_text());
return false;
}
displayName = FilenameUtils.getName(path);
return new File(path).isFile();
}
/**
* Get the path(s) which have been selected on this panel
*
* @return a List of Strings representing the path(s) for the selected files
*/
List<String> getContentPaths() {
final List<String> pathsList = new ArrayList<>();
if (currentFiles == null) {
return pathsList;
}
for (final File f : currentFiles) {
pathsList.add(f.getAbsolutePath());
}
return pathsList;
}
/**
* Get the name of the logical evidence file which was selected.
*
* @return the name of the logical evidence file
*/
String getFileSetName() {
return displayName;
}
@Override
public void insertUpdate(final DocumentEvent docEvent) {
fireChange();
}
@Override
public void removeUpdate(final DocumentEvent docEvent) {
fireChange();
}
@Override
public void changedUpdate(final DocumentEvent docEvent) {
fireChange();
}
@Messages({
"LogicalEvidenceFilePanel.moduleErr.name=Module Error",
"LogicalEvidenceFilePanel.moduleErr.msg=A module caused an error listening to LogicalEvidenceFilePanel updates. See log to determine which module. Some data could be incomplete."
})
private void fireChange() {
try {
firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
} catch (Exception e) {
logger.log(Level.SEVERE, "LogicalEvidenceFilePanel listener threw exception", e); //NON-NLS
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "LogicalEvidenceFilePanel.moduleErr"),
NbBundle.getMessage(this.getClass(), "LogicalEvidenceFilePanel.moduleErr.msg"),
MessageNotifyUtil.MessageType.ERROR);
}
}
}

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="dspSubtypeComboBox" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="dspSubtypePanel" alignment="0" min="-2" pref="466" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="dspSubtypeComboBox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="dspSubtypePanel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="dspSubtypePanel">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[467, 160]"/>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="466" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="160" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
</Container>
<Component class="javax.swing.JComboBox" name="dspSubtypeComboBox">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.DefaultComboBoxModel&lt;&gt;(new String[] {Bundle.LogicalFilesDspPanel_subTypeComboBox_localFilesOption_text(), Bundle.LogicalFilesDspPanel_subTypeComboBox_l01FileOption_text()})" type="code"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[379, 20]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[379, 20]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="dspSubtypeComboBoxActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,233 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
@Messages({
"LogicalFilesDspPanel.subTypeComboBox.localFilesOption.text=Local files and folders",
"LogicalFilesDspPanel.subTypeComboBox.l01FileOption.text=Logical evidence file (L01)"
})
/**
* Add input wizard subpanel for adding local files / dirs to the case
*/
final class LogicalFilesDspPanel extends JPanel {
private static final long serialVersionUID = 1L;
private final LocalFilesPanel localFilesPanel = new LocalFilesPanel();
private final LogicalEvidenceFilePanel l01panel = LogicalEvidenceFilePanel.createInstance();
private static LogicalFilesDspPanel instance;
/**
* Creates new form LocalFilesPanel
*/
private LogicalFilesDspPanel() {
initComponents();
dspSubtypePanel.setLayout(new BoxLayout(dspSubtypePanel, BoxLayout.Y_AXIS));
dspSubtypePanel.add(l01panel);
dspSubtypePanel.add(localFilesPanel);
l01panel.setVisible(false);
}
@Override
public void addPropertyChangeListener(final PropertyChangeListener listener) {
super.addPropertyChangeListener(listener);
localFilesPanel.addPropertyChangeListener(listener);
l01panel.addPropertyChangeListener(listener);
}
@Override
public void removePropertyChangeListener(final PropertyChangeListener listener) {
super.removePropertyChangeListener(listener);
localFilesPanel.removePropertyChangeListener(listener);
l01panel.removePropertyChangeListener(listener);
}
static LogicalFilesDspPanel getDefault() {
synchronized (LogicalFilesDspPanel.class) {
if (instance == null) {
instance = new LogicalFilesDspPanel();
}
return instance;
}
}
String getContentType() {
return NbBundle.getMessage(this.getClass(), "LocalFilesPanel.contentType.text");
}
void select() {
dspSubtypeComboBox.setSelectedIndex(0);
localFilesPanel.setVisible(true);
l01panel.setVisible(false);
localFilesPanel.reset();
l01panel.reset();
dspSubtypePanel.repaint();
}
@Override
public String toString() {
return NbBundle.getMessage(this.getClass(), "LocalFilesDSProcessor.toString.text");
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
dspSubtypePanel = new javax.swing.JPanel();
dspSubtypeComboBox = new javax.swing.JComboBox<>();
dspSubtypePanel.setPreferredSize(new java.awt.Dimension(467, 160));
javax.swing.GroupLayout dspSubtypePanelLayout = new javax.swing.GroupLayout(dspSubtypePanel);
dspSubtypePanel.setLayout(dspSubtypePanelLayout);
dspSubtypePanelLayout.setHorizontalGroup(
dspSubtypePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 466, Short.MAX_VALUE)
);
dspSubtypePanelLayout.setVerticalGroup(
dspSubtypePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 160, Short.MAX_VALUE)
);
dspSubtypeComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] {Bundle.LogicalFilesDspPanel_subTypeComboBox_localFilesOption_text(), Bundle.LogicalFilesDspPanel_subTypeComboBox_l01FileOption_text()}));
dspSubtypeComboBox.setMinimumSize(new java.awt.Dimension(379, 20));
dspSubtypeComboBox.setPreferredSize(new java.awt.Dimension(379, 20));
dspSubtypeComboBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
dspSubtypeComboBoxActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(dspSubtypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(dspSubtypePanel, javax.swing.GroupLayout.PREFERRED_SIZE, 466, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(dspSubtypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(dspSubtypePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0))
);
}// </editor-fold>//GEN-END:initComponents
private void dspSubtypeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dspSubtypeComboBoxActionPerformed
if (evt.getSource() instanceof JComboBox<?>) {
final String selectedSubType = dspSubtypeComboBox.getSelectedItem().toString();
if (selectedSubType.equals(Bundle.LogicalFilesDspPanel_subTypeComboBox_localFilesOption_text())) {
localFilesPanel.setVisible(true);
l01panel.setVisible(false);
} else if (selectedSubType.equals(Bundle.LogicalFilesDspPanel_subTypeComboBox_l01FileOption_text())) {
localFilesPanel.setVisible(false);
l01panel.setVisible(true);
}
firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
}
}//GEN-LAST:event_dspSubtypeComboBoxActionPerformed
/**
* Validate the contents of the panel and its subtype.
*
* @return true if the panel is valid, false if it is not
*/
boolean validatePanel() {
// display warning if there is one (but don't disable "next" button)
final String selectedSubType = dspSubtypeComboBox.getSelectedItem().toString();
if (selectedSubType.equals(Bundle.LogicalFilesDspPanel_subTypeComboBox_localFilesOption_text())) {
return localFilesPanel.validatePanel();
} else if (selectedSubType.equals(Bundle.LogicalFilesDspPanel_subTypeComboBox_l01FileOption_text())) {
return l01panel.validatePanel();
} else {
return false;
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JComboBox<String> dspSubtypeComboBox;
private javax.swing.JPanel dspSubtypePanel;
// End of variables declaration//GEN-END:variables
/**
* Identify if the selected subtype panel is a LogicalEvidencePanel
*
* @return true if logical evidence files have been selected
*/
boolean subTypeIsLogicalEvidencePanel() {
final String selectedSubType = dspSubtypeComboBox.getSelectedItem().toString();
return selectedSubType.equals(Bundle.LogicalFilesDspPanel_subTypeComboBox_l01FileOption_text());
}
/**
* Get the selected paths of the selected panel subtype.
*
* @return a list of strings which are paths to the selected files or
* directories
*/
List<String> getContentPaths() {
String selectedSubType = dspSubtypeComboBox.getSelectedItem().toString();
if (selectedSubType.equals(Bundle.LogicalFilesDspPanel_subTypeComboBox_localFilesOption_text())) {
return localFilesPanel.getContentPaths();
} else if (selectedSubType.equals(Bundle.LogicalFilesDspPanel_subTypeComboBox_l01FileOption_text())) {
return l01panel.getContentPaths();
} else {
return new ArrayList<>();
}
}
/**
* Get the name of the file set based on its subtype.
*
* @return the name of the set of files to be ingested.
*/
String getFileSetName() {
String selectedSubType = dspSubtypeComboBox.getSelectedItem().toString();
if (selectedSubType.equals(Bundle.LogicalFilesDspPanel_subTypeComboBox_localFilesOption_text())) {
return localFilesPanel.getFileSetName();
} else if (selectedSubType.equals(Bundle.LogicalFilesDspPanel_subTypeComboBox_l01FileOption_text())) {
return l01panel.getFileSetName();
} else {
return "";
}
}
}

View File

@ -2,7 +2,7 @@ EncryptionDetectionIngestJobSettingsPanel.minimumEntropyLabel.text=Minimum Entro
EncryptionDetectionIngestJobSettingsPanel.minimumFileSizeLabel.text=Minimum File Size:
EncryptionDetectionIngestJobSettingsPanel.fileSizeMultiplesEnforcedCheckbox.text=Consider only files with sizes that are multiples of 512.
EncryptionDetectionIngestJobSettingsPanel.slackFilesAllowedCheckbox.text=Consider slack space files.
EncryptionDetectionIngestJobSettingsPanel.minimumEntropyTextbox.text=
EncryptionDetectionIngestJobSettingsPanel.minimumFileSizeTextbox.text=
EncryptionDetectionIngestJobSettingsPanel.mbLabel.text=MB
EncryptionDetectionIngestJobSettingsPanel.detectionSettingsLabel.text=Detection Settings
EncryptionDetectionIngestJobSettingsPanel.minimumFileSizeTextbox.text=
EncryptionDetectionIngestJobSettingsPanel.minimumEntropyTextbox.text=

View File

@ -23,6 +23,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -49,12 +50,16 @@ final class EncryptionDetectionFileIngestModule extends FileIngestModuleAdapter
static final boolean DEFAULT_CONFIG_FILE_SIZE_MULTIPLE_ENFORCED = true;
static final boolean DEFAULT_CONFIG_SLACK_FILES_ALLOWED = true;
static final double MINIMUM_ENTROPY_INPUT_RANGE_MIN = 6.0;
static final double MINIMUM_ENTROPY_INPUT_RANGE_MAX = 8.0;
static final int MINIMUM_FILE_SIZE_INPUT_RANGE_MIN = 1;
private static final int FILE_SIZE_MODULUS = 512;
private static final double ONE_OVER_LOG2 = 1.4426950408889634073599246810019; // (1 / log(2))
private static final int BYTE_OCCURENCES_BUFFER_SIZE = 256;
private final IngestServices SERVICES = IngestServices.getInstance();
private final Logger LOGGER = SERVICES.getLogger(EncryptionDetectionModuleFactory.getModuleName());
private final IngestServices services = IngestServices.getInstance();
private final Logger logger = services.getLogger(EncryptionDetectionModuleFactory.getModuleName());
private FileTypeDetector fileTypeDetector;
private Blackboard blackboard;
private double calculatedEntropy;
@ -79,8 +84,9 @@ final class EncryptionDetectionFileIngestModule extends FileIngestModuleAdapter
@Override
public void startUp(IngestJobContext context) throws IngestModule.IngestModuleException {
blackboard = Case.getCurrentCase().getServices().getBlackboard();
try {
validateSettings();
blackboard = Case.getCurrentCase().getServices().getBlackboard();
fileTypeDetector = new FileTypeDetector();
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
throw new IngestModule.IngestModuleException("Failed to create file type detector", ex);
@ -95,13 +101,33 @@ final class EncryptionDetectionFileIngestModule extends FileIngestModuleAdapter
return flagFile(file);
}
} catch (IOException | TskCoreException ex) {
LOGGER.log(Level.SEVERE, String.format("Unable to process file '%s'", file.getParentPath() + file.getName()), ex);
logger.log(Level.SEVERE, String.format("Unable to process file '%s'", file.getParentPath() + file.getName()), ex);
return IngestModule.ProcessResult.ERROR;
}
return IngestModule.ProcessResult.OK;
}
/**
* Validate ingest module settings.
*
* @throws IngestModule.IngestModuleException If the input is empty,
* invalid, or out of range.
*/
@NbBundle.Messages({
"EncryptionDetectionFileIngestModule.errorMessage.minimumEntropyInput=Minimum entropy input must be a number between 6.0 and 8.0.",
"EncryptionDetectionFileIngestModule.errorMessage.minimumFileSizeInput=Minimum file size input must be an integer (in megabytes) of 1 or greater."
})
private void validateSettings() throws IngestModule.IngestModuleException {
if (minimumEntropy < MINIMUM_ENTROPY_INPUT_RANGE_MIN || minimumEntropy > MINIMUM_ENTROPY_INPUT_RANGE_MAX) {
throw new IngestModule.IngestModuleException(Bundle.EncryptionDetectionFileIngestModule_errorMessage_minimumEntropyInput());
}
if (minimumFileSize < MINIMUM_FILE_SIZE_INPUT_RANGE_MIN) {
throw new IngestModule.IngestModuleException(Bundle.EncryptionDetectionFileIngestModule_errorMessage_minimumFileSizeInput());
}
}
/**
* Create a blackboard artifact.
*
@ -120,13 +146,13 @@ final class EncryptionDetectionFileIngestModule extends FileIngestModuleAdapter
*/
blackboard.indexArtifact(artifact);
} catch (Blackboard.BlackboardException ex) {
LOGGER.log(Level.SEVERE, "Unable to index blackboard artifact " + artifact.getArtifactID(), ex); //NON-NLS
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + artifact.getArtifactID(), ex); //NON-NLS
}
/*
* Send an event to update the view with the new result.
*/
SERVICES.fireModuleDataEvent(new ModuleDataEvent(EncryptionDetectionModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED, Collections.singletonList(artifact)));
services.fireModuleDataEvent(new ModuleDataEvent(EncryptionDetectionModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED, Collections.singletonList(artifact)));
/*
* Make an ingest inbox message.
@ -135,7 +161,7 @@ final class EncryptionDetectionFileIngestModule extends FileIngestModuleAdapter
detailsSb.append("File: ").append(file.getParentPath()).append(file.getName()).append("<br/>\n");
detailsSb.append("Entropy: ").append(calculatedEntropy);
SERVICES.postMessage(IngestMessage.createDataMessage(EncryptionDetectionModuleFactory.getModuleName(),
services.postMessage(IngestMessage.createDataMessage(EncryptionDetectionModuleFactory.getModuleName(),
"Encryption Detected Match: " + file.getName(),
detailsSb.toString(),
file.getName(),
@ -143,7 +169,7 @@ final class EncryptionDetectionFileIngestModule extends FileIngestModuleAdapter
return IngestModule.ProcessResult.OK;
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, String.format("Failed to create blackboard artifact for '%s'.", file.getParentPath() + file.getName()), ex); //NON-NLS
logger.log(Level.SEVERE, String.format("Failed to create blackboard artifact for '%s'.", file.getParentPath() + file.getName()), ex); //NON-NLS
return IngestModule.ProcessResult.ERROR;
}
}

View File

@ -21,12 +21,13 @@
<Group type="103" groupAlignment="0" attributes="0">
<Component id="slackFilesAllowedCheckbox" min="-2" max="-2" attributes="0"/>
<Component id="detectionSettingsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="fileSizeMultiplesEnforcedCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="minimumFileSizeLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="minimumFileSizeTextbox" min="-2" pref="32" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="mbLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="minimumEntropyLabel" min="-2" max="-2" attributes="0"/>
@ -34,11 +35,6 @@
<Component id="minimumEntropyTextbox" min="-2" pref="32" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="mbLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="fileSizeMultiplesEnforcedCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="15" max="32767" attributes="0"/>
</Group>
</Group>
@ -50,14 +46,14 @@
<Component id="detectionSettingsLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="16" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="minimumEntropyTextbox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="minimumEntropyLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="minimumEntropyTextbox" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="minimumFileSizeTextbox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="mbLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="minimumFileSizeLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="minimumFileSizeTextbox" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="fileSizeMultiplesEnforcedCheckbox" min="-2" max="-2" attributes="0"/>
@ -69,20 +65,6 @@
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JTextField" name="minimumEntropyTextbox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/encryptiondetection/Bundle.properties" key="EncryptionDetectionIngestJobSettingsPanel.minimumEntropyTextbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="minimumFileSizeTextbox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/encryptiondetection/Bundle.properties" key="EncryptionDetectionIngestJobSettingsPanel.minimumFileSizeTextbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="fileSizeMultiplesEnforcedCheckbox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
@ -128,5 +110,28 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JFormattedTextField" name="minimumFileSizeTextbox">
<Properties>
<Property name="formatterFactory" type="javax.swing.JFormattedTextField$AbstractFormatterFactory" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="minimumFileSizeTextFormatterFactory" type="code"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/encryptiondetection/Bundle.properties" key="EncryptionDetectionIngestJobSettingsPanel.minimumFileSizeTextbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="minimumFileSizeTextboxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JFormattedTextField" name="minimumEntropyTextbox">
<Properties>
<Property name="formatterFactory" type="javax.swing.JFormattedTextField$AbstractFormatterFactory" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="minimumEntropyTextFormatterFactory" type="code"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/encryptiondetection/Bundle.properties" key="EncryptionDetectionIngestJobSettingsPanel.minimumEntropyTextbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2017 Basis Technology Corp.
* Copyright 2017-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -18,8 +18,11 @@
*/
package org.sleuthkit.autopsy.modules.encryptiondetection;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import java.text.ParseException;
import java.util.logging.Level;
import javax.swing.text.DefaultFormatter;
import javax.swing.text.DefaultFormatterFactory;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
@ -29,9 +32,12 @@ import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
final class EncryptionDetectionIngestJobSettingsPanel extends IngestModuleIngestJobSettingsPanel {
private static final int MEGABYTE_SIZE = 1048576;
private static final double MINIMUM_ENTROPY_INPUT_RANGE_MIN = 6.0;
private static final double MINIMUM_ENTROPY_INPUT_RANGE_MAX = 8.0;
private static final int MINIMUM_FILE_SIZE_INPUT_RANGE_MIN = 1;
private static final int INVALID_TEXT_FIELD_INPUT_RETURN = -1;
private final Logger logger = Logger.getLogger(EncryptionDetectionIngestJobSettingsPanel.class.getName());
private final DefaultFormatterFactory minimumFileSizeTextFormatterFactory = new DefaultFormatterFactory(new StringIntegerFormatter());
private final DefaultFormatterFactory minimumEntropyTextFormatterFactory = new DefaultFormatterFactory(new StringDoubleFormatter());
/**
* Instantiate the ingest job settings panel.
@ -57,9 +63,6 @@ final class EncryptionDetectionIngestJobSettingsPanel extends IngestModuleIngest
@Override
public IngestModuleIngestJobSettings getSettings() {
validateMinimumEntropy();
validateMinimumFileSize();
return new EncryptionDetectionIngestJobSettings(
Double.valueOf(minimumEntropyTextbox.getText()),
Integer.valueOf(minimumFileSizeTextbox.getText()) * MEGABYTE_SIZE,
@ -68,42 +71,44 @@ final class EncryptionDetectionIngestJobSettingsPanel extends IngestModuleIngest
}
/**
* Validate the minimum entropy input.
*
* @throws IllegalArgumentException If the input is empty, invalid, or out
* of range.
* Formatter to handle conversion between String and Double.
*/
@Messages({
"EncryptionDetectionIngestJobSettingsPanel.minimumEntropyInput.validationError.text=Minimum entropy input must be a number between 6.0 and 8.0."
})
private void validateMinimumEntropy() throws IllegalArgumentException {
private final class StringDoubleFormatter extends DefaultFormatter {
@Override
public Object stringToValue(String string) throws ParseException {
try {
double minimumEntropy = Double.valueOf(minimumEntropyTextbox.getText());
if (minimumEntropy < MINIMUM_ENTROPY_INPUT_RANGE_MIN || minimumEntropy > MINIMUM_ENTROPY_INPUT_RANGE_MAX) {
throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), "EncryptionDetectionIngestJobSettingsPanel.minimumEntropyInput.validationError.text"));
}
return Double.parseDouble(string);
} catch (NumberFormatException ex) {
throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), "EncryptionDetectionIngestJobSettingsPanel.minimumEntropyInput.validationError.text"));
logger.log(Level.WARNING, String.format("The String input '%s' is not valid for Double conversion.", string), ex);
/*
* Return a valid number outside the acceptable value range so
* it can be run through the validator in the file ingest
* module.
*/
return new Double(INVALID_TEXT_FIELD_INPUT_RETURN);
}
}
}
/**
* Validate the minimum file size input.
*
* @throws IllegalArgumentException If the input is empty, invalid, or out
* of range.
* Formatter to handle conversion between String and Integer.
*/
@Messages({
"EncryptionDetectionIngestJobSettingsPanel.minimumFileSizeInput.validationError.text=Minimum file size input must be an integer (in megabytes) of 1 or greater."
})
private void validateMinimumFileSize() throws IllegalArgumentException {
private final class StringIntegerFormatter extends DefaultFormatter {
@Override
public Object stringToValue(String string) throws ParseException {
try {
int minimumFileSize = Integer.valueOf(minimumFileSizeTextbox.getText());
if (minimumFileSize < MINIMUM_FILE_SIZE_INPUT_RANGE_MIN) {
throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), "EncryptionDetectionIngestJobSettingsPanel.minimumFileSizeInput.validationError.text"));
}
return Integer.parseInt(string);
} catch (NumberFormatException ex) {
throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), "EncryptionDetectionIngestJobSettingsPanel.minimumFileSizeInput.validationError.text"));
logger.log(Level.WARNING, String.format("The String input '%s' is not valid for Integer conversion.", string), ex);
/*
* Return a valid number outside the acceptable value range so
* it can still be run through the validator in the file ingest
* module.
*/
return INVALID_TEXT_FIELD_INPUT_RETURN;
}
}
}
@ -116,18 +121,14 @@ final class EncryptionDetectionIngestJobSettingsPanel extends IngestModuleIngest
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
minimumEntropyTextbox = new javax.swing.JTextField();
minimumFileSizeTextbox = new javax.swing.JTextField();
fileSizeMultiplesEnforcedCheckbox = new javax.swing.JCheckBox();
slackFilesAllowedCheckbox = new javax.swing.JCheckBox();
minimumEntropyLabel = new javax.swing.JLabel();
minimumFileSizeLabel = new javax.swing.JLabel();
mbLabel = new javax.swing.JLabel();
detectionSettingsLabel = new javax.swing.JLabel();
minimumEntropyTextbox.setText(org.openide.util.NbBundle.getMessage(EncryptionDetectionIngestJobSettingsPanel.class, "EncryptionDetectionIngestJobSettingsPanel.minimumEntropyTextbox.text")); // NOI18N
minimumFileSizeTextbox.setText(org.openide.util.NbBundle.getMessage(EncryptionDetectionIngestJobSettingsPanel.class, "EncryptionDetectionIngestJobSettingsPanel.minimumFileSizeTextbox.text")); // NOI18N
minimumFileSizeTextbox = new javax.swing.JFormattedTextField();
minimumEntropyTextbox = new javax.swing.JFormattedTextField();
org.openide.awt.Mnemonics.setLocalizedText(fileSizeMultiplesEnforcedCheckbox, org.openide.util.NbBundle.getMessage(EncryptionDetectionIngestJobSettingsPanel.class, "EncryptionDetectionIngestJobSettingsPanel.fileSizeMultiplesEnforcedCheckbox.text")); // NOI18N
@ -142,6 +143,17 @@ final class EncryptionDetectionIngestJobSettingsPanel extends IngestModuleIngest
detectionSettingsLabel.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(detectionSettingsLabel, org.openide.util.NbBundle.getMessage(EncryptionDetectionIngestJobSettingsPanel.class, "EncryptionDetectionIngestJobSettingsPanel.detectionSettingsLabel.text")); // NOI18N
minimumFileSizeTextbox.setFormatterFactory(minimumFileSizeTextFormatterFactory);
minimumFileSizeTextbox.setText(org.openide.util.NbBundle.getMessage(EncryptionDetectionIngestJobSettingsPanel.class, "EncryptionDetectionIngestJobSettingsPanel.minimumFileSizeTextbox.text")); // NOI18N
minimumFileSizeTextbox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
minimumFileSizeTextboxActionPerformed(evt);
}
});
minimumEntropyTextbox.setFormatterFactory(minimumEntropyTextFormatterFactory);
minimumEntropyTextbox.setText(org.openide.util.NbBundle.getMessage(EncryptionDetectionIngestJobSettingsPanel.class, "EncryptionDetectionIngestJobSettingsPanel.minimumEntropyTextbox.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
@ -151,19 +163,17 @@ final class EncryptionDetectionIngestJobSettingsPanel extends IngestModuleIngest
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(slackFilesAllowedCheckbox)
.addComponent(detectionSettingsLabel)
.addComponent(fileSizeMultiplesEnforcedCheckbox)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addComponent(minimumFileSizeLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(minimumFileSizeTextbox, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addComponent(minimumFileSizeTextbox, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(mbLabel))
.addGroup(layout.createSequentialGroup()
.addComponent(minimumEntropyLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(minimumEntropyTextbox, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(mbLabel))
.addComponent(fileSizeMultiplesEnforcedCheckbox))
.addContainerGap(15, Short.MAX_VALUE))
);
layout.setVerticalGroup(
@ -173,13 +183,13 @@ final class EncryptionDetectionIngestJobSettingsPanel extends IngestModuleIngest
.addComponent(detectionSettingsLabel)
.addGap(16, 16, 16)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(minimumEntropyTextbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(minimumEntropyLabel))
.addComponent(minimumEntropyLabel)
.addComponent(minimumEntropyTextbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(minimumFileSizeTextbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(mbLabel)
.addComponent(minimumFileSizeLabel))
.addComponent(minimumFileSizeLabel)
.addComponent(minimumFileSizeTextbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(fileSizeMultiplesEnforcedCheckbox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
@ -188,14 +198,18 @@ final class EncryptionDetectionIngestJobSettingsPanel extends IngestModuleIngest
);
}// </editor-fold>//GEN-END:initComponents
private void minimumFileSizeTextboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_minimumFileSizeTextboxActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_minimumFileSizeTextboxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel detectionSettingsLabel;
private javax.swing.JCheckBox fileSizeMultiplesEnforcedCheckbox;
private javax.swing.JLabel mbLabel;
private javax.swing.JLabel minimumEntropyLabel;
private javax.swing.JTextField minimumEntropyTextbox;
private javax.swing.JFormattedTextField minimumEntropyTextbox;
private javax.swing.JLabel minimumFileSizeLabel;
private javax.swing.JTextField minimumFileSizeTextbox;
private javax.swing.JFormattedTextField minimumFileSizeTextbox;
private javax.swing.JCheckBox slackFilesAllowedCheckbox;
// End of variables declaration//GEN-END:variables
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.