diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageTask.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageTask.java
index 599bf56110..793d90bae3 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageTask.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageTask.java
@@ -107,7 +107,7 @@ class AddImageTask implements Runnable {
try {
synchronized (tskAddImageProcessLock) {
if (!tskAddImageProcessStopped) {
- tskAddImageProcess = currentCase.getSleuthkitCase().makeAddImageProcess(imageDetails.timeZone, true, imageDetails.ignoreFatOrphanFiles, imageWriterPath);
+ tskAddImageProcess = currentCase.getSleuthkitCase().makeAddImageProcess(imageDetails.timeZone, true, imageDetails.ignoreFatOrphanFiles, imageWriterPath, imageDetails.password);
} else {
return;
}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED
index 3e2e6c4199..9e7e2d7e81 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED
@@ -159,6 +159,10 @@ ImageFilePanel.validatePanel.dataSourceOnCDriveError=Warning: Path to multi-user
ImageFilePanel.validatePanel.invalidMD5=Invalid MD5 hash
ImageFilePanel.validatePanel.invalidSHA1=Invalid SHA1 hash
ImageFilePanel.validatePanel.invalidSHA256=Invalid SHA256 hash
+# {0} - imageOpenError
+ImageFilePanel_validatePanel_imageOpenError=
An error occurred while opening the image:{0}
+ImageFilePanel_validatePanel_unknownError=An unknown error occurred while attempting to validate the image
+ImageFilePanel_validatePanel_unknownErrorMsg=
IngestJobInfoPanel.IngestJobTableModel.EndTime.header=End Time
IngestJobInfoPanel.IngestJobTableModel.IngestStatus.header=Ingest Status
IngestJobInfoPanel.IngestJobTableModel.StartTime.header=Start Time
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/ImageDSProcessor.java b/Core/src/org/sleuthkit/autopsy/casemodule/ImageDSProcessor.java
index 0b219c3d4d..c1fef28484 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/ImageDSProcessor.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/ImageDSProcessor.java
@@ -207,7 +207,7 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
this.host = host;
try {
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
- new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, this.host, this.password);
+ new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, this.host);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
final List errors = new ArrayList<>();
@@ -271,7 +271,7 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
// Set up the data source before creating the ingest stream
try {
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
- new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, this.host, this.password);
+ new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, this.host);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
final List errors = new ArrayList<>();
@@ -394,6 +394,7 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
* @param md5 The MD5 hash of the image, may be null.
* @param sha1 The SHA-1 hash of the image, may be null.
* @param sha256 The SHA-256 hash of the image, may be null.
+ * @param password Password for image decryption. May be null.
* @param progressMonitor Progress monitor for reporting progress
* during processing.
* @param callback Callback to call when processing is done.
@@ -517,7 +518,7 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
ingestStream = new DefaultIngestStream();
try {
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
- new String[]{imagePath}, sectorSize, timeZone, "", "", "", deviceId, host, this.password);
+ new String[]{imagePath}, sectorSize, timeZone, "", "", "", deviceId, host);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
final List errors = new ArrayList<>();
@@ -547,7 +548,7 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
// Set up the data source before creating the ingest stream
try {
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
- new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, host, this.password);
+ new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, host);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
final List errors = new ArrayList<>();
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.form
index 2fa29a1a8f..c46749306b 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.form
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.form
@@ -19,116 +19,10 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -136,6 +30,11 @@
+
+
+
+
+
@@ -146,6 +45,11 @@
+
+
+
+
+
@@ -153,6 +57,11 @@
+
+
+
+
+
@@ -160,6 +69,11 @@
+
+
+
+
+
@@ -171,6 +85,11 @@
+
+
+
+
+
@@ -181,6 +100,11 @@
+
+
+
+
+
@@ -190,7 +114,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -198,6 +137,11 @@
+
+
+
+
+
@@ -208,6 +152,11 @@
+
+
+
+
+
@@ -216,6 +165,11 @@
+
+
+
+
+
@@ -224,6 +178,11 @@
+
+
+
+
+
@@ -232,6 +191,11 @@
+
+
+
+
+
@@ -240,6 +204,11 @@
+
+
+
+
+
@@ -248,6 +217,11 @@
+
+
+
+
+
@@ -256,6 +230,11 @@
+
+
+
+
+
@@ -264,6 +243,11 @@
+
+
+
+
+
@@ -272,6 +256,11 @@
+
+
+
+
+
@@ -279,6 +268,11 @@
+
+
+
+
+
@@ -286,6 +280,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.java
index 7be2a01c95..7cf1f85183 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.java
@@ -18,9 +18,14 @@
*/
package org.sleuthkit.autopsy.casemodule;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.io.File;
import java.util.Calendar;
import java.util.List;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
@@ -32,11 +37,14 @@ import org.apache.commons.lang3.StringUtils;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
import org.sleuthkit.autopsy.coreutils.DriveUtils;
+import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PathValidator;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.guiutils.JFileChooserFactory;
import org.sleuthkit.datamodel.HashUtility;
+import org.sleuthkit.datamodel.SleuthkitJNI;
+import org.sleuthkit.datamodel.SleuthkitJNI.TestOpenImageResult;
/**
* Panel for adding an image file such as .img, .E0x, .00x, etc. Allows the user
@@ -44,8 +52,10 @@ import org.sleuthkit.datamodel.HashUtility;
* files in FAT32.
*/
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
-public class ImageFilePanel extends JPanel implements DocumentListener {
+public class ImageFilePanel extends JPanel {
+ private static final Logger logger = Logger.getLogger(AddImageTask.class.getName());
+
private static final long serialVersionUID = 1L;
private static final String PROP_LASTIMAGE_PATH = "LBL_LastImage_PATH"; //NON-NLS
private static final String[] SECTOR_SIZE_CHOICES = {"Auto Detect", "512", "1024", "2048", "4096"};
@@ -53,6 +63,11 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
private JFileChooser fileChooser;
private final String contextName;
private final List fileChooserFilters;
+
+ private static int VALIDATE_TIMEOUT_MILLIS = 1500;
+ static ScheduledThreadPoolExecutor delayedValidationService = new ScheduledThreadPoolExecutor(1, new ThreadFactoryBuilder().setNameFormat("ImageFilePanel delayed validation").build());
+
+ private Future validateAction = null;
/**
* Creates new form ImageFilePanel
@@ -105,11 +120,17 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
*/
public static synchronized ImageFilePanel createInstance(String context, List fileChooserFilters) {
ImageFilePanel instance = new ImageFilePanel(context, fileChooserFilters);
+ DocumentListener delayedValidationListener = instance.new DelayedValidationDocListener();
+
// post-constructor initialization of listener support without leaking references of uninitialized objects
- instance.getPathTextField().getDocument().addDocumentListener(instance);
- instance.getMd5TextFieldField().getDocument().addDocumentListener(instance);
- instance.getSha1TextField().getDocument().addDocumentListener(instance);
- instance.getSha256TextField().getDocument().addDocumentListener(instance);
+ for (JTextField textField: List.of(
+ instance.getPathTextField(),
+ instance.getMd5TextFieldField(),
+ instance.getSha1TextField(),
+ instance.getSha256TextField(),
+ instance.getPasswordTextField())) {
+ textField.getDocument().addDocumentListener(delayedValidationListener);
+ }
return instance;
}
@@ -155,6 +176,7 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
*/
// //GEN-BEGIN:initComponents
private void initComponents() {
+ java.awt.GridBagConstraints gridBagConstraints;
pathLabel = new javax.swing.JLabel();
browseButton = new javax.swing.JButton();
@@ -175,11 +197,22 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
hashValuesNoteLabel = new javax.swing.JLabel();
passwordLabel = new javax.swing.JLabel();
passwordTextField = new javax.swing.JTextField();
+ javax.swing.JPanel spacer = new javax.swing.JPanel();
setMinimumSize(new java.awt.Dimension(0, 65));
setPreferredSize(new java.awt.Dimension(403, 65));
+ setLayout(new java.awt.GridBagLayout());
org.openide.awt.Mnemonics.setLocalizedText(pathLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.pathLabel.text")); // NOI18N
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.gridwidth = 3;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
+ add(pathLabel, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.browseButton.text")); // NOI18N
browseButton.addActionListener(new java.awt.event.ActionListener() {
@@ -187,136 +220,211 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
browseButtonActionPerformed(evt);
}
});
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 2;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 5);
+ add(browseButton, gridBagConstraints);
pathTextField.setText(org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.pathTextField.text")); // NOI18N
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.gridwidth = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
+ add(pathTextField, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(timeZoneLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.timeZoneLabel.text")); // NOI18N
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 3;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
+ add(timeZoneLabel, gridBagConstraints);
timeZoneComboBox.setMaximumRowCount(30);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 3;
+ gridBagConstraints.gridwidth = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 5);
+ add(timeZoneComboBox, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(noFatOrphansCheckbox, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.noFatOrphansCheckbox.text")); // NOI18N
noFatOrphansCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.noFatOrphansCheckbox.toolTipText")); // NOI18N
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.gridwidth = 3;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
+ add(noFatOrphansCheckbox, gridBagConstraints);
errorLabel.setForeground(new java.awt.Color(255, 0, 0));
org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.errorLabel.text")); // NOI18N
+ errorLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP);
+ errorLabel.setMaximumSize(new java.awt.Dimension(500, 60));
+ errorLabel.setMinimumSize(new java.awt.Dimension(200, 20));
+ errorLabel.setPreferredSize(new java.awt.Dimension(200, 60));
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 11;
+ gridBagConstraints.gridwidth = 3;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
+ add(errorLabel, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(sectorSizeLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.sectorSizeLabel.text")); // NOI18N
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 4;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
+ add(sectorSizeLabel, gridBagConstraints);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 4;
+ gridBagConstraints.gridwidth = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 5);
+ add(sectorSizeComboBox, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(sha256HashLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.sha256HashLabel.text")); // NOI18N
sha256HashLabel.setEnabled(false);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 9;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
+ add(sha256HashLabel, gridBagConstraints);
sha256HashTextField.setText(org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.sha256HashTextField.text")); // NOI18N
sha256HashTextField.setEnabled(false);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 9;
+ gridBagConstraints.gridwidth = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 5);
+ add(sha256HashTextField, gridBagConstraints);
sha1HashTextField.setText(org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.sha1HashTextField.text")); // NOI18N
sha1HashTextField.setEnabled(false);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 8;
+ gridBagConstraints.gridwidth = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 5);
+ add(sha1HashTextField, gridBagConstraints);
md5HashTextField.setText(org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.md5HashTextField.text")); // NOI18N
md5HashTextField.setEnabled(false);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 7;
+ gridBagConstraints.gridwidth = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 5);
+ add(md5HashTextField, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(sha1HashLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.sha1HashLabel.text")); // NOI18N
sha1HashLabel.setEnabled(false);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 8;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
+ add(sha1HashLabel, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(md5HashLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.md5HashLabel.text")); // NOI18N
md5HashLabel.setEnabled(false);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 7;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
+ add(md5HashLabel, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(hashValuesLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.hashValuesLabel.text")); // NOI18N
hashValuesLabel.setEnabled(false);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 6;
+ gridBagConstraints.gridwidth = 3;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
+ add(hashValuesLabel, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(hashValuesNoteLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.hashValuesNoteLabel.text")); // NOI18N
hashValuesNoteLabel.setEnabled(false);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 10;
+ gridBagConstraints.gridwidth = 3;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
+ add(hashValuesNoteLabel, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(passwordLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.passwordLabel.text")); // NOI18N
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 5;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
+ add(passwordLabel, gridBagConstraints);
passwordTextField.setText(org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.passwordTextField.text")); // NOI18N
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 5;
+ gridBagConstraints.gridwidth = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 5);
+ add(passwordTextField, gridBagConstraints);
- javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
- this.setLayout(layout);
- layout.setHorizontalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addComponent(pathTextField)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(browseButton)
- .addGap(2, 2, 2))
- .addGroup(layout.createSequentialGroup()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(pathLabel)
- .addComponent(noFatOrphansCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 262, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGap(0, 368, Short.MAX_VALUE))
- .addGroup(layout.createSequentialGroup()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(errorLabel)
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addComponent(timeZoneLabel)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 455, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addComponent(sectorSizeLabel)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(sectorSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 455, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addComponent(md5HashLabel)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(md5HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 455, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addComponent(sha1HashLabel)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(sha1HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 455, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addComponent(sha256HashLabel)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(sha256HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 455, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addComponent(hashValuesNoteLabel)
- .addGroup(layout.createSequentialGroup()
- .addComponent(passwordLabel)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(passwordTextField))
- .addComponent(hashValuesLabel))
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ javax.swing.GroupLayout spacerLayout = new javax.swing.GroupLayout(spacer);
+ spacer.setLayout(spacerLayout);
+ spacerLayout.setHorizontalGroup(
+ spacerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 0, Short.MAX_VALUE)
);
- layout.setVerticalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addComponent(pathLabel)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(browseButton)
- .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(noFatOrphansCheckbox)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(timeZoneLabel))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(sectorSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(sectorSizeLabel))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(passwordLabel)
- .addComponent(passwordTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(hashValuesLabel)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(md5HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(md5HashLabel))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(sha1HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(sha1HashLabel))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(sha256HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(sha256HashLabel))
- .addGap(18, 18, 18)
- .addComponent(hashValuesNoteLabel)
- .addGap(18, 18, 18)
- .addComponent(errorLabel)
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ spacerLayout.setVerticalGroup(
+ spacerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 0, Short.MAX_VALUE)
);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 12;
+ gridBagConstraints.weighty = 1.0;
+ add(spacer, gridBagConstraints);
}// //GEN-END:initComponents
@NbBundle.Messages({"ImageFilePanel.000.confirmationMessage=The selected file"
@@ -478,7 +586,12 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
"ImageFilePanel.validatePanel.dataSourceOnCDriveError=Warning: Path to multi-user data source is on \"C:\" drive",
"ImageFilePanel.validatePanel.invalidMD5=Invalid MD5 hash",
"ImageFilePanel.validatePanel.invalidSHA1=Invalid SHA1 hash",
- "ImageFilePanel.validatePanel.invalidSHA256=Invalid SHA256 hash",})
+ "ImageFilePanel.validatePanel.invalidSHA256=Invalid SHA256 hash",
+ "# {0} - imageOpenError",
+ "ImageFilePanel_validatePanel_imageOpenError=An error occurred while opening the image:{0}
",
+ "ImageFilePanel_validatePanel_unknownErrorMsg=",
+ "ImageFilePanel_validatePanel_unknownError=An unknown error occurred while attempting to validate the image
"
+ })
public boolean validatePanel() {
errorLabel.setVisible(false);
@@ -488,31 +601,59 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
}
if (!StringUtils.isBlank(getMd5()) && !HashUtility.isValidMd5Hash(getMd5())) {
- errorLabel.setVisible(true);
- errorLabel.setText(Bundle.ImageFilePanel_validatePanel_invalidMD5());
+ showError(Bundle.ImageFilePanel_validatePanel_invalidMD5());
return false;
}
if (!StringUtils.isBlank(getSha1()) && !HashUtility.isValidSha1Hash(getSha1())) {
- errorLabel.setVisible(true);
- errorLabel.setText(Bundle.ImageFilePanel_validatePanel_invalidSHA1());
+ showError(Bundle.ImageFilePanel_validatePanel_invalidSHA1());
return false;
}
if (!StringUtils.isBlank(getSha256()) && !HashUtility.isValidSha256Hash(getSha256())) {
- errorLabel.setVisible(true);
- errorLabel.setText(Bundle.ImageFilePanel_validatePanel_invalidSHA256());
+ showError(Bundle.ImageFilePanel_validatePanel_invalidSHA256());
return false;
}
if (!PathValidator.isValidForCaseType(path, Case.getCurrentCase().getCaseType())) {
- errorLabel.setVisible(true);
- errorLabel.setText(Bundle.ImageFilePanel_validatePanel_dataSourceOnCDriveError());
+ showError(Bundle.ImageFilePanel_validatePanel_dataSourceOnCDriveError());
+ }
+
+ try {
+ String password = this.getPassword();
+ TestOpenImageResult testResult = SleuthkitJNI.testOpenImage(path, password);
+ if (!testResult.wasSuccessful()) {
+ showError(Bundle.ImageFilePanel_validatePanel_imageOpenError(
+ StringUtils.defaultIfBlank(
+ testResult.getMessage(),
+ Bundle.ImageFilePanel_validatePanel_unknownErrorMsg())));
+ return false;
+ }
+ } catch (Throwable t) {
+ logger.log(Level.SEVERE, "An unknown error occurred test opening image: " + path, t);
+ showError(Bundle.ImageFilePanel_validatePanel_unknownError());
+ return false;
}
return true;
}
+ /**
+ * Show an error message if error message is non-empty. Otherwise, hide
+ * error message.
+ *
+ * @param errorMessage The error message to show.
+ */
+ private void showError(String errorMessage) {
+ if (StringUtils.isNotBlank(errorMessage)) {
+ errorLabel.setVisible(true);
+ errorLabel.setText(errorMessage);
+ } else {
+ errorLabel.setVisible(false);
+ errorLabel.setText("");
+ }
+ }
+
private boolean isImagePathValid() {
String path = getContentPaths();
@@ -538,21 +679,6 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
}
}
- @Override
- public void insertUpdate(DocumentEvent e) {
- updateHelper();
- }
-
- @Override
- public void removeUpdate(DocumentEvent e) {
- updateHelper();
- }
-
- @Override
- public void changedUpdate(DocumentEvent e) {
- updateHelper();
- }
-
/**
* Update functions are called by the pathTextField which has this set as
* it's DocumentEventListener. Each update function fires a property change
@@ -578,4 +704,40 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
public void select() {
pathTextField.requestFocusInWindow();
}
+
+ /**
+ * This class validates on a delay canceling any tasks previously scheduled
+ * so that password validation doesn't lock up the system.
+ */
+ private class DelayedValidationDocListener implements DocumentListener {
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ delayValidate();
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ delayValidate();
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ delayValidate();
+ }
+
+ private synchronized void delayValidate() {
+ if (ImageFilePanel.this.validateAction != null) {
+ ImageFilePanel.this.validateAction.cancel(true);
+ }
+
+ ImageFilePanel.this.validateAction = ImageFilePanel.this.delayedValidationService.schedule(
+ () -> {
+ ImageFilePanel.this.updateHelper();
+ return null;
+ },
+ VALIDATE_TIMEOUT_MILLIS,
+ TimeUnit.MILLISECONDS);
+ }
+ }
}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskDSProcessor.java b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskDSProcessor.java
index 5843220af4..e63943a456 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskDSProcessor.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskDSProcessor.java
@@ -173,7 +173,7 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
try {
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
new String[]{drivePath}, sectorSize,
- timeZone, null, null, null, deviceId, this.host, this.password);
+ timeZone, null, null, null, deviceId, this.host);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error adding local disk with path " + drivePath + " to database", ex);
final List errors = new ArrayList<>();
diff --git a/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/AddMultipleImagesTask.java b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/AddMultipleImagesTask.java
index 4cf0503679..95484341c7 100644
--- a/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/AddMultipleImagesTask.java
+++ b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/AddMultipleImagesTask.java
@@ -128,7 +128,7 @@ class AddMultipleImagesTask implements Runnable {
for (String imageFilePath : imageFilePaths) {
try {
currentImage = SleuthkitJNI.addImageToDatabase(currentCase.getSleuthkitCase(), new String[]{imageFilePath},
- 0, timeZone, "", "", "", deviceId, host, null);
+ 0, timeZone, "", "", "", deviceId, host);
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Error adding image " + imageFilePath + " to database", ex);
errorMessages.add(Bundle.AddMultipleImagesTask_imageError(imageFilePath));
diff --git a/Core/src/org/sleuthkit/autopsy/report/modules/portablecase/PortableCaseReportModule.java b/Core/src/org/sleuthkit/autopsy/report/modules/portablecase/PortableCaseReportModule.java
index 137850ee17..860739f91b 100644
--- a/Core/src/org/sleuthkit/autopsy/report/modules/portablecase/PortableCaseReportModule.java
+++ b/Core/src/org/sleuthkit/autopsy/report/modules/portablecase/PortableCaseReportModule.java
@@ -1230,7 +1230,7 @@ public class PortableCaseReportModule implements ReportModule {
if (content instanceof Image) {
Image image = (Image) content;
newContent = portableSkCase.addImage(image.getType(), image.getSsize(), image.getSize(), image.getName(),
- new ArrayList<>(), image.getTimeZone(), md5, sha1, sha256, image.getDeviceId(), newHost, null, trans);
+ new ArrayList<>(), image.getTimeZone(), md5, sha1, sha256, image.getDeviceId(), newHost, trans);
} else if (content instanceof VolumeSystem) {
VolumeSystem vs = (VolumeSystem) content;
newContent = portableSkCase.addVolumeSystem(parentId, vs.getType(), vs.getOffset(), vs.getBlockSize(), trans);