Made hash lookup module and settings panels work with settings

This commit is contained in:
Richard Cordovano 2014-03-26 15:18:37 -04:00
parent f3ba1f9c80
commit 819e10c2eb
8 changed files with 174 additions and 104 deletions

View File

@ -290,7 +290,7 @@ final class IngestJob {
Map<String, FileIngestModuleDecorator> modulesByClass = new HashMap<>(); Map<String, FileIngestModuleDecorator> modulesByClass = new HashMap<>();
for (IngestModuleTemplate template : moduleTemplates) { for (IngestModuleTemplate template : moduleTemplates) {
if (template.isFileIngestModuleTemplate()) { if (template.isFileIngestModuleTemplate()) {
FileIngestModuleDecorator module = new FileIngestModuleDecorator(template.createFileIngestModule(), template.getModuleName()); FileIngestModuleDecorator module = new FileIngestModuleDecorator(template.createFileIngestModule(), template.getModuleName()); // RJCTODO: Move into try block for bpth impls
IngestJobContext context = new IngestJobContext(task); IngestJobContext context = new IngestJobContext(task);
try { try {
module.startUp(context); module.startUp(context);

View File

@ -152,7 +152,7 @@ public interface IngestModuleFactory {
* @param ingestOptions Per ingest job options to initialize the panel. * @param ingestOptions Per ingest job options to initialize the panel.
* @return A user interface panel. * @return A user interface panel.
*/ */
IngestModuleIngestJobSettingsPanel getModuleSettingsPanel(IngestModuleIngestJobSettings settings); IngestModuleIngestJobSettingsPanel getModuleSettingsPanel(IngestModuleIngestJobSettings settings); // RJCTODO: Can these be made into generics?
/** /**
* Queries the factory to determine if it is capable of creating file ingest * Queries the factory to determine if it is capable of creating file ingest

View File

@ -87,8 +87,6 @@ public class HashDbIngestModule extends IngestModuleAdapter implements FileInges
} }
private void getEnabledHashSets(List<HashDb> hashSets, List<HashDb> enabledHashSets) { private void getEnabledHashSets(List<HashDb> hashSets, List<HashDb> enabledHashSets) {
assert hashSets != null;
assert enabledHashSets != null;
enabledHashSets.clear(); enabledHashSets.clear();
for (HashDb db : hashSets) { for (HashDb db : hashSets) {
if (settings.isHashSetEnabled(db.getHashSetName())) { if (settings.isHashSetEnabled(db.getHashSetName())) {

View File

@ -94,7 +94,7 @@ public class HashDbManager implements PropertyChangeListener {
*/ */
public enum SetEvt { public enum SetEvt {
DB_ADDED, DB_DELETED DB_ADDED, DB_DELETED, DB_INDEXED
}; };
/** /**
@ -1018,6 +1018,7 @@ public class HashDbManager implements PropertyChangeListener {
try { try {
hashDb.propertyChangeSupport.firePropertyChange(HashDb.Event.INDEXING_DONE.toString(), null, hashDb); hashDb.propertyChangeSupport.firePropertyChange(HashDb.Event.INDEXING_DONE.toString(), null, hashDb);
hashDb.propertyChangeSupport.firePropertyChange(HashDbManager.SetEvt.DB_INDEXED.toString(), null, hashDb.getHashSetName());
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "HashDbManager listener threw exception", e); logger.log(Level.SEVERE, "HashDbManager listener threw exception", e);
MessageNotifyUtil.Notify.show( MessageNotifyUtil.Notify.show(

View File

@ -59,21 +59,19 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter {
@Override @Override
public IngestModuleIngestJobSettings getDefaultModuleSettings() { public IngestModuleIngestJobSettings getDefaultModuleSettings() {
// All available hash sets are enabled by default.
HashDbManager hashDbManager = HashDbManager.getInstance(); HashDbManager hashDbManager = HashDbManager.getInstance();
List<String> enabledHashSets = new ArrayList<>(); List<String> knownHashSetNames = getHashSetNames(hashDbManager.getKnownFileHashSets());
List<HashDbManager.HashDb> knownFileHashSets = hashDbManager.getKnownFileHashSets(); List<String> knownBadHashSetNames = getHashSetNames(hashDbManager.getKnownBadFileHashSets());
for (HashDbManager.HashDb db : knownFileHashSets) { return new HashLookupModuleSettings(hashDbManager.getAlwaysCalculateHashes(), knownHashSetNames, knownBadHashSetNames);
if (db.getSearchDuringIngest()) {
enabledHashSets.add(db.getHashSetName());
} }
private List<String> getHashSetNames(List<HashDbManager.HashDb> hashDbs) {
List<String> hashSetNames = new ArrayList<>();
for (HashDbManager.HashDb db : hashDbs) {
hashSetNames.add(db.getHashSetName());
} }
List<HashDbManager.HashDb> knownBadFileHashSets = hashDbManager.getKnownBadFileHashSets(); return hashSetNames;
for (HashDbManager.HashDb db : knownBadFileHashSets) {
if (db.getSearchDuringIngest()) {
enabledHashSets.add(db.getHashSetName());
}
}
return new HashLookupModuleSettings(hashDbManager.getAlwaysCalculateHashes(), enabledHashSets);
} }
@Override @Override
@ -83,10 +81,14 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter {
@Override @Override
public IngestModuleIngestJobSettingsPanel getModuleSettingsPanel(IngestModuleIngestJobSettings settings) { public IngestModuleIngestJobSettingsPanel getModuleSettingsPanel(IngestModuleIngestJobSettings settings) {
if (moduleSettingsPanel == null) { if (!(settings instanceof HashLookupModuleSettings)) {
moduleSettingsPanel = new HashLookupModuleSettingsPanel(); throw new IllegalArgumentException("Expected settings argument to be instanceof HashLookupModuleSettings");
}
if (moduleSettingsPanel == null) {
moduleSettingsPanel = new HashLookupModuleSettingsPanel((HashLookupModuleSettings) settings);
} else {
moduleSettingsPanel.reset((HashLookupModuleSettings) settings);
} }
moduleSettingsPanel.load(); // RJCTODO: Fix this, use passed in settings
return moduleSettingsPanel; return moduleSettingsPanel;
} }
@ -109,7 +111,6 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter {
@Override @Override
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) { public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) {
assert settings instanceof HashLookupModuleSettings;
if (!(settings instanceof HashLookupModuleSettings)) { if (!(settings instanceof HashLookupModuleSettings)) {
throw new IllegalArgumentException("Expected settings argument to be instanceof HashLookupModuleSettings"); throw new IllegalArgumentException("Expected settings argument to be instanceof HashLookupModuleSettings");
} }

View File

@ -18,6 +18,7 @@
*/ */
package org.sleuthkit.autopsy.hashdatabase; package org.sleuthkit.autopsy.hashdatabase;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
@ -27,14 +28,14 @@ import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
*/ */
final class HashLookupModuleSettings implements IngestModuleIngestJobSettings { final class HashLookupModuleSettings implements IngestModuleIngestJobSettings {
private final HashSet<String> enabledHashSets = new HashSet<>(); private final HashSet<String> namesOfEnabledKnownHashSets = new HashSet<>();
private final HashSet<String> namesOfEnabledKnownBadHashSets = new HashSet<>();
private boolean shouldCalculateHashes = true; private boolean shouldCalculateHashes = true;
HashLookupModuleSettings(boolean shouldCalculateHashes, List<String> enabledHashSetNames) { HashLookupModuleSettings(boolean shouldCalculateHashes, List<String> namesOfEnabledKnownHashSets, List<String> namesOfEnabledKnownBadHashSets) {
this.shouldCalculateHashes = shouldCalculateHashes; this.shouldCalculateHashes = shouldCalculateHashes;
for (String hashSet : enabledHashSetNames) { this.namesOfEnabledKnownHashSets.addAll(namesOfEnabledKnownHashSets);
enabledHashSets.add(hashSet); this.namesOfEnabledKnownBadHashSets.addAll(namesOfEnabledKnownBadHashSets);
}
} }
boolean shouldCalculateHashes() { boolean shouldCalculateHashes() {
@ -42,6 +43,14 @@ final class HashLookupModuleSettings implements IngestModuleIngestJobSettings {
} }
boolean isHashSetEnabled(String hashSetName) { boolean isHashSetEnabled(String hashSetName) {
return enabledHashSets.contains(hashSetName); return (namesOfEnabledKnownHashSets.contains(hashSetName) || namesOfEnabledKnownBadHashSets.contains(hashSetName));
}
List<String> getNamesOfEnabledKnownHashSets() {
return new ArrayList<>(namesOfEnabledKnownHashSets);
}
List<String> getNamesOfEnabledKnownBadHashSets() {
return new ArrayList<>(namesOfEnabledKnownBadHashSets);
} }
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 - 2014 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -21,51 +21,61 @@ package org.sleuthkit.autopsy.hashdatabase;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn; import javax.swing.table.TableColumn;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb; import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel; import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
/** /**
* Instances of this class provide a simplified UI for managing the hash sets * Ingest job settings panel for hash lookup file ingest modules.
* configuration.
*/ */
public class HashLookupModuleSettingsPanel extends IngestModuleIngestJobSettingsPanel implements PropertyChangeListener { public final class HashLookupModuleSettingsPanel extends IngestModuleIngestJobSettingsPanel implements PropertyChangeListener {
private final HashDbManager hashDbManager = HashDbManager.getInstance(); private final HashDbManager hashDbManager = HashDbManager.getInstance();
private HashDatabasesTableModel knownTableModel; private final List<HashSetModel> knownHashSetModels = new ArrayList<>();
private HashDatabasesTableModel knownBadTableModel; private final HashSetsTableModel knownHashSetsTableModel = new HashSetsTableModel(knownHashSetModels);
private final List<HashSetModel> knownBadHashSetModels = new ArrayList<>();
private final HashSetsTableModel knownBadHashSetsTableModel = new HashSetsTableModel(knownBadHashSetModels);
HashLookupModuleSettingsPanel() { HashLookupModuleSettingsPanel(HashLookupModuleSettings settings) {
knownTableModel = new HashDatabasesTableModel(HashDbManager.HashDb.KnownFilesType.KNOWN); initializeHashSetModels(settings);
knownBadTableModel = new HashDatabasesTableModel(HashDbManager.HashDb.KnownFilesType.KNOWN_BAD);
initComponents(); initComponents();
customizeComponents(); customizeComponents();
} }
private void initializeHashSetModels(HashLookupModuleSettings settings) {
initializeHashSetModels(settings, hashDbManager.getKnownFileHashSets(), knownHashSetModels);
initializeHashSetModels(settings, hashDbManager.getKnownBadFileHashSets(), knownBadHashSetModels);
}
private void initializeHashSetModels(HashLookupModuleSettings settings, List<HashDb> hashDbs, List<HashSetModel> hashSetModels) {
hashSetModels.clear();
for (HashDb db : hashDbs) {
String name = db.getHashSetName();
hashSetModels.add(new HashSetModel(name, settings.isHashSetEnabled(name), isHashDbIndexed(db)));
}
}
private void customizeComponents() { private void customizeComponents() {
customizeHashDbsTable(jScrollPane1, knownHashTable, knownTableModel); customizeHashSetsTable(jScrollPane1, knownHashTable, knownHashSetsTableModel);
customizeHashDbsTable(jScrollPane2, knownBadHashTable, knownBadTableModel); customizeHashSetsTable(jScrollPane2, knownBadHashTable, knownBadHashSetsTableModel);
alwaysCalcHashesCheckbox.setSelected(hashDbManager.getAlwaysCalculateHashes()); alwaysCalcHashesCheckbox.setSelected(hashDbManager.getAlwaysCalculateHashes());
load();
hashDbManager.addPropertyChangeListener(this); hashDbManager.addPropertyChangeListener(this);
} }
private void customizeHashDbsTable(JScrollPane scrollPane, JTable table, HashDatabasesTableModel tableModel) { private void customizeHashSetsTable(JScrollPane scrollPane, JTable table, HashSetsTableModel tableModel) {
table.setModel(tableModel); table.setModel(tableModel);
table.setTableHeader(null); table.setTableHeader(null);
table.setRowSelectionAllowed(false); table.setRowSelectionAllowed(false);
final int width1 = scrollPane.getPreferredSize().width; final int width1 = scrollPane.getPreferredSize().width;
knownHashTable.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN); knownHashTable.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
TableColumn column; TableColumn column;
@ -81,65 +91,132 @@ public class HashLookupModuleSettingsPanel extends IngestModuleIngestJobSettings
@Override @Override
public void propertyChange(PropertyChangeEvent event) { public void propertyChange(PropertyChangeEvent event) {
if (event.getPropertyName().equals(HashDbManager.SetEvt.DB_ADDED.name()) || if (event.getPropertyName().equals(HashDbManager.SetEvt.DB_ADDED.name())
event.getPropertyName().equals(HashDbManager.SetEvt.DB_DELETED.name())) { || event.getPropertyName().equals(HashDbManager.SetEvt.DB_DELETED.name())
load(); || event.getPropertyName().equals(HashDbManager.SetEvt.DB_INDEXED.name())) {
update();
} }
} }
@Override @Override
public IngestModuleIngestJobSettings getSettings() { public IngestModuleIngestJobSettings getSettings() {
List<String> enabledHashSets = new ArrayList<>(); return new HashLookupModuleSettings(alwaysCalcHashesCheckbox.isSelected(),
List<HashDbManager.HashDb> knownFileHashSets = hashDbManager.getKnownFileHashSets(); getNamesOfEnabledHashSets(knownHashSetModels),
for (HashDb db : knownFileHashSets) { getNamesOfEnabledHashSets(knownBadHashSetModels));
if (db.getSearchDuringIngest()) {
enabledHashSets.add(db.getHashSetName());
}
}
List<HashDbManager.HashDb> knownBadFileHashSets = hashDbManager.getKnownBadFileHashSets();
for (HashDb db : knownBadFileHashSets) {
if (db.getSearchDuringIngest()) {
enabledHashSets.add(db.getHashSetName());
}
}
return new HashLookupModuleSettings(alwaysCalcHashesCheckbox.isSelected(), enabledHashSets);
} }
void load() { private List<String> getNamesOfEnabledHashSets(List<HashSetModel> hashSetModels) {
knownTableModel.load(); List<String> namesOfEnabledHashSets = new ArrayList<>();
knownBadTableModel.load(); for (HashSetModel model : hashSetModels) {
if (model.isEnabled() && model.isIndexed()) {
namesOfEnabledHashSets.add(model.getName());
}
}
return namesOfEnabledHashSets;
} }
void store() { void update() {
hashDbManager.save(); updateHashSetModels();
knownHashSetsTableModel.fireTableDataChanged();
knownBadHashSetsTableModel.fireTableDataChanged();
} }
private class HashDatabasesTableModel extends AbstractTableModel { private void updateHashSetModels() {
updateHashSetModels(hashDbManager.getKnownFileHashSets(), knownHashSetModels);
private final HashDbManager.HashDb.KnownFilesType hashDatabasesType; updateHashSetModels(hashDbManager.getKnownBadFileHashSets(), knownBadHashSetModels);
private List<HashDb> hashDatabases;
HashDatabasesTableModel(HashDbManager.HashDb.KnownFilesType hashDatabasesType) {
this.hashDatabasesType = hashDatabasesType;
getHashDatabases();
} }
private void getHashDatabases() { void updateHashSetModels(List<HashDb> hashDbs, List<HashSetModel> hashSetModels) {
if (HashDbManager.HashDb.KnownFilesType.KNOWN == hashDatabasesType) { Map<String, HashDb> hashSetDbs = new HashMap<>();
hashDatabases = hashDbManager.getKnownFileHashSets(); for (HashDb db : hashDbs) {
hashSetDbs.put(db.getHashSetName(), db);
}
// Update the hash sets and detect deletions.
List<HashSetModel> deletedHashSetModels = new ArrayList<>();
for (HashSetModel model : hashSetModels) {
String hashSetName = model.getName();
if (hashSetDbs.containsKey(hashSetName)) {
HashDb db = hashSetDbs.get(hashSetName);
model.setIndexed(isHashDbIndexed(db));
hashSetDbs.remove(hashSetName);
} else { } else {
hashDatabases = hashDbManager.getKnownBadFileHashSets(); deletedHashSetModels.add(model);
} }
} }
private void load() { // Remove the deleted hash sets.
getHashDatabases(); for (HashSetModel model : deletedHashSetModels) {
fireTableDataChanged(); hashSetModels.remove(model);
}
// Add any new hash sets. All new sets are enabled by default.
for (HashDb db : hashSetDbs.values()) {
String name = db.getHashSetName();
hashSetModels.add(new HashSetModel(name, true, isHashDbIndexed(db)));
}
}
void reset(HashLookupModuleSettings newSettings) {
initializeHashSetModels(newSettings);
knownHashSetsTableModel.fireTableDataChanged();
knownBadHashSetsTableModel.fireTableDataChanged();
}
private boolean isHashDbIndexed(HashDb hashDb) {
boolean indexed = false;
try {
indexed = hashDb.hasIndex();
} catch (TskCoreException ex) {
Logger.getLogger(HashLookupModuleSettingsPanel.class.getName()).log(Level.SEVERE, "Error getting indexed status info for hash set (name = " + hashDb.getHashSetName() + ")", ex);
}
return indexed;
}
private static final class HashSetModel {
private final String name;
private boolean indexed;
private boolean enabled;
HashSetModel(String name, boolean enabled, boolean indexed) {
this.name = name;
this.enabled = enabled;
this.indexed = indexed;
}
String getName() {
return name;
}
void setEnabled(boolean enabled) {
this.enabled = enabled;
}
boolean isEnabled() {
return enabled;
}
void setIndexed(boolean indexed) {
this.indexed = indexed;
}
boolean isIndexed() {
return indexed;
}
}
private static final class HashSetsTableModel extends AbstractTableModel {
private final List<HashSetModel> hashSets;
HashSetsTableModel(List<HashSetModel> hashSets) {
this.hashSets = hashSets;
} }
@Override @Override
public int getRowCount() { public int getRowCount() {
return hashDatabases.size(); return hashSets.size();
} }
@Override @Override
@ -149,36 +226,22 @@ public class HashLookupModuleSettingsPanel extends IngestModuleIngestJobSettings
@Override @Override
public Object getValueAt(int rowIndex, int columnIndex) { public Object getValueAt(int rowIndex, int columnIndex) {
HashDb db = hashDatabases.get(rowIndex);
if (columnIndex == 0) { if (columnIndex == 0) {
return db.getSearchDuringIngest(); return hashSets.get(rowIndex).isEnabled();
} else { } else {
return db.getHashSetName(); return hashSets.get(rowIndex).getName();
} }
} }
@Override @Override
public boolean isCellEditable(int rowIndex, int columnIndex) { public boolean isCellEditable(int rowIndex, int columnIndex) {
return !IngestManager.getDefault().isIngestRunning() && columnIndex == 0; return (columnIndex == 0 && hashSets.get(rowIndex).isIndexed());
} }
@Override @Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) { public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (columnIndex == 0) { if (columnIndex == 0) {
HashDb db = hashDatabases.get(rowIndex); hashSets.get(rowIndex).setEnabled((Boolean) aValue);
boolean dbHasIndex = false;
try {
dbHasIndex = db.hasIndex();
} catch (TskCoreException ex) {
Logger.getLogger(HashLookupModuleSettingsPanel.class.getName()).log(Level.SEVERE, "Error getting info for " + db.getHashSetName() + " hash database", ex);
}
if (((Boolean) getValueAt(rowIndex, columnIndex)) || dbHasIndex) {
db.setSearchDuringIngest((Boolean) aValue);
} else {
JOptionPane.showMessageDialog(HashLookupModuleSettingsPanel.this,
NbBundle.getMessage(this.getClass(),
"HashDbSimpleConfigPanel.dlgMsg.mustIndexDbBeforeUse"));
}
} }
} }

View File

@ -31,9 +31,7 @@ final class KeywordSearchJobSettings implements IngestModuleIngestJobSettings {
private final HashSet<String> namesOfEnabledKeywordLists = new HashSet<>(); private final HashSet<String> namesOfEnabledKeywordLists = new HashSet<>();
KeywordSearchJobSettings(List<String> namesOfEnabledKeywordLists) { KeywordSearchJobSettings(List<String> namesOfEnabledKeywordLists) {
for (String keywordList : namesOfEnabledKeywordLists) { this.namesOfEnabledKeywordLists.addAll(namesOfEnabledKeywordLists);
this.namesOfEnabledKeywordLists.add(keywordList);
}
} }
boolean isKeywordListEnabled(String keywordListName) { boolean isKeywordListEnabled(String keywordListName) {