User can enter image data source hashes

This commit is contained in:
Richard Cordovano 2018-12-08 15:13:22 -05:00
parent 16eed89b82
commit e213eb04d3
8 changed files with 174 additions and 84 deletions

View File

@ -47,6 +47,9 @@ class AddImageTask implements Runnable {
private final String timeZone;
private final ImageWriterSettings imageWriterSettings;
private final boolean ignoreFatOrphanFiles;
private final String md5;
private final String sha1;
private final String sha256;
private final DataSourceProcessorProgressMonitor progressMonitor;
private final DataSourceProcessorCallback callback;
private boolean criticalErrorOccurred;
@ -82,6 +85,9 @@ class AddImageTask implements Runnable {
* java.util.TimeZone.getID.
* @param ignoreFatOrphanFiles Whether to parse orphans if the image has a
* FAT filesystem.
* @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 imageWriterPath Path that a copy of the image should be
* written to. Use empty string to disable image
* writing
@ -89,13 +95,16 @@ class AddImageTask implements Runnable {
* processing.
* @param callback Callback to call when processing is done.
*/
AddImageTask(String deviceId, String imagePath, int sectorSize, String timeZone, boolean ignoreFatOrphanFiles, ImageWriterSettings imageWriterSettings,
AddImageTask(String deviceId, String imagePath, int sectorSize, String timeZone, boolean ignoreFatOrphanFiles, String md5, String sha1, String sha256, ImageWriterSettings imageWriterSettings,
DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
this.deviceId = deviceId;
this.imagePath = imagePath;
this.sectorSize = sectorSize;
this.timeZone = timeZone;
this.ignoreFatOrphanFiles = ignoreFatOrphanFiles;
this.md5 = md5;
this.sha1 = sha1;
this.sha256 = sha256;
this.imageWriterSettings = imageWriterSettings;
this.callback = callback;
this.progressMonitor = progressMonitor;
@ -111,7 +120,7 @@ class AddImageTask implements Runnable {
try {
currentCase = Case.getCurrentCaseThrows();
} catch (NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "Exception while getting open case.", ex);
logger.log(Level.SEVERE, "Failed to add image data source, no current case", ex);
return;
}
progressMonitor.setIndeterminate(true);
@ -125,11 +134,10 @@ class AddImageTask implements Runnable {
try {
currentCase.getSleuthkitCase().acquireSingleUserCaseWriteLock();
synchronized (tskAddImageProcessLock) {
if (!tskAddImageProcessStopped) { //if we have already cancelled don't bother making an addImageProcess
tskAddImageProcess = currentCase.getSleuthkitCase().makeAddImageProcess(timeZone, true,
ignoreFatOrphanFiles, imageWriterPath);
if (!tskAddImageProcessStopped) {
tskAddImageProcess = currentCase.getSleuthkitCase().makeAddImageProcess(timeZone, true, ignoreFatOrphanFiles, imageWriterPath);
} else {
return; //we have already cancelled so we do not want to add the image, returning will execute the finally block
return;
}
}
Thread progressUpdateThread = new Thread(new ProgressUpdater(progressMonitor, tskAddImageProcess));
@ -139,7 +147,6 @@ class AddImageTask implements Runnable {
commitOrRevertAddImageProcess(currentCase, errorMessages, newDataSources);
progressMonitor.setProgress(100);
} finally {
currentCase.getSleuthkitCase().releaseSingleUserCaseWriteLock();
DataSourceProcessorCallback.DataSourceProcessorResult result;
if (criticalErrorOccurred) {
result = DataSourceProcessorResult.CRITICAL_ERRORS;
@ -148,6 +155,7 @@ class AddImageTask implements Runnable {
} else {
result = DataSourceProcessorResult.NO_ERRORS;
}
currentCase.getSleuthkitCase().releaseSingleUserCaseWriteLock();
callback.done(result, errorMessages, newDataSources);
}
}
@ -233,6 +241,39 @@ class AddImageTask implements Runnable {
ImageWriterService.createImageWriter(imageId, imageWriterSettings);
}
newDataSources.add(newImage);
try {
newImage.setMD5(md5);
} catch (TskCoreException | TskDataException ex) {
/*
* Treat both exceptions as the same since this is a
* new image and the hash should not already be set.
*/
logger.log(Level.SEVERE, String.format("Failed to add MD5 hash for image data source %s (objId=%d)", newImage.getName(), newImage.getId()), ex);
errorMessages.add(ex.getMessage());
criticalErrorOccurred = true;
}
try {
newImage.setSha1(sha1);
} catch (TskCoreException | TskDataException ex) {
/*
* Treat both exceptions as the same since this is a
* new image and the hash should not already be set.
*/
logger.log(Level.SEVERE, String.format("Failed to add SHA1 hash for image data source %s (objId=%d)", newImage.getName(), newImage.getId()), ex);
errorMessages.add(ex.getMessage());
criticalErrorOccurred = true;
}
try {
newImage.setSha256(sha256);
} catch (TskCoreException | TskDataException ex) {
/*
* Treat both exceptions as the same since this is a
* new image and the hash should not already be set.
*/
logger.log(Level.SEVERE, String.format("Failed to add SHA256 for image data source %s (objId=%d)", newImage.getName(), newImage.getId()), ex);
errorMessages.add(ex.getMessage());
criticalErrorOccurred = true;
}
} else {
String errorMessage = String.format("Error commiting adding image %s to the case database, no object id returned", imagePath); //NON-NLS
logger.log(Level.SEVERE, errorMessage);

View File

@ -24,7 +24,7 @@ AddImageErrorsDialog.copyButton.text=Copy
AddImageErrorsDialog.closeButton.toolTipText=Close this window
AddImageErrorsDialog.closeButton.text=Close
OpenRecentCasePanel.openButton.text=Open
ImageFilePanel.pathLabel.text=Browse for an image file:
ImageFilePanel.pathLabel.text=Path:
ImageFilePanel.browseButton.text=Browse
ImageFilePanel.pathTextField.text=
MissingImageDialog.selectButton.text=Select Image
@ -201,7 +201,6 @@ MultiUserCasesPanel.bnOpenSingleUserCase.text=Open Single-User Case...
CueBannerPanel.newCaseButton.text=
MultiUserCasesPanel.searchLabel.text=Select any case and start typing to search by case name
MultiUserCasesPanel.cancelButton.text=Cancel
ImageFilePanel.pathErrorLabel.text=Error Label
ImageFilePanel.sectorSizeLabel.text=Sector size:
LocalDiskPanel.sectorSizeLabel.text=Sector Size:
LocalFilesPanel.displayNameLabel.text=Logical File Set Display Name: Default
@ -239,3 +238,4 @@ ImageFilePanel.sha256HashLabel.text=SHA-256 hash:
ImageFilePanel.sha256HashTextField.text=
ImageFilePanel.sha1HashTextField.text=
ImageFilePanel.md5HashTextField.text=
ImageFilePanel.errorLabel.text=Error Label

View File

@ -186,7 +186,6 @@ OpenMultiUserCasePanel.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
OpenMultiUserCasePanel.jLabel1.text=\u6700\u8fd1\u958b\u3044\u305f\u30d5\u30a1\u30a4\u30eb
CueBannerPanel.newCaseLabel.text=\u65b0\u898f\u30b1\u30fc\u30b9\u3092\u4f5c\u6210
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

View File

@ -41,9 +41,10 @@ import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor;
* 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=AutoIngestDataSourceProcessor.class)}
@ServiceProviders(value = {
@ServiceProvider(service = DataSourceProcessor.class)
,
@ServiceProvider(service = AutoIngestDataSourceProcessor.class)}
)
public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSourceProcessor {
@ -66,6 +67,9 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
private int sectorSize;
private String timeZone;
private boolean ignoreFatOrphanFiles;
private String md5;
private String sha1;
private String sha256;
private boolean setDataSourceOptionsCalled;
static {
@ -74,7 +78,7 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
filtersList.add(encaseFilter);
allExt.addAll(GeneralFilter.RAW_IMAGE_EXTS);
allExt.addAll(GeneralFilter.ENCASE_IMAGE_EXTS);
if(!System.getProperty("os.name").toLowerCase().contains("mac")){
if (!System.getProperty("os.name").toLowerCase().contains("mac")) {
filtersList.add(virtualMachineFilter);
allExt.addAll(GeneralFilter.VIRTUAL_MACHINE_EXTS);
}
@ -172,8 +176,20 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
sectorSize = configPanel.getSectorSize();
timeZone = configPanel.getTimeZone();
ignoreFatOrphanFiles = configPanel.getNoFatOrphans();
md5 = configPanel.getMd5();
if (md5.isEmpty()) {
md5 = null;
}
sha1 = configPanel.getSha1();
if (sha1.isEmpty()) {
sha1 = null;
}
sha256 = configPanel.getSha256();
if (sha256.isEmpty()) {
sha256 = null;
}
}
run(deviceId, imagePath, sectorSize, timeZone, ignoreFatOrphanFiles, progressMonitor, callback);
run(deviceId, imagePath, sectorSize, timeZone, ignoreFatOrphanFiles, md5, sha1, sha256, progressMonitor, callback);
}
/**
@ -198,7 +214,7 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
* @param callback Callback to call when processing is done.
*/
public void run(String deviceId, String imagePath, String timeZone, boolean ignoreFatOrphanFiles, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
run(deviceId, imagePath, 0, timeZone, ignoreFatOrphanFiles, progressMonitor, callback);
run(deviceId, imagePath, 0, timeZone, ignoreFatOrphanFiles, null, null, null, progressMonitor, callback);
}
/**
@ -219,12 +235,15 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
* java.util.TimeZone.getID.
* @param ignoreFatOrphanFiles Whether to parse orphans if the image has a
* FAT filesystem.
* @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 progressMonitor Progress monitor for reporting progress
* during processing.
* @param callback Callback to call when processing is done.
*/
private void run(String deviceId, String imagePath, int sectorSize, String timeZone, boolean ignoreFatOrphanFiles, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
addImageTask = new AddImageTask(deviceId, imagePath, sectorSize, timeZone, ignoreFatOrphanFiles, null, progressMonitor, callback);
private void run(String deviceId, String imagePath, int sectorSize, String timeZone, boolean ignoreFatOrphanFiles, String md5, String sha1, String sha256, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
addImageTask = new AddImageTask(deviceId, imagePath, sectorSize, timeZone, ignoreFatOrphanFiles, md5, sha1, sha256, null, progressMonitor, callback);
new Thread(addImageTask).start();
}
@ -296,7 +315,7 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
this.timeZone = Calendar.getInstance().getTimeZone().getID();
this.ignoreFatOrphanFiles = false;
setDataSourceOptionsCalled = true;
run(deviceId, dataSourcePath.toString(), sectorSize, timeZone, ignoreFatOrphanFiles, progressMonitor, callBack);
run(deviceId, dataSourcePath.toString(), sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, progressMonitor, callBack);
}
/**

View File

@ -33,7 +33,7 @@
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="pathLabel" min="-2" max="-2" attributes="0"/>
<Component id="pathErrorLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="errorLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="noFatOrphansCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
@ -54,7 +54,7 @@
<Component id="sha1HashTextField" min="-2" pref="287" max="-2" attributes="0"/>
<Component id="sha256HashTextField" min="-2" pref="455" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="-237" max="32767" attributes="0"/>
<EmptySpace pref="11" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -67,8 +67,6 @@
<Component id="browseButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="pathTextField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
<Component id="pathErrorLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="noFatOrphansCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
@ -96,7 +94,9 @@
<Component id="sha256HashTextField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="sha256HashLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="45" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -154,13 +154,13 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="pathErrorLabel">
<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="ImageFilePanel.pathErrorLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="ImageFilePanel.errorLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>

View File

@ -21,23 +21,21 @@ package org.sleuthkit.autopsy.casemodule;
import java.io.File;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Level;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileFilter;
import org.apache.commons.lang3.StringUtils;
import org.openide.util.NbBundle;
import static org.sleuthkit.autopsy.casemodule.Bundle.*;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
import org.sleuthkit.autopsy.coreutils.DriveUtils;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PathValidator;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.datamodel.HashUtility;
/**
* Panel for adding an image file such as .img, .E0x, .00x, etc. Allows the user
@ -47,15 +45,10 @@ import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
public class ImageFilePanel extends JPanel implements DocumentListener {
private static final Logger logger = Logger.getLogger(ImageFilePanel.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"};
private final JFileChooser fileChooser = new JFileChooser();
/**
* Externally supplied name is used to store settings
*/
private final String contextName;
/**
@ -79,7 +72,7 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
}
sectorSizeComboBox.setSelectedIndex(0);
pathErrorLabel.setVisible(false);
errorLabel.setVisible(false);
fileChooser.setDragEnabled(false);
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
@ -117,10 +110,29 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
public static synchronized ImageFilePanel createInstance(String context, List<FileFilter> fileChooserFilters) {
ImageFilePanel instance = new ImageFilePanel(context, fileChooserFilters);
// post-constructor initialization of listener support without leaking references of uninitialized objects
instance.pathTextField.getDocument().addDocumentListener(instance);
instance.getPathTextField().getDocument().addDocumentListener(instance);
instance.getMd5TextFieldField().getDocument().addDocumentListener(instance);
instance.getSha1TextField().getDocument().addDocumentListener(instance);
instance.getSha256TextField().getDocument().addDocumentListener(instance);
return instance;
}
private JTextField getPathTextField() {
return pathTextField;
}
private JTextField getMd5TextFieldField() {
return md5HashTextField;
}
private JTextField getSha1TextField() {
return sha1HashTextField;
}
private JTextField getSha256TextField() {
return sha256HashTextField;
}
/**
* 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
@ -135,7 +147,7 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
timeZoneLabel = new javax.swing.JLabel();
timeZoneComboBox = new javax.swing.JComboBox<>();
noFatOrphansCheckbox = new javax.swing.JCheckBox();
pathErrorLabel = new javax.swing.JLabel();
errorLabel = new javax.swing.JLabel();
sectorSizeLabel = new javax.swing.JLabel();
sectorSizeComboBox = new javax.swing.JComboBox<>();
sha256HashLabel = new javax.swing.JLabel();
@ -166,8 +178,8 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
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
pathErrorLabel.setForeground(new java.awt.Color(255, 0, 0));
org.openide.awt.Mnemonics.setLocalizedText(pathErrorLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.pathErrorLabel.text")); // NOI18N
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
org.openide.awt.Mnemonics.setLocalizedText(sectorSizeLabel, org.openide.util.NbBundle.getMessage(ImageFilePanel.class, "ImageFilePanel.sectorSizeLabel.text")); // NOI18N
@ -195,7 +207,7 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(pathLabel)
.addComponent(pathErrorLabel)
.addComponent(errorLabel)
.addComponent(noFatOrphansCheckbox))
.addGap(0, 0, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
@ -212,7 +224,7 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
.addComponent(md5HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 231, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(sha1HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 287, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(sha256HashTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 455, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap(11, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -222,8 +234,6 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
.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))
.addGap(3, 3, 3)
.addComponent(pathErrorLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(noFatOrphansCheckbox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
@ -246,7 +256,9 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
.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))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGap(18, 18, 18)
.addComponent(errorLabel)
.addContainerGap(45, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
@ -282,10 +294,10 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton browseButton;
private javax.swing.JLabel errorLabel;
private javax.swing.JLabel md5HashLabel;
private javax.swing.JTextField md5HashTextField;
private javax.swing.JCheckBox noFatOrphansCheckbox;
private javax.swing.JLabel pathErrorLabel;
private javax.swing.JLabel pathLabel;
private javax.swing.JTextField pathTextField;
private javax.swing.JComboBox<String> sectorSizeComboBox;
@ -340,6 +352,18 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
return noFatOrphansCheckbox.isSelected();
}
String getMd5() {
return this.md5HashTextField.getText();
}
String getSha1() {
return this.sha1HashTextField.getText();
}
String getSha256() {
return this.sha256HashTextField.getText();
}
public void reset() {
//reset the UI elements to default
pathTextField.setText(null);
@ -350,30 +374,43 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
*
* @return true if a proper image has been selected, false otherwise
*/
@NbBundle.Messages({"ImageFilePanel.pathValidation.dataSourceOnCDriveError=Warning: Path to multi-user data source is on \"C:\" drive",
"ImageFilePanel.pathValidation.getOpenCase.Error=Warning: Exception while getting open case."
})
@NbBundle.Messages({
"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",})
public boolean validatePanel() {
pathErrorLabel.setVisible(false);
errorLabel.setVisible(false);
String path = getContentPaths();
if (StringUtils.isBlank(path)) {
if (StringUtils.isBlank(path) || (!(new File(path).isFile() || DriveUtils.isPhysicalDrive(path) || DriveUtils.isPartition(path)))) {
return false;
}
// Display warning if there is one (but don't disable "next" button)
try {
if (false == PathValidator.isValidForMultiUserCase(path, Case.getCurrentCaseThrows().getCaseType())) {
pathErrorLabel.setVisible(true);
pathErrorLabel.setText(Bundle.ImageFilePanel_pathValidation_dataSourceOnCDriveError());
}
} catch (NoCurrentCaseException ex) {
pathErrorLabel.setVisible(true);
pathErrorLabel.setText(Bundle.ImageFilePanel_pathValidation_getOpenCase_Error());
if (!StringUtils.isBlank(getMd5()) && !HashUtility.isValidMd5Hash(getMd5())) {
errorLabel.setVisible(true);
errorLabel.setText(Bundle.ImageFilePanel_validatePanel_invalidMD5());
return false;
}
return new File(path).isFile()
|| DriveUtils.isPhysicalDrive(path)
|| DriveUtils.isPartition(path);
if (!StringUtils.isBlank(getSha1()) && !HashUtility.isValidSha1Hash(getSha1())) {
errorLabel.setVisible(true);
errorLabel.setText(Bundle.ImageFilePanel_validatePanel_invalidSHA1());
return false;
}
if (!StringUtils.isBlank(getSha256()) && !HashUtility.isValidSha256Hash(getSha256())) {
errorLabel.setVisible(true);
errorLabel.setText(Bundle.ImageFilePanel_validatePanel_invalidSHA256());
return false;
}
if (!PathValidator.isValidForMultiUserCase(path, Case.getCurrentCase().getCaseType())) {
errorLabel.setVisible(true);
errorLabel.setText(Bundle.ImageFilePanel_validatePanel_dataSourceOnCDriveError());
}
return true;
}
public void storeSettings() {
@ -416,12 +453,7 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
"ImageFilePanel.moduleErr.msg=A module caused an error listening to ImageFilePanel updates."
+ " See log to determine which module. Some data could be incomplete.\n"})
private void updateHelper() {
try {
firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
} catch (Exception e) {
logger.log(Level.SEVERE, "ImageFilePanel listener threw exception", e); //NON-NLS
MessageNotifyUtil.Notify.error(ImageFilePanel_moduleErr(), ImageFilePanel_moduleErr_msg());
}
firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
}
/**

View File

@ -139,7 +139,7 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
imageWriterSettings = null;
}
}
addDiskTask = new AddImageTask(deviceId, drivePath, sectorSize, timeZone, ignoreFatOrphanFiles, imageWriterSettings, progressMonitor, callback);
addDiskTask = new AddImageTask(deviceId, drivePath, sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, imageWriterSettings, progressMonitor, callback);
new Thread(addDiskTask).start();
}
@ -191,7 +191,7 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
* @param callback Callback to call when processing is done.
*/
private void run(String deviceId, String drivePath, int sectorSize, String timeZone, boolean ignoreFatOrphanFiles, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
addDiskTask = new AddImageTask(deviceId, drivePath, sectorSize, timeZone, ignoreFatOrphanFiles, imageWriterSettings, progressMonitor, callback);
addDiskTask = new AddImageTask(deviceId, drivePath, sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, imageWriterSettings, progressMonitor, callback);
new Thread(addDiskTask).start();
}

View File

@ -25,7 +25,6 @@ import java.util.List;
import java.util.logging.Level;
import javax.xml.bind.DatatypeConverter;
import java.util.Arrays;
import org.openide.util.Exceptions;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.DataSourceIngestModule;
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
@ -266,12 +265,12 @@ public class DataSourceIntegrityIngestModule implements DataSourceIngestModule {
for (HashData hashData:hashDataList) {
if (hashData.storedHash.equals(hashData.calculatedHash)) {
hashResults += Bundle.DataSourceIntegrityIngestModule_process_hashMatch(hashData.type.name);
hashResults += Bundle.DataSourceIntegrityIngestModule_process_hashMatch(hashData.type.name) + " ";
} else {
verified = false;
hashResults += Bundle.DataSourceIntegrityIngestModule_process_hashNonMatch(hashData.type.name);
hashResults += Bundle.DataSourceIntegrityIngestModule_process_hashNonMatch(hashData.type.name) + " ";
artifactComment += Bundle.DataSourceIntegrityIngestModule_process_hashFailedForArtifact(hashData.type.name,
hashData.calculatedHash, hashData.storedHash);
hashData.calculatedHash, hashData.storedHash) + " ";
}
hashResults += Bundle.DataSourceIntegrityIngestModule_process_hashList(hashData.calculatedHash, hashData.storedHash);
}