mirror of
https://github.com/elisspace/autopsy.git
synced 2026-10-04 00:09:53 +00:00
Implementation of hash database name and path filters
This commit is contained in:
@@ -130,7 +130,7 @@ final class AddContentToHashDbAction extends AbstractAction implements Presenter
|
||||
newHashSetItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
HashDb hashDb = new HashDbCreateDatabaseDialog().doDialog();
|
||||
HashDb hashDb = new HashDbCreateDatabaseDialog().getHashDatabase();
|
||||
if (null != hashDb) {
|
||||
HashDbManager.getInstance().save();
|
||||
addFilesToHashSet(selectedFiles, hashDb);
|
||||
@@ -145,7 +145,7 @@ final class AddContentToHashDbAction extends AbstractAction implements Presenter
|
||||
String md5Hash = file.getMd5Hash();
|
||||
if (null != md5Hash) {
|
||||
try {
|
||||
hashSet.add(file);
|
||||
hashSet.addHashes(file);
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(AddContentToHashDbAction.class.getName()).log(Level.SEVERE, "Error adding to hash database", ex);
|
||||
|
||||
@@ -47,10 +47,7 @@ HashDbConfigPanel.hashDbIndexStatusLabel.text=No database selected
|
||||
HashDbConfigPanel.hashDbTypeLabel.text=No database selected
|
||||
HashDbConfigPanel.indexButton.text=Index
|
||||
HashDbConfigPanel.indexLabel.text=Index Status:
|
||||
HashDbConfigPanel.showInboxMessagesCheckBox.text=Send ingest messages
|
||||
HashDbConfigPanel.useForIngestCheckbox.text=Search during ingest
|
||||
HashDbConfigPanel.informationLabel.text=Information
|
||||
HashDbSimpleConfigPanel.calcHashesButton.text=Calculate hashes even if no hash database is selected
|
||||
HashDbConfigPanel.importDatabaseButton.text=Import Database
|
||||
HashDbConfigPanel.deleteDatabaseButton.text=Delete Database
|
||||
HashDbConfigPanel.indexPathLabelLabel.text=Index Path:
|
||||
@@ -64,7 +61,7 @@ HashDbSimpleConfigPanel.knownBadHashDbsLabel.text=Enable known bad databases for
|
||||
HashDbSimpleConfigPanel.knownHashDbsLabel.text=Enable known hash databases for ingest:
|
||||
HashDbImportDatabaseDialog.knownRadioButton.text=Known (NSRL or other)
|
||||
HashDbCreateDatabaseDialog.knownRadioButton.text=Known
|
||||
HashDbCreateDatabaseDialog.jLabel1.text=Hash Set Name:
|
||||
HashDbCreateDatabaseDialog.jLabel1.text=Database Path:
|
||||
HashDbCreateDatabaseDialog.saveAsButton.text=Save As...
|
||||
HashDbCreateDatabaseDialog.hashSetNameTextField.text=
|
||||
HashDbImportDatabaseDialog.jLabel3.text=Database Path:
|
||||
@@ -76,3 +73,9 @@ HashDbImportDatabaseDialog.sendIngestMessagesCheckbox.text=Send ingest messages
|
||||
HashDbImportDatabaseDialog.hashSetNameTextField.text=
|
||||
HashDbConfigPanel.createDatabaseButton.text=Create Database
|
||||
HashDbImportDatabaseDialog.openButton.text=Open...
|
||||
HashDbSimpleConfigPanel.alwaysCalcHashesCheckbox.text=Calculate hashes even if no hash database is selected
|
||||
HashDbCreateDatabaseDialog.jLabel3.text=Hash Set Name:
|
||||
HashDbCreateDatabaseDialog.okButton.text=OK
|
||||
HashDbCreateDatabaseDialog.databasePathTextField.text=
|
||||
HashDbConfigPanel.searchDuringIngestCheckbox.text=Search during ingest
|
||||
HashDbConfigPanel.sendIngestMessagesCheckBox.text=Send ingest messages
|
||||
|
||||
@@ -96,10 +96,10 @@
|
||||
<EmptySpace min="-2" pref="53" max="-2" attributes="0"/>
|
||||
<Component id="hashDbNameLabel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="useForIngestCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="searchDuringIngestCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
|
||||
<Component id="showInboxMessagesCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="sendIngestMessagesCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
@@ -180,9 +180,9 @@
|
||||
<Component id="optionsSeparator" min="-2" pref="6" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="useForIngestCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="searchDuringIngestCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="showInboxMessagesCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="sendIngestMessagesCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="ingestWarningLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
@@ -360,24 +360,24 @@
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="indexButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="useForIngestCheckbox">
|
||||
<Component class="javax.swing.JCheckBox" name="searchDuringIngestCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.useForIngestCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.searchDuringIngestCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="useForIngestCheckboxActionPerformed"/>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="searchDuringIngestCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="showInboxMessagesCheckBox">
|
||||
<Component class="javax.swing.JCheckBox" name="sendIngestMessagesCheckBox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.showInboxMessagesCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.sendIngestMessagesCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="showInboxMessagesCheckBoxActionPerformed"/>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="sendIngestMessagesCheckBoxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="informationLabel">
|
||||
|
||||
@@ -40,13 +40,16 @@ import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb.KnownFilesType;
|
||||
|
||||
/**
|
||||
* Instances of this class provide a comprehensive UI for managing the hash sets configuration.
|
||||
*/
|
||||
public final class HashDbConfigPanel extends javax.swing.JPanel implements OptionsPanel {
|
||||
private static final String NO_SELECTION_TEXT = "No database selected";
|
||||
private static final String ERROR_GETTING_INDEX_STATUS = "Error occurred getting status";
|
||||
private static final String ERROR_GETTING_PATH_TEXT = "Error occurred getting path";
|
||||
private static final String ERROR_GETTING_INDEX_STATUS_TEXT = "Error occurred getting status";
|
||||
private static final String LEGACY_INDEX_FILE_EXTENSION = "-md5.idx";
|
||||
private HashDbManager hashSetManager = HashDbManager.getInstance();
|
||||
private HashSetTableModel hashSetTableModel = new HashSetTableModel();
|
||||
@@ -111,10 +114,10 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
indexButton.setEnabled(false);
|
||||
|
||||
// Update ingest options.
|
||||
useForIngestCheckbox.setSelected(false);
|
||||
useForIngestCheckbox.setEnabled(false);
|
||||
showInboxMessagesCheckBox.setSelected(false);
|
||||
showInboxMessagesCheckBox.setEnabled(false);
|
||||
searchDuringIngestCheckbox.setSelected(false);
|
||||
searchDuringIngestCheckbox.setEnabled(false);
|
||||
sendIngestMessagesCheckBox.setSelected(false);
|
||||
sendIngestMessagesCheckBox.setEnabled(false);
|
||||
optionsLabel.setEnabled(false);
|
||||
optionsSeparator.setEnabled(false);
|
||||
|
||||
@@ -133,8 +136,22 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
// Update descriptive labels.
|
||||
hashDbNameLabel.setText(db.getHashSetName());
|
||||
hashDbTypeLabel.setText(db.getKnownFilesType().getDisplayName());
|
||||
hashDbLocationLabel.setText(shortenPath(db.getDatabasePath()));
|
||||
indexPathLabel.setText(shortenPath(db.getIndexPath()));
|
||||
|
||||
try {
|
||||
hashDbLocationLabel.setText(shortenPath(db.getDatabasePath()));
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbConfigPanel.class.getName()).log(Level.SEVERE, "Error getting database path of " + db.getHashSetName() + " hash database", ex);
|
||||
hashDbLocationLabel.setText(ERROR_GETTING_PATH_TEXT);
|
||||
}
|
||||
|
||||
try {
|
||||
indexPathLabel.setText(shortenPath(db.getIndexPath()));
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbConfigPanel.class.getName()).log(Level.SEVERE, "Error getting index path of " + db.getHashSetName() + " hash database", ex);
|
||||
indexPathLabel.setText(ERROR_GETTING_PATH_TEXT);
|
||||
}
|
||||
|
||||
// Update indexing components.
|
||||
try {
|
||||
@@ -155,7 +172,7 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
hashDbIndexStatusLabel.setText("Indexed");
|
||||
}
|
||||
hashDbIndexStatusLabel.setForeground(Color.black);
|
||||
if (db.canBeReindexed()) {
|
||||
if (db.canBeReIndexed()) {
|
||||
indexButton.setText("Re-Index");
|
||||
indexButton.setEnabled(true);
|
||||
}
|
||||
@@ -173,7 +190,7 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbConfigPanel.class.getName()).log(Level.SEVERE, "Error getting index state of hash database", ex);
|
||||
hashDbIndexStatusLabel.setText(ERROR_GETTING_INDEX_STATUS);
|
||||
hashDbIndexStatusLabel.setText(ERROR_GETTING_INDEX_STATUS_TEXT);
|
||||
hashDbIndexStatusLabel.setForeground(Color.red);
|
||||
indexButton.setText("Index");
|
||||
indexButton.setEnabled(false);
|
||||
@@ -185,12 +202,12 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
}
|
||||
|
||||
// Update ingest option components.
|
||||
useForIngestCheckbox.setSelected(db.getUseForIngest());
|
||||
useForIngestCheckbox.setEnabled(!ingestIsRunning);
|
||||
showInboxMessagesCheckBox.setSelected(db.getShowInboxMessages());
|
||||
showInboxMessagesCheckBox.setEnabled(!ingestIsRunning && db.getUseForIngest() && db.getKnownFilesType().equals(HashDb.KnownFilesType.KNOWN_BAD));
|
||||
optionsLabel.setEnabled(!ingestIsRunning && db.getUseForIngest() && db.getKnownFilesType().equals(HashDb.KnownFilesType.KNOWN_BAD));
|
||||
optionsSeparator.setEnabled(!ingestIsRunning && db.getUseForIngest() && db.getKnownFilesType().equals(HashDb.KnownFilesType.KNOWN_BAD));
|
||||
searchDuringIngestCheckbox.setSelected(db.getSearchDuringIngest());
|
||||
searchDuringIngestCheckbox.setEnabled(!ingestIsRunning);
|
||||
sendIngestMessagesCheckBox.setSelected(db.getSendIngestMessages());
|
||||
sendIngestMessagesCheckBox.setEnabled(!ingestIsRunning && db.getSearchDuringIngest() && db.getKnownFilesType().equals(KnownFilesType.KNOWN_BAD));
|
||||
optionsLabel.setEnabled(!ingestIsRunning);
|
||||
optionsSeparator.setEnabled(!ingestIsRunning);
|
||||
|
||||
// Update database action buttons.
|
||||
createDatabaseButton.setEnabled(true);
|
||||
@@ -245,14 +262,9 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
hashSetManager.save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a list of HashDbs from the dialog panel that do not have a companion -md5.idx file.
|
||||
* Occurs when user clicks "No" to the dialog pop up box.
|
||||
* @param toRemove a list of HashDbs that are unindexed
|
||||
*/
|
||||
void removeThese(List<HashDb> toRemove) {
|
||||
for (HashDb hashDb : toRemove) {
|
||||
hashSetManager.removeHashSet(hashDb);
|
||||
hashSetManager.removeHashDatabase(hashDb);
|
||||
}
|
||||
hashSetTableModel.refreshModel();
|
||||
}
|
||||
@@ -290,7 +302,6 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
}
|
||||
|
||||
boolean valid() {
|
||||
// TODO check whether form is consistent and complete
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -439,8 +450,8 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
hashDbIndexStatusLabel = new javax.swing.JLabel();
|
||||
indexLabel = new javax.swing.JLabel();
|
||||
indexButton = new javax.swing.JButton();
|
||||
useForIngestCheckbox = new javax.swing.JCheckBox();
|
||||
showInboxMessagesCheckBox = new javax.swing.JCheckBox();
|
||||
searchDuringIngestCheckbox = new javax.swing.JCheckBox();
|
||||
sendIngestMessagesCheckBox = new javax.swing.JCheckBox();
|
||||
informationLabel = new javax.swing.JLabel();
|
||||
optionsLabel = new javax.swing.JLabel();
|
||||
informationSeparator = new javax.swing.JSeparator();
|
||||
@@ -529,17 +540,17 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(useForIngestCheckbox, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.useForIngestCheckbox.text")); // NOI18N
|
||||
useForIngestCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
org.openide.awt.Mnemonics.setLocalizedText(searchDuringIngestCheckbox, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.searchDuringIngestCheckbox.text")); // NOI18N
|
||||
searchDuringIngestCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
useForIngestCheckboxActionPerformed(evt);
|
||||
searchDuringIngestCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(showInboxMessagesCheckBox, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.showInboxMessagesCheckBox.text")); // NOI18N
|
||||
showInboxMessagesCheckBox.addActionListener(new java.awt.event.ActionListener() {
|
||||
org.openide.awt.Mnemonics.setLocalizedText(sendIngestMessagesCheckBox, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.sendIngestMessagesCheckBox.text")); // NOI18N
|
||||
sendIngestMessagesCheckBox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
showInboxMessagesCheckBoxActionPerformed(evt);
|
||||
sendIngestMessagesCheckBoxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -600,10 +611,10 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
.addComponent(nameLabel)
|
||||
.addGap(53, 53, 53)
|
||||
.addComponent(hashDbNameLabel))
|
||||
.addComponent(useForIngestCheckbox)
|
||||
.addComponent(searchDuringIngestCheckbox)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(21, 21, 21)
|
||||
.addComponent(showInboxMessagesCheckBox)))
|
||||
.addComponent(sendIngestMessagesCheckBox)))
|
||||
.addGap(0, 0, Short.MAX_VALUE))))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(optionsLabel)
|
||||
@@ -661,9 +672,9 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
.addComponent(optionsLabel)
|
||||
.addComponent(optionsSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 6, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(useForIngestCheckbox)
|
||||
.addComponent(searchDuringIngestCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(showInboxMessagesCheckBox)
|
||||
.addComponent(sendIngestMessagesCheckBox)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(ingestWarningLabel)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
@@ -712,7 +723,7 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
if (JOptionPane.showConfirmDialog(null, "This will remove the hash database for all cases. Do you want to proceed? ", "Delete Hash Database from Configuration", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) {
|
||||
HashDb hashDb = ((HashSetTable)hashSetTable).getSelection();
|
||||
if (hashDb != null) {
|
||||
hashSetManager.removeHashSet(hashDb);
|
||||
hashSetManager.removeHashDatabase(hashDb);
|
||||
hashSetTableModel.refreshModel();
|
||||
}
|
||||
}
|
||||
@@ -722,40 +733,41 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
if (evt.getKeyCode() == KeyEvent.VK_DELETE) {
|
||||
HashDb hashDb = ((HashSetTable)hashSetTable).getSelection();
|
||||
if (hashDb != null) {
|
||||
hashSetManager.removeHashSet(hashDb);
|
||||
hashSetManager.removeHashDatabase(hashDb);
|
||||
hashSetTableModel.refreshModel();
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_hashSetTableKeyPressed
|
||||
|
||||
private void useForIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useForIngestCheckboxActionPerformed
|
||||
private void searchDuringIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchDuringIngestCheckboxActionPerformed
|
||||
HashDb hashDb = ((HashSetTable)hashSetTable).getSelection();
|
||||
if (hashDb != null) {
|
||||
hashDb.setUseForIngest(useForIngestCheckbox.isSelected());
|
||||
showInboxMessagesCheckBox.setEnabled(useForIngestCheckbox.isSelected());
|
||||
hashDb.setSearchDuringIngest(searchDuringIngestCheckbox.isSelected());
|
||||
if (!searchDuringIngestCheckbox.isSelected()) {
|
||||
sendIngestMessagesCheckBox.setSelected(false);
|
||||
}
|
||||
hashDb.setSendIngestMessages(sendIngestMessagesCheckBox.isSelected());
|
||||
}
|
||||
}//GEN-LAST:event_useForIngestCheckboxActionPerformed
|
||||
}//GEN-LAST:event_searchDuringIngestCheckboxActionPerformed
|
||||
|
||||
private void showInboxMessagesCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showInboxMessagesCheckBoxActionPerformed
|
||||
private void sendIngestMessagesCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sendIngestMessagesCheckBoxActionPerformed
|
||||
HashDb hashDb = ((HashSetTable)hashSetTable).getSelection();
|
||||
if (hashDb != null) {
|
||||
hashDb.setShowInboxMessages(showInboxMessagesCheckBox.isSelected());
|
||||
hashDb.setSendIngestMessages(sendIngestMessagesCheckBox.isSelected());
|
||||
}
|
||||
}//GEN-LAST:event_showInboxMessagesCheckBoxActionPerformed
|
||||
}//GEN-LAST:event_sendIngestMessagesCheckBoxActionPerformed
|
||||
|
||||
private void importDatabaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importDatabaseButtonActionPerformed
|
||||
HashDb hashDb = new HashDbImportDatabaseDialog().doDialog();
|
||||
if (hashDb != null) {
|
||||
hashSetManager.addHashSet(hashDb);
|
||||
HashDb hashDb = new HashDbImportDatabaseDialog().getHashDatabase();
|
||||
if (null != hashDb) {
|
||||
hashSetTableModel.refreshModel();
|
||||
((HashSetTable)hashSetTable).selectRowByName(hashDb.getHashSetName());
|
||||
}
|
||||
}//GEN-LAST:event_importDatabaseButtonActionPerformed
|
||||
|
||||
private void createDatabaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_createDatabaseButtonActionPerformed
|
||||
HashDb hashDb = new HashDbCreateDatabaseDialog().doDialog();
|
||||
HashDb hashDb = new HashDbCreateDatabaseDialog().getHashDatabase();
|
||||
if (null != hashDb) {
|
||||
hashSetManager.addHashSet(hashDb);
|
||||
hashSetTableModel.refreshModel();
|
||||
((HashSetTable)hashSetTable).selectRowByName(hashDb.getHashSetName());
|
||||
}
|
||||
@@ -787,8 +799,8 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
private javax.swing.JLabel nameLabel;
|
||||
private javax.swing.JLabel optionsLabel;
|
||||
private javax.swing.JSeparator optionsSeparator;
|
||||
private javax.swing.JCheckBox showInboxMessagesCheckBox;
|
||||
private javax.swing.JCheckBox searchDuringIngestCheckbox;
|
||||
private javax.swing.JCheckBox sendIngestMessagesCheckBox;
|
||||
private javax.swing.JLabel typeLabel;
|
||||
private javax.swing.JCheckBox useForIngestCheckbox;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
+59
-18
@@ -27,7 +27,7 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
@@ -42,12 +42,13 @@
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="okButton" linkSize="2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="hashSetNameTextField" min="-2" pref="176" max="-2" attributes="0"/>
|
||||
<Component id="cancelButton" linkSize="2" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="20" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
@@ -55,29 +56,44 @@
|
||||
<Component id="knownBadRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="1" max="-2" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="databasePathTextField" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="hashSetNameTextField" min="-2" pref="272" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="saveAsButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="saveAsButton" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cancelButton" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="hashSetNameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="databasePathTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="saveAsButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="7" max="-2" attributes="0"/>
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="knownRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
@@ -87,12 +103,12 @@
|
||||
<Component id="searchDuringIngestCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="sendIngestMessagesCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="saveAsButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace pref="12" max="32767" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@@ -188,5 +204,30 @@
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel3">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbCreateDatabaseDialog.jLabel3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="databasePathTextField">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbCreateDatabaseDialog.databasePathTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="okButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbCreateDatabaseDialog.okButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
||||
+131
-70
@@ -27,21 +27,48 @@ import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JFrame;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.KnownFilesType;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb.KnownFilesType;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDatabaseFileAlreadyExistsException;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.DuplicateHashSetNameException;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDatabaseAlreadyAddedException;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.IllegalHashDatabaseFileNameExtensionException;
|
||||
|
||||
/**
|
||||
* Instances of this class allow a user to create a new hash database.
|
||||
* Instances of this class allow a user to create a new hash database and
|
||||
* add it to the set of hash databases used to classify files as unknown, known
|
||||
* or known bad.
|
||||
*/
|
||||
final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
||||
|
||||
private static final String DEFAULT_FILE_NAME = "hashset";
|
||||
private JFileChooser fileChooser = null;
|
||||
private HashDb newHashDb = null;
|
||||
|
||||
/**
|
||||
* Displays a dialog that allows a user to create a new hash database and
|
||||
* add it to the set of hash databases used to classify files as unknown, known
|
||||
* or known bad.
|
||||
*/
|
||||
HashDbCreateDatabaseDialog() {
|
||||
super(new javax.swing.JFrame(), "Create Hash Database", true);
|
||||
super(new JFrame(), "Create Hash Database", true);
|
||||
initFileChooser();
|
||||
initComponents();
|
||||
display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hash database created by the user, if any.
|
||||
* @return A HashDb object or null.
|
||||
*/
|
||||
HashDb getHashDatabase() {
|
||||
return newHashDb;
|
||||
}
|
||||
|
||||
private void initFileChooser() {
|
||||
fileChooser = new JFileChooser() {
|
||||
@Override
|
||||
public void approveSelection() {
|
||||
@@ -49,36 +76,29 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
||||
if (!FilenameUtils.getExtension(selectedFile.getName()).equalsIgnoreCase(HashDbManager.getHashDatabaseFileExtension())) {
|
||||
if (JOptionPane.showConfirmDialog(this, "The hash database file must have a ." + HashDbManager.getHashDatabaseFileExtension() + " extension.", "File Name Error", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.CANCEL_OPTION) {
|
||||
cancelSelection();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (selectedFile.exists()) {
|
||||
if (JOptionPane.showConfirmDialog(this, "A file with this name already exists. Please choose a new file name.", "File Already Exists Error", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.CANCEL_OPTION) {
|
||||
cancelSelection();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
super.approveSelection();
|
||||
}
|
||||
};
|
||||
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
fileChooser.setDragEnabled(false);
|
||||
fileChooser.setMultiSelectionEnabled(false);
|
||||
|
||||
initComponents();
|
||||
fileChooser.setMultiSelectionEnabled(false);
|
||||
}
|
||||
|
||||
HashDb doDialog() {
|
||||
newHashDb = null;
|
||||
|
||||
// Center and display the dialog.
|
||||
private void display() {
|
||||
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
|
||||
this.setVisible(true);
|
||||
|
||||
return newHashDb;
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -98,6 +118,9 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
searchDuringIngestCheckbox = new javax.swing.JCheckBox();
|
||||
sendIngestMessagesCheckbox = new javax.swing.JCheckBox();
|
||||
jLabel3 = new javax.swing.JLabel();
|
||||
databasePathTextField = new javax.swing.JTextField();
|
||||
okButton = new javax.swing.JButton();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
|
||||
@@ -150,6 +173,18 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
||||
sendIngestMessagesCheckbox.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(sendIngestMessagesCheckbox, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.sendIngestMessagesCheckbox.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.jLabel3.text")); // NOI18N
|
||||
|
||||
databasePathTextField.setEditable(false);
|
||||
databasePathTextField.setText(org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.databasePathTextField.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.okButton.text")); // NOI18N
|
||||
okButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
okButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
@@ -166,35 +201,47 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jLabel2)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jLabel1)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(okButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(hashSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 176, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(cancelButton))
|
||||
.addComponent(jLabel2)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(20, 20, 20)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(knownRadioButton)
|
||||
.addComponent(knownBadRadioButton))))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(saveAsButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cancelButton)
|
||||
.addContainerGap())
|
||||
.addComponent(knownBadRadioButton)))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jLabel1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(databasePathTextField))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
|
||||
.addComponent(jLabel3)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(hashSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 272, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(saveAsButton)))
|
||||
.addContainerGap())))
|
||||
);
|
||||
|
||||
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {cancelButton, saveAsButton});
|
||||
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {cancelButton, okButton});
|
||||
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGap(2, 2, 2)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel1)
|
||||
.addComponent(jLabel3)
|
||||
.addComponent(hashSetNameTextField, 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(databasePathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(saveAsButton)
|
||||
.addComponent(jLabel1))
|
||||
.addGap(7, 7, 7)
|
||||
.addComponent(jLabel2)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(knownRadioButton)
|
||||
@@ -204,22 +251,24 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
||||
.addComponent(searchDuringIngestCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(sendIngestMessagesCheckbox)
|
||||
.addGap(18, 18, 18)
|
||||
.addGap(3, 3, 3)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(saveAsButton)
|
||||
.addComponent(cancelButton))
|
||||
.addContainerGap(12, Short.MAX_VALUE))
|
||||
.addComponent(cancelButton)
|
||||
.addComponent(okButton))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void knownRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_knownRadioButtonActionPerformed
|
||||
searchDuringIngestCheckbox.setSelected(true);
|
||||
sendIngestMessagesCheckbox.setSelected(false);
|
||||
sendIngestMessagesCheckbox.setEnabled(false);
|
||||
}//GEN-LAST:event_knownRadioButtonActionPerformed
|
||||
|
||||
private void knownBadRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_knownBadRadioButtonActionPerformed
|
||||
searchDuringIngestCheckbox.setSelected(true);
|
||||
sendIngestMessagesCheckbox.setSelected(true);
|
||||
sendIngestMessagesCheckbox.setEnabled(true);
|
||||
}//GEN-LAST:event_knownBadRadioButtonActionPerformed
|
||||
@@ -229,16 +278,47 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
||||
}//GEN-LAST:event_cancelButtonActionPerformed
|
||||
|
||||
private void saveAsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveAsButtonActionPerformed
|
||||
if (hashSetNameTextField.getText().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this, "A hash set name must be entered.");
|
||||
return;
|
||||
}
|
||||
|
||||
fileChooser.setSelectedFile(new File(hashSetNameTextField.getText() + "." + HashDbManager.getHashDatabaseFileExtension()));
|
||||
if (fileChooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) {
|
||||
return;
|
||||
try {
|
||||
StringBuilder path = new StringBuilder();
|
||||
if (!hashSetNameTextField.getText().isEmpty()) {
|
||||
path.append(hashSetNameTextField.getText());
|
||||
}
|
||||
else {
|
||||
path.append(DEFAULT_FILE_NAME);
|
||||
}
|
||||
path.append(".").append(HashDbManager.getHashDatabaseFileExtension());
|
||||
fileChooser.setSelectedFile(new File(path.toString()));
|
||||
if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
|
||||
File databaseFile = fileChooser.getSelectedFile();
|
||||
databasePathTextField.setText(databaseFile.getCanonicalPath());
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
Logger.getLogger(HashDbCreateDatabaseDialog.class.getName()).log(Level.WARNING, "Couldn't get selected file path.", ex);
|
||||
}
|
||||
}//GEN-LAST:event_saveAsButtonActionPerformed
|
||||
|
||||
private void searchDuringIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchDuringIngestCheckboxActionPerformed
|
||||
sendIngestMessagesCheckbox.setEnabled(searchDuringIngestCheckbox.isSelected());
|
||||
if (!searchDuringIngestCheckbox.isSelected()) {
|
||||
sendIngestMessagesCheckbox.setSelected(false);
|
||||
}
|
||||
}//GEN-LAST:event_searchDuringIngestCheckboxActionPerformed
|
||||
|
||||
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
|
||||
// Note that the error handlers in this method call return without disposing of the
|
||||
// dialog to allow the user to try again, if desired.
|
||||
|
||||
if (hashSetNameTextField.getText().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this, "A hash set name must be entered.", "Create Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (databasePathTextField.getText().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this, "A database path must be entered.", "Create Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
KnownFilesType type;
|
||||
if (knownRadioButton.isSelected()) {
|
||||
type = KnownFilesType.KNOWN;
|
||||
@@ -254,53 +334,34 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
||||
}
|
||||
catch (IOException ex) {
|
||||
Logger.getLogger(HashDbCreateDatabaseDialog.class.getName()).log(Level.WARNING, errorMessage, ex);
|
||||
JOptionPane.showMessageDialog(this, "Cannot create a hash database file at the selected location.");
|
||||
JOptionPane.showMessageDialog(this, "Cannot create a hash database file at the selected location.", "Create Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
catch (HashDbManager.FileAlreadyExistsException ex) {
|
||||
catch (HashDatabaseFileAlreadyExistsException | DuplicateHashSetNameException | HashDatabaseAlreadyAddedException | IllegalHashDatabaseFileNameExtensionException ex) {
|
||||
Logger.getLogger(HashDbCreateDatabaseDialog.class.getName()).log(Level.WARNING, errorMessage, ex);
|
||||
JOptionPane.showMessageDialog(this, ex.getMessage());
|
||||
JOptionPane.showMessageDialog(this, ex.getMessage(), "Create Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
catch (HashDbManager.DuplicateHashSetNameException ex) {
|
||||
Logger.getLogger(HashDbCreateDatabaseDialog.class.getName()).log(Level.WARNING, errorMessage, ex);
|
||||
JOptionPane.showMessageDialog(this, ex.getMessage());
|
||||
return;
|
||||
}
|
||||
catch (HashDbManager.HashDatabaseAlreadyAddedException ex) {
|
||||
Logger.getLogger(HashDbCreateDatabaseDialog.class.getName()).log(Level.WARNING, errorMessage, ex);
|
||||
JOptionPane.showMessageDialog(this, ex.getMessage());
|
||||
return;
|
||||
}
|
||||
catch (HashDbManager.IllegalHashDatabaseFileNameExtensionException ex) {
|
||||
Logger.getLogger(HashDbCreateDatabaseDialog.class.getName()).log(Level.WARNING, errorMessage, ex);
|
||||
JOptionPane.showMessageDialog(this, ex.getMessage());
|
||||
return;
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbCreateDatabaseDialog.class.getName()).log(Level.SEVERE, errorMessage, ex);
|
||||
JOptionPane.showMessageDialog(this, "Failed to create the hash database.");
|
||||
JOptionPane.showMessageDialog(this, "Failed to create the hash database.", "Create Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
dispose();
|
||||
}//GEN-LAST:event_saveAsButtonActionPerformed
|
||||
|
||||
private void searchDuringIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchDuringIngestCheckboxActionPerformed
|
||||
sendIngestMessagesCheckbox.setEnabled(searchDuringIngestCheckbox.isSelected());
|
||||
if (!searchDuringIngestCheckbox.isSelected()) {
|
||||
sendIngestMessagesCheckbox.setSelected(false);
|
||||
}
|
||||
}//GEN-LAST:event_searchDuringIngestCheckboxActionPerformed
|
||||
}//GEN-LAST:event_okButtonActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.ButtonGroup buttonGroup1;
|
||||
private javax.swing.JButton cancelButton;
|
||||
private javax.swing.JTextField databasePathTextField;
|
||||
private javax.swing.JTextField hashSetNameTextField;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JLabel jLabel3;
|
||||
private javax.swing.JRadioButton knownBadRadioButton;
|
||||
private javax.swing.JRadioButton knownRadioButton;
|
||||
private javax.swing.JButton okButton;
|
||||
private javax.swing.JButton saveAsButton;
|
||||
private javax.swing.JCheckBox searchDuringIngestCheckbox;
|
||||
private javax.swing.JCheckBox sendIngestMessagesCheckbox;
|
||||
|
||||
+59
-35
@@ -27,47 +27,61 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.JFrame;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.KnownFilesType;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb.KnownFilesType;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDatabaseDoesNotExistException;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.DuplicateHashSetNameException;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDatabaseAlreadyAddedException;
|
||||
|
||||
/**
|
||||
* Instances of this class allow a user to select a hash database for import.
|
||||
* Instances of this class allow a user to select an existing hash database and
|
||||
* add it to the set of hash databases used to classify files as unknown, known,
|
||||
* or known bad.
|
||||
*/
|
||||
final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
||||
|
||||
private JFileChooser fileChooser = new JFileChooser();
|
||||
private String selectedFilePath = "";
|
||||
private HashDb selectedHashDb;
|
||||
|
||||
HashDbImportDatabaseDialog() {
|
||||
super(new javax.swing.JFrame(), "Import Hash Database", true);
|
||||
setResizable(false);
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
}
|
||||
private HashDb selectedHashDb = null;
|
||||
|
||||
void customizeComponents() {
|
||||
/**
|
||||
* Displays a dialog that allows a user to select an existing hash database
|
||||
* and add it to the set of hash databases used to classify files as unknown,
|
||||
* known, or known bad.
|
||||
*/
|
||||
HashDbImportDatabaseDialog() {
|
||||
super(new JFrame(), "Import Hash Database", true);
|
||||
initFileChooser();
|
||||
initComponents();
|
||||
display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hash database imported by the user, if any.
|
||||
* @return A HashDb object or null.
|
||||
*/
|
||||
HashDb getHashDatabase() {
|
||||
return selectedHashDb;
|
||||
}
|
||||
|
||||
private void initFileChooser() {
|
||||
fileChooser.setDragEnabled(false);
|
||||
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
String[] EXTENSION = new String[] { "txt", "kdb", "idx", "hash", "Hash", "hsh"};
|
||||
FileNameExtensionFilter filter = new FileNameExtensionFilter("Hash Database File", EXTENSION);
|
||||
fileChooser.setFileFilter(filter);
|
||||
fileChooser.setMultiSelectionEnabled(false);
|
||||
}
|
||||
|
||||
HashDb doDialog() {
|
||||
selectedHashDb = null;
|
||||
|
||||
// Center and display the dialog.
|
||||
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
|
||||
this.setVisible(true);
|
||||
|
||||
return selectedHashDb;
|
||||
fileChooser.setMultiSelectionEnabled(false);
|
||||
}
|
||||
|
||||
private void display() {
|
||||
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
private static String shortenPath(String path) {
|
||||
String shortenedPath = path;
|
||||
if (shortenedPath.length() > 50){
|
||||
@@ -260,11 +274,13 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
||||
}//GEN-LAST:event_openButtonActionPerformed
|
||||
|
||||
private void knownRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_knownRadioButtonActionPerformed
|
||||
searchDuringIngestCheckbox.setSelected(true);
|
||||
sendIngestMessagesCheckbox.setSelected(false);
|
||||
sendIngestMessagesCheckbox.setEnabled(false);
|
||||
}//GEN-LAST:event_knownRadioButtonActionPerformed
|
||||
|
||||
private void knownBadRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_knownBadRadioButtonActionPerformed
|
||||
searchDuringIngestCheckbox.setSelected(true);
|
||||
sendIngestMessagesCheckbox.setSelected(true);
|
||||
sendIngestMessagesCheckbox.setEnabled(true);
|
||||
}//GEN-LAST:event_knownBadRadioButtonActionPerformed
|
||||
@@ -274,19 +290,21 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
||||
}//GEN-LAST:event_cancelButtonActionPerformed
|
||||
|
||||
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
|
||||
if(selectedFilePath.isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this, "A hash database file path must be selected.");
|
||||
return;
|
||||
}
|
||||
// Note that the error handlers in this method call return without disposing of the
|
||||
// dialog to allow the user to try again, if desired.
|
||||
|
||||
if(hashSetNameTextField.getText().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this, "A hash set name must be entered..");
|
||||
JOptionPane.showMessageDialog(this, "A hash set name must be entered.", "Import Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if(selectedFilePath.isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this, "A hash database file path must be selected.", "Import Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
File file = new File(selectedFilePath);
|
||||
if (!file.exists()) {
|
||||
JOptionPane.showMessageDialog(this, "The selected hash database does not exist.");
|
||||
JOptionPane.showMessageDialog(this, "The selected hash database does not exist.", "Import Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -298,16 +316,22 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
||||
type = KnownFilesType.KNOWN_BAD;
|
||||
}
|
||||
|
||||
String errorMessage = "Failed to open hash database at " + selectedFilePath + ".";
|
||||
try {
|
||||
selectedHashDb = HashDb.openHashDatabase(hashSetNameTextField.getText(), selectedFilePath, searchDuringIngestCheckbox.isSelected(), sendIngestMessagesCheckbox.isSelected(), type);
|
||||
selectedHashDb = HashDbManager.getInstance().addExistingHashDatabase(hashSetNameTextField.getText(), selectedFilePath, searchDuringIngestCheckbox.isSelected(), sendIngestMessagesCheckbox.isSelected(), type);
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbImportDatabaseDialog.class.getName()).log(Level.WARNING, "Failed to open hash database at " + selectedFilePath, ex);
|
||||
JOptionPane.showMessageDialog(this, "Failed to import the selected database.\nPlease verify that the selected file is a hash database.");
|
||||
catch (HashDatabaseDoesNotExistException | DuplicateHashSetNameException | HashDatabaseAlreadyAddedException ex) {
|
||||
Logger.getLogger(HashDbImportDatabaseDialog.class.getName()).log(Level.WARNING, errorMessage, ex);
|
||||
JOptionPane.showMessageDialog(this, ex.getMessage(), "Import Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbCreateDatabaseDialog.class.getName()).log(Level.SEVERE, errorMessage, ex);
|
||||
JOptionPane.showMessageDialog(this, errorMessage, "Import Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
this.dispose();
|
||||
dispose();
|
||||
}//GEN-LAST:event_okButtonActionPerformed
|
||||
|
||||
private void searchDuringIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchDuringIngestCheckboxActionPerformed
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb;
|
||||
|
||||
public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
private static HashDbIngestModule instance = null;
|
||||
@@ -138,9 +139,9 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
skCase = Case.getCurrentCase().getSleuthkitCase();
|
||||
|
||||
HashDbManager hashDbManager = HashDbManager.getInstance();
|
||||
getHashSetsUsableForIngest(hashDbManager.getKnownBadHashSets(), knownBadHashSets);
|
||||
getHashSetsUsableForIngest(hashDbManager.getKnownHashSets(), knownHashSets);
|
||||
calcHashesIsSet = hashDbManager.shouldAlwaysCalculateHashes();
|
||||
getHashSetsUsableForIngest(hashDbManager.getKnownBadFileHashSets(), knownBadHashSets);
|
||||
getHashSetsUsableForIngest(hashDbManager.getKnownFileHashSets(), knownHashSets);
|
||||
calcHashesIsSet = hashDbManager.getAlwaysCalculateHashes();
|
||||
|
||||
if (knownHashSets.isEmpty()) {
|
||||
services.postMessage(IngestMessage.createWarningMessage(++messageId, this, "No known hash database set", "Known file search will not be executed."));
|
||||
@@ -155,14 +156,14 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
assert hashDbsForIngest != null;
|
||||
hashDbsForIngest.clear();
|
||||
for (HashDb db : hashDbs) {
|
||||
if (db.getUseForIngest()) {
|
||||
if (db.getSearchDuringIngest()) {
|
||||
try {
|
||||
if (db.hasLookupIndex()) {
|
||||
hashDbsForIngest.add(db);
|
||||
}
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Error get index status for hash database at " +db.getDatabasePath(), ex);
|
||||
logger.log(Level.WARNING, "Error getting index status for " + db.getHashSetName() +" hash database", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,7 +212,7 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
for (HashDb db : knownBadHashSets) {
|
||||
try {
|
||||
long lookupstart = System.currentTimeMillis();
|
||||
if (db.hasHashOfContent(file)) {
|
||||
if (db.hasMd5HashOf(file)) {
|
||||
foundBad = true;
|
||||
knownBadCount += 1;
|
||||
try {
|
||||
@@ -223,7 +224,7 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
ret = ProcessResult.ERROR;
|
||||
}
|
||||
String hashSetName = db.getHashSetName();
|
||||
postHashSetHitToBlackboard(file, md5Hash, hashSetName, db.getShowInboxMessages());
|
||||
postHashSetHitToBlackboard(file, md5Hash, hashSetName, db.getSendIngestMessages());
|
||||
}
|
||||
lookuptime += (System.currentTimeMillis() - lookupstart);
|
||||
} catch (TskException ex) {
|
||||
@@ -241,7 +242,7 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
for (HashDb db : knownHashSets) {
|
||||
try {
|
||||
long lookupstart = System.currentTimeMillis();
|
||||
if (db.hasHashOfContent(file)) {
|
||||
if (db.hasMd5HashOf(file)) {
|
||||
try {
|
||||
skCase.setKnown(file, TskData.FileKnown.KNOWN);
|
||||
break;
|
||||
|
||||
@@ -16,26 +16,22 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.sleuthkit.autopsy.hashdatabase;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.XMLUtil;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
@@ -54,48 +50,28 @@ import org.sleuthkit.datamodel.HashInfo;
|
||||
import org.sleuthkit.datamodel.SleuthkitJNI;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
|
||||
/**
|
||||
* This class is a singleton that manages the set of hash databases
|
||||
* used to identify files as known files or known bad files.
|
||||
* This class implements a singleton that manages the set of hash databases
|
||||
* used to classify files as unknown, known or known bad.
|
||||
*/
|
||||
public class HashDbManager {
|
||||
/**
|
||||
* Characterizes the files whose hashes are stored in a hash database.
|
||||
*/
|
||||
public enum KnownFilesType{
|
||||
KNOWN("Known"),
|
||||
KNOWN_BAD("Known Bad");
|
||||
|
||||
private String displayName;
|
||||
|
||||
private KnownFilesType(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return this.displayName;
|
||||
}
|
||||
}
|
||||
|
||||
// RJCTODO: Consider making these local
|
||||
private static final String ROOT_EL = "hash_sets";
|
||||
private static final String SET_EL = "hash_set";
|
||||
private static final String SET_NAME_ATTR = "name";
|
||||
private static final String SET_TYPE_ATTR = "type";
|
||||
private static final String SET_USE_FOR_INGEST_ATTR = "use_for_ingest";
|
||||
private static final String SET_SHOW_INBOX_MESSAGES = "show_inbox_messages";
|
||||
private static final String PATH_EL = "hash_set_path";
|
||||
private static final String CUR_HASHSETS_FILE_NAME = "hashsets.xml";
|
||||
private static final String XSDFILE = "HashsetsSchema.xsd";
|
||||
private static final String ROOT_ELEMENT = "hash_sets";
|
||||
private static final String SET_ELEMENT = "hash_set";
|
||||
private static final String SET_NAME_ATTRIBUTE = "name";
|
||||
private static final String SET_TYPE_ATTRIBUTE = "type";
|
||||
private static final String SEARCH_DURING_INGEST_ATTRIBUTE = "use_for_ingest";
|
||||
private static final String SEND_INGEST_MESSAGES_ATTRIBUTE = "show_inbox_messages";
|
||||
private static final String PATH_ELEMENT = "hash_set_path";
|
||||
private static final String CONFIG_FILE_NAME = "hashsets.xml";
|
||||
private static final String XSD_FILE_NAME = "HashsetsSchema.xsd";
|
||||
private static final String ENCODING = "UTF-8";
|
||||
private static final String SET_CALC = "hash_calculate";
|
||||
private static final String SET_VALUE = "value";
|
||||
private static final String ALWAYS_CALCULATE_HASHES_ELEMENT = "hash_calculate";
|
||||
private static final String VALUE_ATTRIBUTE = "value";
|
||||
private static final String HASH_DATABASE_FILE_EXTENSON = "kdb";
|
||||
private static final String LEGACY_INDEX_FILE_EXTENSION = "-md5.idx";
|
||||
private static final Logger logger = Logger.getLogger(HashDbManager.class.getName());
|
||||
private static HashDbManager instance;
|
||||
private final String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + CUR_HASHSETS_FILE_NAME;
|
||||
private final String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + CONFIG_FILE_NAME;
|
||||
private List<HashDb> knownHashSets = new ArrayList<>();
|
||||
private List<HashDb> knownBadHashSets = new ArrayList<>();
|
||||
private Set<String> hashSetNames = new HashSet<>();
|
||||
@@ -118,171 +94,209 @@ public class HashDbManager {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hashSetsConfigurationFileExists() {
|
||||
File f = new File(configFilePath);
|
||||
return f.exists() && f.canRead() && f.canWrite();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the extension, without the dot separator, that the SleuthKit requires
|
||||
* for hash database files that combine the database and the index.
|
||||
*/
|
||||
public static String getHashDatabaseFileExtension() {
|
||||
return HASH_DATABASE_FILE_EXTENSON;
|
||||
}
|
||||
|
||||
public class DuplicateHashSetNameException extends Exception {
|
||||
private DuplicateHashSetNameException() {
|
||||
super("The hash set name has already been used for another hash database.");
|
||||
private DuplicateHashSetNameException(String hashSetName) {
|
||||
super("The hash set name '"+ hashSetName +"' has already been used for another hash database.");
|
||||
}
|
||||
}
|
||||
|
||||
public class HashDatabaseDoesNotExistException extends Exception {
|
||||
private HashDatabaseDoesNotExistException() {
|
||||
super("Attempt to add a hash database that does not exist to the configuration");
|
||||
private HashDatabaseDoesNotExistException(String path) {
|
||||
super("No hash database found at\n" + path);
|
||||
}
|
||||
}
|
||||
|
||||
public class FileAlreadyExistsException extends Exception {
|
||||
private FileAlreadyExistsException() {
|
||||
super("A hash database file already exists at the selected location.");
|
||||
public class HashDatabaseFileAlreadyExistsException extends Exception {
|
||||
private HashDatabaseFileAlreadyExistsException(String path) {
|
||||
super("A file already exists at\n" + path);
|
||||
}
|
||||
}
|
||||
|
||||
public class HashDatabaseAlreadyAddedException extends Exception {
|
||||
private HashDatabaseAlreadyAddedException() {
|
||||
super("The hash database has already been created.");
|
||||
private HashDatabaseAlreadyAddedException(String path) {
|
||||
super("The hash database at\n" + path + "\nhas already been created or imported.");
|
||||
}
|
||||
}
|
||||
|
||||
public class IllegalHashDatabaseFileNameExtensionException extends Exception {
|
||||
private IllegalHashDatabaseFileNameExtensionException() {
|
||||
super("The hash database file must have a ." + getHashDatabaseFileExtension() + " extension.");
|
||||
super("The hash database file name must have a ." + getHashDatabaseFileExtension() + " extension.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an existing hash database to the set of hash databases used to classify files as known or known bad.
|
||||
* Does not save the configuration - the configuration is only saved on demand to support cancellation of
|
||||
* configuration panels.
|
||||
* @param hashSetName Name used to represent the hash database in user interface components.
|
||||
* @param filePath Full path to either a hash database file or a hash database index file.
|
||||
* @param path Full path to either a hash database file or a hash database index file.
|
||||
* @param searchDuringIngest A flag indicating whether or not the hash database should be searched during ingest.
|
||||
* @param sendIngestMessages A flag indicating whether hash set hit messages should be sent as ingest messages.
|
||||
* @param knownFilesType The classification to apply to files whose hashes are found in the hash database.
|
||||
* @return A HashDb object representation of the hash database.
|
||||
* @return A HashDb representing the hash database.
|
||||
* @throws HashDatabaseDoesNotExistException, DuplicateHashSetNameException, HashDatabaseAlreadyAddedException, TskCoreException
|
||||
*/
|
||||
public synchronized HashDb addExistingHashDatabase(String hashSetName, String filePath, boolean searchDuringIngest, boolean sendIngestMessages, KnownFilesType knownFilesType) throws HashDatabaseDoesNotExistException, DuplicateHashSetNameException, HashDatabaseAlreadyAddedException, TskCoreException {
|
||||
if (new File(filePath).exists()) {
|
||||
throw new HashDatabaseDoesNotExistException();
|
||||
public synchronized HashDb addExistingHashDatabase(String hashSetName, String path, boolean searchDuringIngest, boolean sendIngestMessages, HashDb.KnownFilesType knownFilesType) throws HashDatabaseDoesNotExistException, DuplicateHashSetNameException, HashDatabaseAlreadyAddedException, TskCoreException {
|
||||
if (!new File(path).exists()) {
|
||||
throw new HashDatabaseDoesNotExistException(path);
|
||||
}
|
||||
|
||||
if (hashSetPaths.contains(path)) {
|
||||
throw new HashDatabaseAlreadyAddedException(path);
|
||||
}
|
||||
|
||||
if (hashSetNames.contains(hashSetName)) {
|
||||
throw new DuplicateHashSetNameException();
|
||||
throw new DuplicateHashSetNameException(hashSetName);
|
||||
}
|
||||
|
||||
if (hashSetPaths.contains(filePath)) {
|
||||
throw new HashDatabaseAlreadyAddedException();
|
||||
}
|
||||
|
||||
int handle = SleuthkitJNI.openHashDatabase(filePath);
|
||||
HashDb hashDb = new HashDb(handle, SleuthkitJNI.getHashDatabasePath(handle), SleuthkitJNI.getHashDatabaseIndexPath(handle), hashSetName, searchDuringIngest, sendIngestMessages, knownFilesType);
|
||||
addToConfiguration(hashDb);
|
||||
return hashDb;
|
||||
return addHashDatabase(SleuthkitJNI.openHashDatabase(path), hashSetName, searchDuringIngest, sendIngestMessages, knownFilesType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new hash database to the set of hash databases used to classify files as known or known bad.
|
||||
* Does not save the configuration - the configuration is only saved on demand to support cancellation of
|
||||
* configuration panels.
|
||||
* @param hashSetName Hash set name used to represent the hash database in user interface components.
|
||||
* @param filePath Full path to the database file to be created. The file name component of the path must have a ".kdb" extension.
|
||||
* @param useForIngest A flag indicating whether or not the data base should be used during the file ingest process.
|
||||
* @param showInboxMessages A flag indicating whether messages indicating lookup hits should be sent to the application in box.
|
||||
* @param hashSetType The type of hash set to associate with the database.
|
||||
* @return A HashDb object representation of the opened hash database.
|
||||
* @param path Full path to the database file to be created.
|
||||
* @param searchDuringIngest A flag indicating whether or not the hash database should be searched during ingest.
|
||||
* @param sendIngestMessages A flag indicating whether hash set hit messages should be sent as ingest messages.
|
||||
* @param knownFilesType The classification to apply to files whose hashes are found in the hash database.
|
||||
* @return A HashDb representing the hash database.
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
public synchronized HashDb addNewHashDatabase(String hashSetName, String filePath, boolean useForIngest, boolean showInboxMessages, KnownFilesType knownFilesType) throws FileAlreadyExistsException, DuplicateHashSetNameException, HashDatabaseAlreadyAddedException, IllegalHashDatabaseFileNameExtensionException, TskCoreException {
|
||||
File file = new File(filePath);
|
||||
public synchronized HashDb addNewHashDatabase(String hashSetName, String path, boolean searchDuringIngest, boolean sendIngestMessages, HashDb.KnownFilesType knownFilesType) throws HashDatabaseFileAlreadyExistsException, IllegalHashDatabaseFileNameExtensionException, DuplicateHashSetNameException, HashDatabaseAlreadyAddedException, TskCoreException {
|
||||
File file = new File(path);
|
||||
if (file.exists()) {
|
||||
throw new FileAlreadyExistsException();
|
||||
throw new HashDatabaseFileAlreadyExistsException(path);
|
||||
}
|
||||
if (!FilenameUtils.getExtension(file.getName()).equalsIgnoreCase(HASH_DATABASE_FILE_EXTENSON)) {
|
||||
throw new IllegalHashDatabaseFileNameExtensionException();
|
||||
}
|
||||
|
||||
if (hashSetPaths.contains(path)) {
|
||||
throw new HashDatabaseAlreadyAddedException(path);
|
||||
}
|
||||
|
||||
if (hashSetNames.contains(hashSetName)) {
|
||||
throw new DuplicateHashSetNameException();
|
||||
throw new DuplicateHashSetNameException(hashSetName);
|
||||
}
|
||||
|
||||
if (hashSetPaths.contains(filePath)) {
|
||||
throw new HashDatabaseAlreadyAddedException();
|
||||
}
|
||||
|
||||
int handle = SleuthkitJNI.createHashDatabase(filePath);
|
||||
HashDb hashDb = new HashDb(handle, SleuthkitJNI.getHashDatabasePath(handle), SleuthkitJNI.getHashDatabaseIndexPath(handle), hashSetName, useForIngest, showInboxMessages, knownFilesType);
|
||||
addToConfiguration(hashDb);
|
||||
return hashDb;
|
||||
return addHashDatabase(SleuthkitJNI.createHashDatabase(path), hashSetName, searchDuringIngest, sendIngestMessages, knownFilesType);
|
||||
}
|
||||
|
||||
private void addToConfiguration(HashDb hashDb) {
|
||||
private HashDb addHashDatabase(int handle, String hashSetName, boolean searchDuringIngest, boolean sendIngestMessages, HashDb.KnownFilesType knownFilesType) throws TskCoreException {
|
||||
HashDb hashDb = new HashDb(handle, hashSetName, searchDuringIngest, sendIngestMessages, knownFilesType);
|
||||
|
||||
// Get the paths before updating the collections since the path
|
||||
// getting methods may throw.
|
||||
String databasePath = hashDb.getDatabasePath();
|
||||
String indexPath = hashDb.getIndexPath();
|
||||
|
||||
// Update the collections used to ensure that hash set names are unique
|
||||
// and the same database is not added to the configuration more than once.
|
||||
hashSetNames.add(hashDb.getHashSetName());
|
||||
hashSetPaths.add(hashDb.getDatabasePath());
|
||||
hashSetPaths.add(hashDb.getIndexPath());
|
||||
hashSetPaths.add(indexPath);
|
||||
if (!hashDb.hasIndexOnly()) {
|
||||
hashSetPaths.add(databasePath);
|
||||
}
|
||||
|
||||
// Add the hash database to the appropriate collection for its type.
|
||||
if (hashDb.getKnownFilesType() == HashDb.KnownFilesType.KNOWN) {
|
||||
knownHashSets.add(hashDb);
|
||||
}
|
||||
else {
|
||||
knownBadHashSets.add(hashDb);
|
||||
}
|
||||
}
|
||||
|
||||
return hashDb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a hash database from the configuration. Does not save the
|
||||
* configuration - the configuration is only saved on demand to support
|
||||
* cancellation of configuration panels.
|
||||
* Removes a hash database from the set of hash databases used to classify
|
||||
* files as known or known bad. Does not save the configuration - the
|
||||
* configuration is only saved on demand to support cancellation of
|
||||
* configuration panels.
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
public synchronized void removeHashDatabase(HashDb hashDb) {
|
||||
try {
|
||||
hashDb.close();
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error closing hash database at " + hashDb.getDatabasePath(), ex);
|
||||
}
|
||||
// First remove the database from whichever hash set list it occupies,
|
||||
// and remove its hash set name from the hash set used to ensure unique
|
||||
// hash set names are used. These operations will succeed and constitute
|
||||
// a mostly effective removal, even if the subsequent operations fail.
|
||||
knownHashSets.remove(hashDb);
|
||||
knownBadHashSets.remove(hashDb);
|
||||
hashSetNames.remove(hashDb.getHashSetName());
|
||||
|
||||
// Now undertake the operations that could fail.
|
||||
try {
|
||||
hashSetPaths.remove(hashDb.getIndexPath());
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error getting index path of " + hashDb.getHashSetName() + " hash database when removing the database", ex);
|
||||
}
|
||||
try {
|
||||
if (!hashDb.hasIndexOnly()) {
|
||||
hashSetPaths.remove(hashDb.getDatabasePath());
|
||||
}
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error getting database path of " + hashDb.getHashSetName() + " hash database when removing the database", ex);
|
||||
}
|
||||
try {
|
||||
hashDb.close();
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error closing " + hashDb.getHashSetName() + " hash database when removing the database", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all of the configured hash sets.
|
||||
* @return A list, possibly empty, of HashDb objects representing the hash
|
||||
* sets.
|
||||
* Gets all of the hash databases used to classify files as known or known bad.
|
||||
* @return A list, possibly empty, of hash databases.
|
||||
*/
|
||||
public synchronized List<HashDb> getAllHashSets() {
|
||||
List<HashDb> hashDbs = new ArrayList<>();
|
||||
hashDbs.addAll(knownHashSets);
|
||||
hashDbs.addAll(knownBadHashSets);
|
||||
return Collections.unmodifiableList(hashDbs);
|
||||
return hashDbs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configured known files hash sets.
|
||||
* @return A list, possibly empty, of HashDb objects.
|
||||
* Gets all of the hash databases used to classify files as known.
|
||||
* @return A list, possibly empty, of hash databases.
|
||||
*/
|
||||
public synchronized List<HashDb> getKnownHashSets() {
|
||||
return Collections.unmodifiableList(knownHashSets);
|
||||
public synchronized List<HashDb> getKnownFileHashSets() {
|
||||
List<HashDb> hashDbs = new ArrayList<>();
|
||||
hashDbs.addAll(knownHashSets);
|
||||
return hashDbs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configured known bad files hash sets.
|
||||
* @return A list, possibly empty, of HashDb objects.
|
||||
* Gets all of the hash databases used to classify files as known bad.
|
||||
* @return A list, possibly empty, of hash databases.
|
||||
*/
|
||||
public synchronized List<HashDb> getKnownBadHashSets() {
|
||||
return Collections.unmodifiableList(knownBadHashSets);
|
||||
public synchronized List<HashDb> getKnownBadFileHashSets() {
|
||||
List<HashDb> hashDbs = new ArrayList<>();
|
||||
hashDbs.addAll(knownBadHashSets);
|
||||
return hashDbs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all of the configured hash sets that accept updates.
|
||||
* @return A list, possibly empty, of HashDb objects.
|
||||
|
||||
/**
|
||||
* Gets all of the hash databases that accept updates.
|
||||
* @return A list, possibly empty, of hash databases.
|
||||
*/
|
||||
public synchronized List<HashDb> getUpdateableHashSets() {
|
||||
List<HashDb> updateableDbs = getUpdateableHashSets(knownHashSets);
|
||||
updateableDbs.addAll(getUpdateableHashSets(knownBadHashSets));
|
||||
return Collections.unmodifiableList(updateableDbs);
|
||||
return updateableDbs;
|
||||
}
|
||||
|
||||
private List<HashDb> getUpdateableHashSets(List<HashDb> hashDbs) {
|
||||
@@ -294,25 +308,25 @@ public class HashDbManager {
|
||||
}
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error checking updateable status of hash database at " + db.getDatabasePath(), ex);
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error checking updateable status of " + db.getHashSetName() + " hash database", ex);
|
||||
}
|
||||
}
|
||||
return updateableDbs;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for the flag that indicates whether hashes should be calculated
|
||||
* for content even if no hash databases are configured.
|
||||
*/
|
||||
public synchronized void alwaysCalculateHashes(boolean alwaysCalculateHashes) {
|
||||
public synchronized void setAlwaysCalculateHashes(boolean alwaysCalculateHashes) {
|
||||
this.alwaysCalculateHashes = alwaysCalculateHashes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accesses the flag that indicates whether hashes should be calculated
|
||||
* Gets the flag that indicates whether hashes should be calculated
|
||||
* for content even if no hash databases are configured.
|
||||
*/
|
||||
public synchronized boolean shouldAlwaysCalculateHashes() {
|
||||
public synchronized boolean getAlwaysCalculateHashes() {
|
||||
return alwaysCalculateHashes;
|
||||
}
|
||||
|
||||
@@ -333,6 +347,7 @@ public class HashDbManager {
|
||||
closeHashDatabases(knownHashSets);
|
||||
closeHashDatabases(knownBadHashSets);
|
||||
hashSetNames.clear();
|
||||
hashSetPaths.clear();
|
||||
|
||||
if (hashSetsConfigurationFileExists()) {
|
||||
readHashSetsConfigurationFromDisk();
|
||||
@@ -348,7 +363,7 @@ public class HashDbManager {
|
||||
}
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error closing hash database at " + dbPath, ex);
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error closing hash database at " + dbPath, ex);
|
||||
}
|
||||
hashDbs.clear();
|
||||
}
|
||||
@@ -359,33 +374,30 @@ public class HashDbManager {
|
||||
try {
|
||||
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
|
||||
Document doc = docBuilder.newDocument();
|
||||
Element rootEl = doc.createElement(ROOT_EL);
|
||||
Element rootEl = doc.createElement(ROOT_ELEMENT);
|
||||
doc.appendChild(rootEl);
|
||||
|
||||
writeHashDbsToDisk(doc, rootEl, knownHashSets);
|
||||
writeHashDbsToDisk(doc, rootEl, knownBadHashSets);
|
||||
|
||||
String calcValue = Boolean.toString(alwaysCalculateHashes);
|
||||
Element setCalc = doc.createElement(SET_CALC);
|
||||
setCalc.setAttribute(SET_VALUE, calcValue);
|
||||
Element setCalc = doc.createElement(ALWAYS_CALCULATE_HASHES_ELEMENT);
|
||||
setCalc.setAttribute(VALUE_ATTRIBUTE, calcValue);
|
||||
rootEl.appendChild(setCalc);
|
||||
|
||||
success = XMLUtil.saveDoc(HashDbManager.class, configFilePath, ENCODING, doc);
|
||||
}
|
||||
catch (ParserConfigurationException e) {
|
||||
logger.log(Level.SEVERE, "Error saving hash databases", e);
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error saving hash databases", e);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
private static void writeHashDbsToDisk(Document doc, Element rootEl, List<HashDb> hashDbs) {
|
||||
for (HashDb db : hashDbs) {
|
||||
Element setEl = doc.createElement(SET_EL);
|
||||
setEl.setAttribute(SET_NAME_ATTR, db.getHashSetName());
|
||||
setEl.setAttribute(SET_TYPE_ATTR, db.getKnownFilesType().toString());
|
||||
setEl.setAttribute(SET_USE_FOR_INGEST_ATTR, Boolean.toString(db.getUseForIngest()));
|
||||
setEl.setAttribute(SET_SHOW_INBOX_MESSAGES, Boolean.toString(db.getShowInboxMessages()));
|
||||
String path = null;
|
||||
// Get the path for the hash database before writing anything, in
|
||||
// case an exception is thrown.
|
||||
String path;
|
||||
try {
|
||||
if (db.hasIndexOnly()) {
|
||||
path = db.getIndexPath();
|
||||
@@ -393,21 +405,32 @@ public class HashDbManager {
|
||||
else {
|
||||
path = db.getDatabasePath();
|
||||
}
|
||||
Element pathEl = doc.createElement(PATH_EL);
|
||||
pathEl.setTextContent(path);
|
||||
setEl.appendChild(pathEl);
|
||||
rootEl.appendChild(setEl);
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error getting path of hash database " + db.getHashSetName() + ", unable to save configuration", ex);
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error getting path of hash database " + db.getHashSetName() + ", discarding from hash database configuration", ex);
|
||||
continue;
|
||||
}
|
||||
|
||||
Element setElement = doc.createElement(SET_ELEMENT);
|
||||
setElement.setAttribute(SET_NAME_ATTRIBUTE, db.getHashSetName());
|
||||
setElement.setAttribute(SET_TYPE_ATTRIBUTE, db.getKnownFilesType().toString());
|
||||
setElement.setAttribute(SEARCH_DURING_INGEST_ATTRIBUTE, Boolean.toString(db.getSearchDuringIngest()));
|
||||
setElement.setAttribute(SEND_INGEST_MESSAGES_ATTRIBUTE, Boolean.toString(db.getSendIngestMessages()));
|
||||
Element pathElement = doc.createElement(PATH_ELEMENT);
|
||||
pathElement.setTextContent(path);
|
||||
setElement.appendChild(pathElement);
|
||||
rootEl.appendChild(setElement);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: The return value from this function is never checked. Failure is not indicated to the user. Is this desired?
|
||||
private boolean hashSetsConfigurationFileExists() {
|
||||
File f = new File(configFilePath);
|
||||
return f.exists() && f.canRead() && f.canWrite();
|
||||
}
|
||||
|
||||
private boolean readHashSetsConfigurationFromDisk() {
|
||||
// Open the XML document that implements the configuration file.
|
||||
final Document doc = XMLUtil.loadDoc(HashDbManager.class, configFilePath, XSDFILE);
|
||||
final Document doc = XMLUtil.loadDoc(HashDbManager.class, configFilePath, XSD_FILE_NAME);
|
||||
if (doc == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -415,15 +438,15 @@ public class HashDbManager {
|
||||
// Get the root element.
|
||||
Element root = doc.getDocumentElement();
|
||||
if (root == null) {
|
||||
logger.log(Level.SEVERE, "Error loading hash sets: invalid file format.");
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error loading hash sets: invalid file format.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the hash set elements.
|
||||
NodeList setsNList = root.getElementsByTagName(SET_EL);
|
||||
NodeList setsNList = root.getElementsByTagName(SET_ELEMENT);
|
||||
int numSets = setsNList.getLength();
|
||||
if(numSets == 0) {
|
||||
logger.log(Level.WARNING, "No element hash_set exists.");
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No element hash_set exists.");
|
||||
}
|
||||
|
||||
// Create HashDb objects for each hash set element.
|
||||
@@ -433,9 +456,9 @@ public class HashDbManager {
|
||||
for (int i = 0; i < numSets; ++i) {
|
||||
Element setEl = (Element) setsNList.item(i);
|
||||
|
||||
String hashSetName = setEl.getAttribute(SET_NAME_ATTR);
|
||||
String hashSetName = setEl.getAttribute(SET_NAME_ATTRIBUTE);
|
||||
if (hashSetName.isEmpty()) {
|
||||
logger.log(Level.SEVERE, SET_NAME_ATTR + attributeErrorMessage, i);
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_NAME_ATTRIBUTE + attributeErrorMessage, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -452,71 +475,70 @@ public class HashDbManager {
|
||||
hashSetName = newHashSetName;
|
||||
}
|
||||
|
||||
String knownFilesType = setEl.getAttribute(SET_TYPE_ATTR);
|
||||
String knownFilesType = setEl.getAttribute(SET_TYPE_ATTRIBUTE);
|
||||
if(knownFilesType.isEmpty()) {
|
||||
logger.log(Level.SEVERE, SET_TYPE_ATTR + attributeErrorMessage, i);
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_TYPE_ATTRIBUTE + attributeErrorMessage, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle legacy known files types.
|
||||
if (knownFilesType.equals("NSRL")) {
|
||||
knownFilesType = KnownFilesType.KNOWN.toString();
|
||||
knownFilesType = HashDb.KnownFilesType.KNOWN.toString();
|
||||
}
|
||||
|
||||
final String useForIngest = setEl.getAttribute(SET_USE_FOR_INGEST_ATTR);
|
||||
if (useForIngest.isEmpty()) {
|
||||
logger.log(Level.SEVERE, SET_USE_FOR_INGEST_ATTR + attributeErrorMessage, i);
|
||||
final String searchDuringIngest = setEl.getAttribute(SEARCH_DURING_INGEST_ATTRIBUTE);
|
||||
if (searchDuringIngest.isEmpty()) {
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SEARCH_DURING_INGEST_ATTRIBUTE + attributeErrorMessage, i);
|
||||
continue;
|
||||
}
|
||||
Boolean useForIngestFlag = Boolean.parseBoolean(useForIngest);
|
||||
Boolean seearchDuringIngestFlag = Boolean.parseBoolean(searchDuringIngest);
|
||||
|
||||
final String showInboxMessages = setEl.getAttribute(SET_SHOW_INBOX_MESSAGES);
|
||||
if (useForIngest.isEmpty()) {
|
||||
logger.log(Level.SEVERE, SET_SHOW_INBOX_MESSAGES + attributeErrorMessage, i);
|
||||
final String sendIngestMessages = setEl.getAttribute(SEND_INGEST_MESSAGES_ATTRIBUTE);
|
||||
if (searchDuringIngest.isEmpty()) {
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SEND_INGEST_MESSAGES_ATTRIBUTE + attributeErrorMessage, i);
|
||||
continue;
|
||||
}
|
||||
Boolean showInboxMessagesFlag = Boolean.parseBoolean(showInboxMessages);
|
||||
Boolean sendIngestMessagesFlag = Boolean.parseBoolean(sendIngestMessages);
|
||||
|
||||
String dbPath;
|
||||
NodeList pathsNList = setEl.getElementsByTagName(PATH_EL);
|
||||
NodeList pathsNList = setEl.getElementsByTagName(PATH_ELEMENT);
|
||||
if (pathsNList.getLength() > 0) {
|
||||
Element pathEl = (Element) pathsNList.item(0); // Shouldn't be more than one.
|
||||
dbPath = pathEl.getTextContent();
|
||||
if (dbPath.isEmpty()) {
|
||||
logger.log(Level.SEVERE, PATH_EL + elementErrorMessage, i);
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
logger.log(Level.SEVERE, PATH_EL + elementErrorMessage, i);
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i);
|
||||
continue;
|
||||
}
|
||||
dbPath = getValidFilePath(hashSetName, dbPath);
|
||||
|
||||
if (null != dbPath) {
|
||||
try {
|
||||
addHashSet(HashDb.openHashDatabase(hashSetName, dbPath, useForIngestFlag, showInboxMessagesFlag, KnownFilesType.valueOf(knownFilesType)));
|
||||
hashSetNames.add(hashSetName);
|
||||
addExistingHashDatabase(hashSetName, dbPath, seearchDuringIngestFlag, sendIngestMessagesFlag, HashDb.KnownFilesType.valueOf(knownFilesType));
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
catch (HashDatabaseDoesNotExistException | DuplicateHashSetNameException | HashDatabaseAlreadyAddedException | TskCoreException ex) {
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex);
|
||||
JOptionPane.showMessageDialog(null, "Unable to open " + dbPath + " hash database.", "Open Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
logger.log(Level.WARNING, "No valid path for hash_set at index {0}, cannot make instance of HashDb class", i);
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No valid path for hash_set at index {0}, cannot make instance of HashDb class", i);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the element that stores the always calculate hashes flag.
|
||||
NodeList calcList = root.getElementsByTagName(SET_CALC);
|
||||
NodeList calcList = root.getElementsByTagName(ALWAYS_CALCULATE_HASHES_ELEMENT);
|
||||
if (calcList.getLength() > 0) {
|
||||
Element calcEl = (Element) calcList.item(0); // Shouldn't be more than one.
|
||||
final String value = calcEl.getAttribute(SET_VALUE);
|
||||
final String value = calcEl.getAttribute(VALUE_ATTRIBUTE);
|
||||
alwaysCalculateHashes = Boolean.parseBoolean(value);
|
||||
}
|
||||
else {
|
||||
logger.log(Level.WARNING, " element ");
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, " element ");
|
||||
alwaysCalculateHashes = false;
|
||||
}
|
||||
|
||||
@@ -566,7 +588,7 @@ public class HashDbManager {
|
||||
filePath = f.getCanonicalPath();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Couldn't get selected file path", ex);
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "Couldn't get selected file path", ex);
|
||||
}
|
||||
}
|
||||
return filePath;
|
||||
@@ -576,6 +598,26 @@ public class HashDbManager {
|
||||
* Instances of this class represent hash databases used to classify files as known or know bad.
|
||||
*/
|
||||
public static class HashDb {
|
||||
|
||||
/**
|
||||
* Indicates how files with hashes stored in a particular hash database
|
||||
* object should be classified.
|
||||
*/
|
||||
public enum KnownFilesType{
|
||||
KNOWN("Known"),
|
||||
KNOWN_BAD("Known Bad");
|
||||
|
||||
private String displayName;
|
||||
|
||||
private KnownFilesType(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return this.displayName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Property change events published by hash database objects.
|
||||
*/
|
||||
@@ -584,53 +626,19 @@ public class HashDbManager {
|
||||
}
|
||||
|
||||
private int handle;
|
||||
private KnownFilesType knownFilesType;
|
||||
private String databasePath;
|
||||
private String indexPath;
|
||||
private String hashSetName;
|
||||
private boolean useForIngest;
|
||||
private boolean sendHitMessages;
|
||||
private boolean searchDuringIngest;
|
||||
private boolean sendIngestMessages;
|
||||
private KnownFilesType knownFilesType;
|
||||
private boolean indexing;
|
||||
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
|
||||
/**
|
||||
* Opens an existing hash database.
|
||||
* @param hashSetName Name used to represent the hash database in user interface components.
|
||||
* @param selectedFilePath Full path to either a hash database file or a hash database index file.
|
||||
* @param useForIngest A flag indicating whether or not the hash database should be used during ingest.
|
||||
* @param sendHitMessages A flag indicating whether hash set hit messages should be sent to the application in box.
|
||||
* @param knownFilesType The classification to apply to files whose hashes are stored in the hash database.
|
||||
* @return A HashDb object representation of the new hash database.
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
public static HashDb openHashDatabase(String hashSetName, String selectedFilePath, boolean useForIngest, boolean sendHitMessages, KnownFilesType knownFilesType) throws TskCoreException {
|
||||
int handle = SleuthkitJNI.openHashDatabase(selectedFilePath);
|
||||
return new HashDb(handle, SleuthkitJNI.getHashDatabasePath(handle), SleuthkitJNI.getHashDatabaseIndexPath(handle), hashSetName, useForIngest, sendHitMessages, knownFilesType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new hash database.
|
||||
* @param hashSetName Hash set name used to represent the hash database in user interface components.
|
||||
* @param databasePath Full path to the database file to be created. The file name component of the path must have a ".kdb" extension.
|
||||
* @param useForIngest A flag indicating whether or not the data base should be used during the file ingest process.
|
||||
* @param showInboxMessages A flag indicating whether messages indicating lookup hits should be sent to the application in box.
|
||||
* @param hashSetType The type of hash set to associate with the database.
|
||||
* @return A HashDb object representation of the opened hash database.
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
public static HashDb createHashDatabase(String hashSetName, String databasePath, boolean useForIngest, boolean showInboxMessages, KnownFilesType knownFilesType) throws TskCoreException {
|
||||
int handle = SleuthkitJNI.createHashDatabase(databasePath);
|
||||
return new HashDb(handle, SleuthkitJNI.getHashDatabasePath(handle), SleuthkitJNI.getHashDatabaseIndexPath(handle), hashSetName, useForIngest, showInboxMessages, knownFilesType);
|
||||
}
|
||||
|
||||
private HashDb(int handle, String databasePath, String indexPath, String name, boolean useForIngest, boolean sendHitMessages, KnownFilesType knownFilesType) {
|
||||
this.databasePath = databasePath;
|
||||
this.indexPath = indexPath;
|
||||
this.hashSetName = name;
|
||||
this.useForIngest = useForIngest;
|
||||
this.sendHitMessages = sendHitMessages;
|
||||
this.knownFilesType = knownFilesType;
|
||||
private HashDb(int handle, String hashSetName, boolean useForIngest, boolean sendHitMessages, KnownFilesType knownFilesType) {
|
||||
this.handle = handle;
|
||||
this.hashSetName = hashSetName;
|
||||
this.searchDuringIngest = useForIngest;
|
||||
this.sendIngestMessages = sendHitMessages;
|
||||
this.knownFilesType = knownFilesType;
|
||||
this.indexing = false;
|
||||
}
|
||||
|
||||
@@ -652,45 +660,45 @@ public class HashDbManager {
|
||||
return hashSetName;
|
||||
}
|
||||
|
||||
public String getDatabasePath() {
|
||||
return databasePath;
|
||||
public String getDatabasePath() throws TskCoreException {
|
||||
return SleuthkitJNI.getHashDatabasePath(handle);
|
||||
}
|
||||
|
||||
public String getIndexPath() {
|
||||
return indexPath;
|
||||
public String getIndexPath() throws TskCoreException {
|
||||
return SleuthkitJNI.getHashDatabaseIndexPath(handle);
|
||||
}
|
||||
|
||||
public KnownFilesType getKnownFilesType() {
|
||||
return knownFilesType;
|
||||
}
|
||||
|
||||
public boolean getUseForIngest() {
|
||||
return useForIngest;
|
||||
public boolean getSearchDuringIngest() {
|
||||
return searchDuringIngest;
|
||||
}
|
||||
|
||||
void setUseForIngest(boolean useForIngest) {
|
||||
this.useForIngest = useForIngest;
|
||||
void setSearchDuringIngest(boolean useForIngest) {
|
||||
this.searchDuringIngest = useForIngest;
|
||||
}
|
||||
|
||||
public boolean getShowInboxMessages() {
|
||||
return sendHitMessages;
|
||||
public boolean getSendIngestMessages() {
|
||||
return sendIngestMessages;
|
||||
}
|
||||
|
||||
void setShowInboxMessages(boolean showInboxMessages) {
|
||||
this.sendHitMessages = showInboxMessages;
|
||||
void setSendIngestMessages(boolean showInboxMessages) {
|
||||
this.sendIngestMessages = showInboxMessages;
|
||||
}
|
||||
|
||||
public boolean hasLookupIndex() throws TskCoreException {
|
||||
return SleuthkitJNI.hashDatabaseHasLookupIndex(handle);
|
||||
}
|
||||
|
||||
public boolean canBeReindexed() throws TskCoreException {
|
||||
return SleuthkitJNI.hashDatabaseCanBeReindexed(handle);
|
||||
}
|
||||
|
||||
public boolean hasIndexOnly() throws TskCoreException {
|
||||
return SleuthkitJNI.hashDatabaseHasLegacyLookupIndexOnly(handle);
|
||||
}
|
||||
|
||||
public boolean canBeReIndexed() throws TskCoreException {
|
||||
return SleuthkitJNI.hashDatabaseCanBeReindexed(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the hash database accepts updates.
|
||||
@@ -705,8 +713,8 @@ public class HashDbManager {
|
||||
* @param content The content for which the calculated hashes, if any, are to be added to the hash database.
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
public void add(Content content) throws TskCoreException {
|
||||
add(content, null);
|
||||
public void addHashes(Content content) throws TskCoreException {
|
||||
addHashes(content, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -715,7 +723,7 @@ public class HashDbManager {
|
||||
* @param comment A comment to associate with the hashes, e.g., the name of the case in which the content was encountered.
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
public void add(Content content, String comment) throws TskCoreException {
|
||||
public void addHashes(Content content, String comment) throws TskCoreException {
|
||||
// TODO: This only works for AbstractFiles at present. Change when Content
|
||||
// can be queried for hashes.
|
||||
assert content instanceof AbstractFile;
|
||||
@@ -728,13 +736,11 @@ public class HashDbManager {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasHashOfContent(Content content) throws TskCoreException {
|
||||
public boolean hasMd5HashOf(Content content) throws TskCoreException {
|
||||
boolean result = false;
|
||||
// TODO: This only works for AbstractFiles at present. Change when Content can be queried for hashes.
|
||||
assert content instanceof AbstractFile;
|
||||
if (content instanceof AbstractFile) {
|
||||
AbstractFile file = (AbstractFile)content;
|
||||
// TODO: Add support for SHA-1 and SHA-256 hashes.
|
||||
if (null != file.getMd5Hash()) {
|
||||
result = SleuthkitJNI.lookupInHashDatabase(file.getMd5Hash(), handle);
|
||||
}
|
||||
@@ -783,7 +789,6 @@ public class HashDbManager {
|
||||
progress.switchToIndeterminate();
|
||||
try {
|
||||
SleuthkitJNI.createLookupIndexForHashDatabase(handle, deleteIndexFile);
|
||||
indexPath = SleuthkitJNI.getHashDatabaseIndexPath(handle);
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDb.class.getName()).log(Level.SEVERE, "Error indexing hash database", ex);
|
||||
@@ -800,7 +805,7 @@ public class HashDbManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws TskCoreException {
|
||||
private void close() throws TskCoreException {
|
||||
SleuthkitJNI.closeHashDatabase(handle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="jScrollPane2" alignment="1" pref="0" max="32767" attributes="1"/>
|
||||
<Component id="calcHashesButton" alignment="1" max="32767" attributes="0"/>
|
||||
<Component id="alwaysCalcHashesCheckbox" alignment="1" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
@@ -46,7 +46,7 @@
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane2" min="-2" pref="55" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="32767" attributes="0"/>
|
||||
<Component id="calcHashesButton" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="alwaysCalcHashesCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
@@ -92,10 +92,10 @@
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="calcHashesButton">
|
||||
<Component class="javax.swing.JCheckBox" name="alwaysCalcHashesCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbSimpleConfigPanel.calcHashesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbSimpleConfigPanel.alwaysCalcHashesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
|
||||
@@ -30,6 +30,7 @@ import javax.swing.table.TableColumn;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb;
|
||||
|
||||
/**
|
||||
* Instances of this class provide a simplified UI for managing the hash sets configuration.
|
||||
@@ -39,8 +40,8 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
|
||||
private HashDbsTableModel knownBadTableModel;
|
||||
|
||||
public HashDbSimpleConfigPanel() {
|
||||
knownTableModel = new HashDbsTableModel(HashDbManager.getInstance().getKnownHashSets());
|
||||
knownBadTableModel = new HashDbsTableModel(HashDbManager.getInstance().getKnownBadHashSets());
|
||||
knownTableModel = new HashDbsTableModel(HashDbManager.getInstance().getKnownFileHashSets());
|
||||
knownBadTableModel = new HashDbsTableModel(HashDbManager.getInstance().getKnownBadFileHashSets());
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
}
|
||||
@@ -51,10 +52,10 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
|
||||
|
||||
// Add a listener to the always calculate hashes checkbox component.
|
||||
// The listener passes the user's selection on to the hash database manager.
|
||||
calcHashesButton.addActionListener( new ActionListener() {
|
||||
alwaysCalcHashesCheckbox.addActionListener( new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
HashDbManager.getInstance().alwaysCalculateHashes(calcHashesButton.isSelected());
|
||||
HashDbManager.getInstance().setAlwaysCalculateHashes(alwaysCalcHashesCheckbox.isSelected());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -82,33 +83,33 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
|
||||
public void refreshComponents() {
|
||||
knownTableModel.refresh();
|
||||
knownBadTableModel.refresh();
|
||||
refreshAlwaysCalcHashesComponents();
|
||||
refreshAlwaysCalcHashesCheckbox();
|
||||
}
|
||||
|
||||
private void refreshAlwaysCalcHashesComponents() {
|
||||
private void refreshAlwaysCalcHashesCheckbox() {
|
||||
boolean noHashDbsConfiguredForIngest = true;
|
||||
for (HashDb hashDb : HashDbManager.getInstance().getAllHashSets()) {
|
||||
try {
|
||||
if (hashDb.getUseForIngest()== true && hashDb.hasLookupIndex()) {
|
||||
if (hashDb.getSearchDuringIngest()== true && hashDb.hasLookupIndex()) {
|
||||
noHashDbsConfiguredForIngest = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbSimpleConfigPanel.class.getName()).log(Level.SEVERE, "Error getting info for hash database at " + hashDb.getDatabasePath(), ex);
|
||||
Logger.getLogger(HashDbSimpleConfigPanel.class.getName()).log(Level.SEVERE, "Error getting info for " + hashDb.getHashSetName() + " hash database", ex);
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no hash databases configured for use during file ingest,
|
||||
// default to always calculating hashes of the files.
|
||||
if (noHashDbsConfiguredForIngest) {
|
||||
calcHashesButton.setEnabled(true);
|
||||
calcHashesButton.setSelected(true);
|
||||
HashDbManager.getInstance().alwaysCalculateHashes(true);
|
||||
alwaysCalcHashesCheckbox.setEnabled(true);
|
||||
alwaysCalcHashesCheckbox.setSelected(true);
|
||||
HashDbManager.getInstance().setAlwaysCalculateHashes(true);
|
||||
} else {
|
||||
calcHashesButton.setEnabled(false);
|
||||
calcHashesButton.setSelected(false);
|
||||
HashDbManager.getInstance().alwaysCalculateHashes(false);
|
||||
alwaysCalcHashesCheckbox.setEnabled(false);
|
||||
alwaysCalcHashesCheckbox.setSelected(false);
|
||||
HashDbManager.getInstance().setAlwaysCalculateHashes(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +138,7 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
HashDb db = hashDbs.get(rowIndex);
|
||||
if (columnIndex == 0) {
|
||||
return db.getUseForIngest();
|
||||
return db.getSearchDuringIngest();
|
||||
} else {
|
||||
return db.getHashSetName();
|
||||
}
|
||||
@@ -157,10 +158,10 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
|
||||
dbHasIndex = db.hasLookupIndex();
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbSimpleConfigPanel.class.getName()).log(Level.SEVERE, "Error getting info for hash database at " + db.getDatabasePath(), ex);
|
||||
Logger.getLogger(HashDbSimpleConfigPanel.class.getName()).log(Level.SEVERE, "Error getting info for " + db.getHashSetName() + " hash database", ex);
|
||||
}
|
||||
if(((Boolean) getValueAt(rowIndex, columnIndex)) || dbHasIndex) {
|
||||
db.setUseForIngest((Boolean) aValue);
|
||||
db.setSearchDuringIngest((Boolean) aValue);
|
||||
}
|
||||
else {
|
||||
JOptionPane.showMessageDialog(HashDbSimpleConfigPanel.this, "Hash databases must be indexed before they can be used for ingest");
|
||||
@@ -187,7 +188,7 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
|
||||
knownHashTable = new javax.swing.JTable();
|
||||
knownBadHashDbsLabel = new javax.swing.JLabel();
|
||||
knownHashDbsLabel = new javax.swing.JLabel();
|
||||
calcHashesButton = new javax.swing.JCheckBox();
|
||||
alwaysCalcHashesCheckbox = new javax.swing.JCheckBox();
|
||||
jScrollPane2 = new javax.swing.JScrollPane();
|
||||
knownBadHashTable = new javax.swing.JTable();
|
||||
|
||||
@@ -202,7 +203,7 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
|
||||
|
||||
knownHashDbsLabel.setText(org.openide.util.NbBundle.getMessage(HashDbSimpleConfigPanel.class, "HashDbSimpleConfigPanel.knownHashDbsLabel.text")); // NOI18N
|
||||
|
||||
calcHashesButton.setText(org.openide.util.NbBundle.getMessage(HashDbSimpleConfigPanel.class, "HashDbSimpleConfigPanel.calcHashesButton.text")); // NOI18N
|
||||
alwaysCalcHashesCheckbox.setText(org.openide.util.NbBundle.getMessage(HashDbSimpleConfigPanel.class, "HashDbSimpleConfigPanel.alwaysCalcHashesCheckbox.text")); // NOI18N
|
||||
|
||||
jScrollPane2.setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||
|
||||
@@ -233,7 +234,7 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
|
||||
.addComponent(knownBadHashDbsLabel))
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
|
||||
.addComponent(calcHashesButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addComponent(alwaysCalcHashesCheckbox, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
@@ -248,13 +249,13 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(calcHashesButton)
|
||||
.addComponent(alwaysCalcHashesCheckbox)
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JCheckBox calcHashesButton;
|
||||
private javax.swing.JCheckBox alwaysCalcHashesCheckbox;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JScrollPane jScrollPane2;
|
||||
private javax.swing.JLabel knownBadHashDbsLabel;
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.util.logging.Level;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb;
|
||||
|
||||
/**
|
||||
* This class exists as a stop-gap measure to force users to have an indexed database.
|
||||
|
||||
Reference in New Issue
Block a user