mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-19 19:14:55 +00:00
Merge branch 'develop-rc1' into develop
This commit is contained in:
commit
e68262fd7c
@ -95,5 +95,9 @@
|
||||
<package>org.sleuthkit.autopsy.hashdatabase</package>
|
||||
</public-packages>
|
||||
</data>
|
||||
<spellchecker-wordlist xmlns="http://www.netbeans.org/ns/spellchecker-wordlist/1">
|
||||
<word>openide</word>
|
||||
<word>org</word>
|
||||
</spellchecker-wordlist>
|
||||
</configuration>
|
||||
</project>
|
@ -24,7 +24,6 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
@ -35,124 +34,128 @@ import org.sleuthkit.autopsy.ingest.IngestConfigurator;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import static org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb;
|
||||
|
||||
/**
|
||||
* Instances of this Action allow users to content to a hash database.
|
||||
*/
|
||||
public class AddContentToHashDbAction extends AbstractAction implements Presenter.Popup {
|
||||
// This class is a singleton to support multi-selection of nodes, since
|
||||
// org.openide.nodes.NodeOp.findActions(Node[] nodes) will only pick up an Action if every
|
||||
// node in the array returns a reference to the same action object from Node.getActions(boolean).
|
||||
final class AddContentToHashDbAction extends AbstractAction implements Presenter.Popup {
|
||||
private static AddContentToHashDbAction instance;
|
||||
private static String SINGLE_SELECTION_NAME = "Add file to hash database";
|
||||
private static String MULTIPLE_SELECTION_NAME = "Add files to hash database";
|
||||
private String menuText;
|
||||
|
||||
/**
|
||||
* AddContentToHashDbAction is a singleton to support multi-selection of nodes, since
|
||||
* org.openide.nodes.NodeOp.findActions(Node[] nodes) will only pick up an Action from a node
|
||||
* if every node in the nodes array returns a reference to the same action object from
|
||||
* Node.getActions(boolean).
|
||||
*/
|
||||
public static synchronized AddContentToHashDbAction getInstance() {
|
||||
if (null == instance) {
|
||||
instance = new AddContentToHashDbAction();
|
||||
}
|
||||
|
||||
instance.setEnabled(true);
|
||||
instance.putValue(Action.NAME, SINGLE_SELECTION_NAME);
|
||||
instance.menuText = SINGLE_SELECTION_NAME;
|
||||
|
||||
// Disable the action if file ingest is in progress.
|
||||
IngestConfigurator ingestConfigurator = Lookup.getDefault().lookup(IngestConfigurator.class);
|
||||
if (null != ingestConfigurator && ingestConfigurator.isIngestRunning()) {
|
||||
instance.setEnabled(false);
|
||||
}
|
||||
|
||||
// Set the name of the action based on the selected content and disable the action if there is
|
||||
// selected content without an MD5 hash.
|
||||
Collection<? extends AbstractFile> selectedFiles = Utilities.actionsGlobalContext().lookupAll(AbstractFile.class);
|
||||
if (selectedFiles.size() > 1) {
|
||||
instance.putValue(Action.NAME, MULTIPLE_SELECTION_NAME);
|
||||
instance.menuText = MULTIPLE_SELECTION_NAME;
|
||||
}
|
||||
if (selectedFiles.isEmpty()) {
|
||||
instance.setEnabled(false);
|
||||
}
|
||||
else {
|
||||
for (AbstractFile file : selectedFiles) {
|
||||
if (null == file.getMd5Hash()) {
|
||||
instance.setEnabled(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private AddContentToHashDbAction() {
|
||||
super(SINGLE_SELECTION_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JMenuItem getPopupPresenter() {
|
||||
return new AddContentToHashDbMenu(menuText);
|
||||
return new AddContentToHashDbMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
}
|
||||
|
||||
private class AddContentToHashDbMenu extends JMenu {
|
||||
AddContentToHashDbMenu(String menuText) {
|
||||
super(menuText);
|
||||
// Instances of this class are used to implement the a pop up menu for this
|
||||
// action.
|
||||
private final class AddContentToHashDbMenu extends JMenu {
|
||||
private final static String SINGLE_SELECTION_NAME = "Add file to hash database";
|
||||
private final static String MULTIPLE_SELECTION_NAME = "Add files to hash database";
|
||||
|
||||
AddContentToHashDbMenu() {
|
||||
super(SINGLE_SELECTION_NAME);
|
||||
|
||||
// Disable the menu if file ingest is in progress.
|
||||
IngestConfigurator ingestConfigurator = Lookup.getDefault().lookup(IngestConfigurator.class);
|
||||
if (null != ingestConfigurator && ingestConfigurator.isIngestRunning()) {
|
||||
setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get any AbstractFile objects from the lookup of the currently focused top component.
|
||||
final Collection<? extends AbstractFile> selectedFiles = Utilities.actionsGlobalContext().lookupAll(AbstractFile.class);
|
||||
if (selectedFiles.isEmpty()) {
|
||||
setEnabled(false);
|
||||
return;
|
||||
}
|
||||
else if (selectedFiles.size() > 1) {
|
||||
setText(MULTIPLE_SELECTION_NAME);
|
||||
}
|
||||
|
||||
// Disable the menu if hashes have not been calculated.
|
||||
for (AbstractFile file : selectedFiles) {
|
||||
if (null == file.getMd5Hash()) {
|
||||
setEnabled(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the current set of updateable hash databases and add each
|
||||
// one as a menu item.
|
||||
List<HashDb> hashDatabases = HashDbManager.getInstance().getUpdateableHashSets();
|
||||
// one to the menu as a separate menu item. Selecting a hash database
|
||||
// adds the selected files to the selected database.
|
||||
final List<HashDb> hashDatabases = HashDbManager.getInstance().getUpdateableHashSets();
|
||||
if (!hashDatabases.isEmpty()) {
|
||||
for (final HashDb database : hashDatabases) {
|
||||
JMenuItem databaseItem = add(database.getHashSetName());
|
||||
databaseItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
addContentToHashSet(database);
|
||||
addFilesToHashSet(selectedFiles, database);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
JMenuItem empty = new JMenuItem("No hash databases");
|
||||
JMenuItem empty = new JMenuItem("No hash databases configured");
|
||||
empty.setEnabled(false);
|
||||
add(empty);
|
||||
}
|
||||
|
||||
// Add a "New Hash Set..." menu item.
|
||||
// Add a "New Hash Set..." menu item. Selecting this item invokes a
|
||||
// a hash database creation dialog and adds the selected files to the
|
||||
// the new database.
|
||||
addSeparator();
|
||||
JMenuItem newHashSetItem = new JMenuItem("New Hash Set...");
|
||||
JMenuItem newHashSetItem = new JMenuItem("Create database...");
|
||||
newHashSetItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
HashDb hashDb = new HashDbCreateDatabaseDialog().doDialog();
|
||||
HashDb hashDb = new HashDbCreateDatabaseDialog().getHashDatabase();
|
||||
if (null != hashDb) {
|
||||
HashDbManager hashSetManager = HashDbManager.getInstance();
|
||||
hashSetManager.addHashSet(hashDb);
|
||||
hashSetManager.save();
|
||||
addContentToHashSet(hashDb);
|
||||
HashDbManager.getInstance().save();
|
||||
addFilesToHashSet(selectedFiles, hashDb);
|
||||
}
|
||||
}
|
||||
});
|
||||
add(newHashSetItem);
|
||||
}
|
||||
|
||||
private void addContentToHashSet(HashDb hashSet) {
|
||||
Collection<? extends AbstractFile> selectedFiles = Utilities.actionsGlobalContext().lookupAll(AbstractFile.class);
|
||||
for (AbstractFile file : selectedFiles) {
|
||||
private void addFilesToHashSet(final Collection<? extends AbstractFile> files, HashDb hashSet) {
|
||||
for (AbstractFile file : files) {
|
||||
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);
|
||||
JOptionPane.showMessageDialog(null, "Unable to add " + file.getName() + " to hash database.", "Add to Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
JOptionPane.showMessageDialog(null, "Unable to add " + file.getName() + " to the hash database.", "Add to Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
JOptionPane.showMessageDialog(null, "Unable to add the " + (files.size() > 1 ? "files" : "file") + " to the hash database. Hashes have not been calculated. Please configure and run an appropriate ingest module.", "Add to Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,26 +22,15 @@ HashDbSearchPanel.errorField.text=Error: Not all files have been hashed.
|
||||
HashDbSearchPanel.saveBox.text=Remember Hashes
|
||||
HashDbSearchPanel.cancelButton.text=Cancel
|
||||
OpenIDE-Module-Short-Description=Hash Database Ingest Module and hash db tools
|
||||
HashDbImportDatabaseDialog.sendInboxMessagesCheckbox.text=Enable sending messages to inbox during ingest
|
||||
HashDbImportDatabaseDialog.useForIngestCheckbox.text=Enable for ingest
|
||||
HashDbImportDatabaseDialog.jLabel1.text=Hash Set Name:
|
||||
HashDbImportDatabaseDialog.databaseNameTextField.text=
|
||||
HashDbImportDatabaseDialog.databasePathTextField.text=
|
||||
HashDbImportDatabaseDialog.browseButton.text=Browse
|
||||
HashDbImportDatabaseDialog.knownBadRadioButton.text=Known Bad
|
||||
HashDbImportDatabaseDialog.jLabel2.text=Type of database:
|
||||
HashDbImportDatabaseDialog.okButton.text=OK
|
||||
HashDbImportDatabaseDialog.cancelButton.text=Cancel
|
||||
HashDbCreateDatabaseDialog.jLabel2.text=Type of database:
|
||||
HashDbCreateDatabaseDialog.jLabel2.text=Type:
|
||||
HashDbCreateDatabaseDialog.knownBadRadioButton.text=Known Bad
|
||||
HashDbCreateDatabaseDialog.browseButton.text=Browse
|
||||
HashDbCreateDatabaseDialog.databasePathTextField.text=
|
||||
HashDbCreateDatabaseDialog.cancelButton.text=Cancel
|
||||
HashDbCreateDatabaseDialog.sendInboxMessagesCheckbox.text=Enable sending messages to inbox during ingest
|
||||
HashDbCreateDatabaseDialog.okButton.text=OK
|
||||
HashDbCreateDatabaseDialog.useForIngestCheckbox.text=Enable for ingest
|
||||
HashDbCreateDatabaseDialog.jLabel1.text=Hash Set Name:
|
||||
HashDbCreateDatabaseDialog.databaseNameTextField.text=
|
||||
HashDbConfigPanel.nameLabel.text=Hash Set Name:
|
||||
HashDbConfigPanel.hashDbNameLabel.text=No database selected
|
||||
HashDbConfigPanel.hashDatabasesLabel.text=Hash Databases:
|
||||
@ -58,11 +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=Enable sending messages to inbox during ingest
|
||||
HashDbConfigPanel.useForIngestCheckbox.text=Enable for ingest
|
||||
HashDbConfigPanel.informationLabel.text=Information
|
||||
HashDbSimpleConfigPanel.calcHashesButton.text=Calculate hashes even if no hash database is selected
|
||||
HashDbConfigPanel.newDatabaseButton.text=New Database
|
||||
HashDbConfigPanel.importDatabaseButton.text=Import Database
|
||||
HashDbConfigPanel.deleteDatabaseButton.text=Delete Database
|
||||
HashDbConfigPanel.indexPathLabelLabel.text=Index Path:
|
||||
@ -75,4 +60,22 @@ ModalNoButtons.CANCEL_BUTTON.text=Cancel
|
||||
HashDbSimpleConfigPanel.knownBadHashDbsLabel.text=Enable known bad databases for ingest:
|
||||
HashDbSimpleConfigPanel.knownHashDbsLabel.text=Enable known hash databases for ingest:
|
||||
HashDbImportDatabaseDialog.knownRadioButton.text=Known (NSRL or other)
|
||||
HashDbCreateDatabaseDialog.knownRadioButton.text=Known (NSRL or other)
|
||||
HashDbCreateDatabaseDialog.knownRadioButton.text=Known
|
||||
HashDbCreateDatabaseDialog.jLabel1.text=Database Path:
|
||||
HashDbCreateDatabaseDialog.saveAsButton.text=Save As...
|
||||
HashDbCreateDatabaseDialog.hashSetNameTextField.text=
|
||||
HashDbImportDatabaseDialog.jLabel3.text=Database Path:
|
||||
HashDbCreateDatabaseDialog.searchDuringIngestCheckbox.text=Search during ingest
|
||||
HashDbCreateDatabaseDialog.searchDuringIngestCheckbox.toolTipText=
|
||||
HashDbCreateDatabaseDialog.sendIngestMessagesCheckbox.text=Send ingest messages
|
||||
HashDbImportDatabaseDialog.searchDuringIngestCheckbox.text=Search during ingest
|
||||
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
|
||||
|
@ -1,287 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 - 2013 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.hashdatabase;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.netbeans.api.progress.ProgressHandle;
|
||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.HashInfo;
|
||||
import org.sleuthkit.datamodel.SleuthkitJNI;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
/**
|
||||
* Instances of this class represent hash databases used to classify files as
|
||||
* known or know bad.
|
||||
*/
|
||||
public class HashDb {
|
||||
/**
|
||||
* Property change events published by hash database objects.
|
||||
*/
|
||||
public enum Event {
|
||||
INDEXING_DONE
|
||||
}
|
||||
|
||||
/**
|
||||
* The classification to apply to files whose hashes are stored in the
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
private int handle;
|
||||
private KnownFilesType knownFilesType;
|
||||
private String databasePath;
|
||||
private String indexPath;
|
||||
private String hashSetName;
|
||||
private boolean useForIngest;
|
||||
private boolean sendHitMessages;
|
||||
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;
|
||||
this.handle = handle;
|
||||
this.indexing = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener for the events defined in HashDb.Event.
|
||||
*/
|
||||
public void addPropertyChangeListener(PropertyChangeListener pcl) {
|
||||
propertyChangeSupport.addPropertyChangeListener(pcl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a listener for the events defined in HashDb.Event.
|
||||
*/
|
||||
public void removePropertyChangeListener(PropertyChangeListener pcl) {
|
||||
propertyChangeSupport.removePropertyChangeListener(pcl);
|
||||
}
|
||||
|
||||
public String getHashSetName() {
|
||||
return hashSetName;
|
||||
}
|
||||
|
||||
public String getDatabasePath() {
|
||||
return databasePath;
|
||||
}
|
||||
|
||||
public String getIndexPath() {
|
||||
return indexPath;
|
||||
}
|
||||
|
||||
public KnownFilesType getKnownFilesType() {
|
||||
return knownFilesType;
|
||||
}
|
||||
|
||||
public boolean getUseForIngest() {
|
||||
return useForIngest;
|
||||
}
|
||||
|
||||
void setUseForIngest(boolean useForIngest) {
|
||||
this.useForIngest = useForIngest;
|
||||
}
|
||||
|
||||
public boolean getShowInboxMessages() {
|
||||
return sendHitMessages;
|
||||
}
|
||||
|
||||
void setShowInboxMessages(boolean showInboxMessages) {
|
||||
this.sendHitMessages = 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the hash database accepts updates.
|
||||
* @return True if the database accepts updates, false otherwise.
|
||||
*/
|
||||
public boolean isUpdateable() throws TskCoreException {
|
||||
return SleuthkitJNI.isUpdateableHashDatabase(this.handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds hashes of content (if calculated) to the hash database.
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds hashes of content (if calculated) to the hash database.
|
||||
* @param content The content for which the calculated hashes, if any, are to be added to the hash database.
|
||||
* @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 {
|
||||
// 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()) {
|
||||
SleuthkitJNI.addToHashDatabase(file.getName(), file.getMd5Hash(), null, null, comment, handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean lookUp(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);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public HashInfo lookUpVerbose(Content content) throws TskCoreException {
|
||||
HashInfo result = null;
|
||||
// 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.lookupInHashDatabaseVerbose(file.getMd5Hash(), handle);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean isIndexing() {
|
||||
return indexing;
|
||||
}
|
||||
|
||||
// Tries to index the database (overwrites any existing index) using a
|
||||
// SwingWorker.
|
||||
void createIndex(boolean deleteIndexFile) {
|
||||
CreateIndex creator = new CreateIndex(deleteIndexFile);
|
||||
creator.execute();
|
||||
}
|
||||
|
||||
private class CreateIndex extends SwingWorker<Object,Void> {
|
||||
private ProgressHandle progress;
|
||||
private boolean deleteIndexFile;
|
||||
|
||||
CreateIndex(boolean deleteIndexFile) {
|
||||
this.deleteIndexFile = deleteIndexFile;
|
||||
};
|
||||
|
||||
@Override
|
||||
protected Object doInBackground() {
|
||||
indexing = true;
|
||||
progress = ProgressHandleFactory.createHandle("Indexing " + hashSetName);
|
||||
progress.start();
|
||||
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);
|
||||
JOptionPane.showMessageDialog(null, "Error indexing hash database for " + getHashSetName() + ".", "Hash Database Index Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
indexing = false;
|
||||
progress.finish();
|
||||
propertyChangeSupport.firePropertyChange(Event.INDEXING_DONE.toString(), null, hashSetName);
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws TskCoreException {
|
||||
SleuthkitJNI.closeHashDatabase(handle);
|
||||
}
|
||||
}
|
@ -60,7 +60,6 @@
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="hashDatabasesLabel" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="jScrollPane1" min="-2" pref="275" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
@ -74,13 +73,6 @@
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="10" pref="10" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="nameLabel" min="-2" max="-2" attributes="0"/>
|
||||
<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="showInboxMessagesCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="locationLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
@ -97,6 +89,21 @@
|
||||
<Component id="hashDbIndexStatusLabel" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="nameLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="53" max="-2" attributes="0"/>
|
||||
<Component id="hashDbNameLabel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<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="sendIngestMessagesCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
@ -106,12 +113,20 @@
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="newDatabaseButton" min="-2" pref="133" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="importDatabaseButton" min="-2" pref="133" max="-2" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="hashDatabasesLabel" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="1" max="-2" attributes="0">
|
||||
<Component id="deleteDatabaseButton" alignment="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="createDatabaseButton" min="-2" pref="137" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="importDatabaseButton" min="-2" pref="133" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="deleteDatabaseButton" alignment="0" min="-2" pref="133" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="24" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
@ -165,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"/>
|
||||
@ -177,7 +192,7 @@
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="importDatabaseButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="newDatabaseButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="createDatabaseButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="deleteDatabaseButton" min="-2" max="-2" attributes="0"/>
|
||||
@ -345,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">
|
||||
@ -383,13 +398,13 @@
|
||||
</Component>
|
||||
<Component class="javax.swing.JSeparator" name="optionsSeparator">
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="newDatabaseButton">
|
||||
<Component class="javax.swing.JButton" name="createDatabaseButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/hashdatabase/new16.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.newDatabaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.createDatabaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[140, 25]"/>
|
||||
@ -402,7 +417,7 @@
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="newDatabaseButtonActionPerformed"/>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="createDatabaseButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="indexPathLabelLabel">
|
||||
|
@ -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();
|
||||
@ -55,6 +58,17 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
updateComponentsForNoSelection();
|
||||
|
||||
// Listen to the ingest modules to refresh the enabled/disabled state of
|
||||
// the components in sync with file ingest.
|
||||
IngestManager.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (isFileIngestStatusChangeEvent(evt)) {
|
||||
updateComponents();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void customizeComponents() {
|
||||
@ -100,16 +114,16 @@ 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);
|
||||
|
||||
// Update database action buttons.
|
||||
newDatabaseButton.setEnabled(!ingestIsRunning);
|
||||
importDatabaseButton.setEnabled(!ingestIsRunning);
|
||||
createDatabaseButton.setEnabled(true);
|
||||
importDatabaseButton.setEnabled(true);
|
||||
deleteDatabaseButton.setEnabled(false);
|
||||
|
||||
// Update ingest in progress warning label.
|
||||
@ -122,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 {
|
||||
@ -144,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);
|
||||
}
|
||||
@ -162,29 +190,29 @@ 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);
|
||||
}
|
||||
|
||||
// Diable the indexing button if ingest is in progress.
|
||||
// Disable the indexing button if ingest is in progress.
|
||||
if (ingestIsRunning) {
|
||||
indexButton.setEnabled(false);
|
||||
}
|
||||
|
||||
// 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);
|
||||
importDatabaseButton.setEnabled(true);
|
||||
deleteDatabaseButton.setEnabled(!ingestIsRunning);
|
||||
importDatabaseButton.setEnabled(!ingestIsRunning);
|
||||
importDatabaseButton.setEnabled(!ingestIsRunning);
|
||||
|
||||
// Update ingest in progress warning label.
|
||||
ingestWarningLabel.setVisible(ingestIsRunning);
|
||||
@ -198,6 +226,10 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
return shortenedPath;
|
||||
}
|
||||
|
||||
private boolean isFileIngestStatusChangeEvent(PropertyChangeEvent evt) {
|
||||
return evt.getPropertyName().equals(IngestManager.IngestModuleEvent.STARTED.toString()) || evt.getPropertyName().equals(IngestManager.IngestModuleEvent.COMPLETED.toString()) || evt.getPropertyName().equals(IngestManager.IngestModuleEvent.STOPPED.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
hashSetTable.clearSelection();
|
||||
@ -230,18 +262,9 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
hashSetManager.save();
|
||||
}
|
||||
|
||||
public void discard() {
|
||||
HashDbManager.getInstance().loadLastSavedConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 popup 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();
|
||||
}
|
||||
@ -279,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;
|
||||
}
|
||||
|
||||
@ -428,13 +450,13 @@ 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();
|
||||
optionsSeparator = new javax.swing.JSeparator();
|
||||
newDatabaseButton = new javax.swing.JButton();
|
||||
createDatabaseButton = new javax.swing.JButton();
|
||||
indexPathLabelLabel = new javax.swing.JLabel();
|
||||
indexPathLabel = new javax.swing.JLabel();
|
||||
|
||||
@ -518,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);
|
||||
}
|
||||
});
|
||||
|
||||
@ -536,14 +558,14 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(optionsLabel, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.optionsLabel.text")); // NOI18N
|
||||
|
||||
newDatabaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/hashdatabase/new16.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(newDatabaseButton, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.newDatabaseButton.text")); // NOI18N
|
||||
newDatabaseButton.setMaximumSize(new java.awt.Dimension(140, 25));
|
||||
newDatabaseButton.setMinimumSize(new java.awt.Dimension(140, 25));
|
||||
newDatabaseButton.setPreferredSize(new java.awt.Dimension(140, 25));
|
||||
newDatabaseButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
createDatabaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/hashdatabase/new16.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(createDatabaseButton, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.createDatabaseButton.text")); // NOI18N
|
||||
createDatabaseButton.setMaximumSize(new java.awt.Dimension(140, 25));
|
||||
createDatabaseButton.setMinimumSize(new java.awt.Dimension(140, 25));
|
||||
createDatabaseButton.setPreferredSize(new java.awt.Dimension(140, 25));
|
||||
createDatabaseButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
newDatabaseButtonActionPerformed(evt);
|
||||
createDatabaseButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
@ -558,7 +580,6 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(hashDatabasesLabel)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
@ -571,12 +592,6 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGap(10, 10, 10)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(nameLabel)
|
||||
.addGap(53, 53, 53)
|
||||
.addComponent(hashDbNameLabel))
|
||||
.addComponent(useForIngestCheckbox)
|
||||
.addComponent(showInboxMessagesCheckBox)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(locationLabel)
|
||||
@ -589,16 +604,32 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
.addComponent(hashDbTypeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 241, Short.MAX_VALUE)
|
||||
.addComponent(hashDbLocationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(indexPathLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(hashDbIndexStatusLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))))
|
||||
.addComponent(hashDbIndexStatusLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(nameLabel)
|
||||
.addGap(53, 53, 53)
|
||||
.addComponent(hashDbNameLabel))
|
||||
.addComponent(searchDuringIngestCheckbox)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(21, 21, 21)
|
||||
.addComponent(sendIngestMessagesCheckBox)))
|
||||
.addGap(0, 0, Short.MAX_VALUE))))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(optionsLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(optionsSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 324, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(newDatabaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(importDatabaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(deleteDatabaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(hashDatabasesLabel)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
|
||||
.addComponent(deleteDatabaseButton, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
|
||||
.addComponent(createDatabaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 137, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(importDatabaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addGap(0, 0, Short.MAX_VALUE)))
|
||||
.addGap(24, 24, 24))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
@ -641,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))
|
||||
@ -651,7 +682,7 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(importDatabaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(newDatabaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(createDatabaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(deleteDatabaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
@ -689,10 +720,10 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
}//GEN-LAST:event_indexButtonActionPerformed
|
||||
|
||||
private void deleteDatabaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteDatabaseButtonActionPerformed
|
||||
if (JOptionPane.showConfirmDialog(null, "This will remove the hash database entry globally (for all Cases). Do you want to proceed? ", "Deleting a Hash Database Entry", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
@ -702,46 +733,48 @@ 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 newDatabaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newDatabaseButtonActionPerformed
|
||||
HashDb hashDb = new HashDbCreateDatabaseDialog().doDialog();
|
||||
private void createDatabaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_createDatabaseButtonActionPerformed
|
||||
HashDb hashDb = new HashDbCreateDatabaseDialog().getHashDatabase();
|
||||
if (null != hashDb) {
|
||||
hashSetManager.addHashSet(hashDb);
|
||||
hashSetTableModel.refreshModel();
|
||||
((HashSetTable)hashSetTable).selectRowByName(hashDb.getHashSetName());
|
||||
}
|
||||
}//GEN-LAST:event_newDatabaseButtonActionPerformed
|
||||
}//GEN-LAST:event_createDatabaseButtonActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton createDatabaseButton;
|
||||
private javax.swing.JButton deleteDatabaseButton;
|
||||
private javax.swing.JLabel hashDatabasesLabel;
|
||||
private javax.swing.JLabel hashDbIndexStatusLabel;
|
||||
@ -764,11 +797,10 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JLabel locationLabel;
|
||||
private javax.swing.JLabel nameLabel;
|
||||
private javax.swing.JButton newDatabaseButton;
|
||||
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
|
||||
}
|
@ -32,43 +32,48 @@
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="okButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="databasePathTextField" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="browseButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="databaseNameTextField" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
|
||||
<Component id="sendIngestMessagesCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="searchDuringIngestCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="10" pref="10" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="knownBadRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="knownRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="useForIngestCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="sendInboxMessagesCheckbox" alignment="0" 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="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">
|
||||
<Component id="knownRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<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 min="0" pref="135" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
@ -77,45 +82,46 @@
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" 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="browseButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="saveAsButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="databaseNameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<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"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="knownBadRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="useForIngestCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="searchDuringIngestCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="sendInboxMessagesCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="sendIngestMessagesCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="okButton" 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 max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="okButton">
|
||||
<Component class="javax.swing.JButton" name="saveAsButton">
|
||||
<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}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbCreateDatabaseDialog.saveAsButton.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"/>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="saveAsButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="cancelButton">
|
||||
@ -128,23 +134,6 @@
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="databasePathTextField">
|
||||
<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.databasePathTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="browseButton">
|
||||
<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.browseButton.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="browseButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="knownRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
@ -179,10 +168,10 @@
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="databaseNameTextField">
|
||||
<Component class="javax.swing.JTextField" name="hashSetNameTextField">
|
||||
<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.databaseNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbCreateDatabaseDialog.hashSetNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
@ -193,24 +182,52 @@
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="useForIngestCheckbox">
|
||||
<Component class="javax.swing.JCheckBox" name="searchDuringIngestCheckbox">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbCreateDatabaseDialog.useForIngestCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbCreateDatabaseDialog.searchDuringIngestCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbCreateDatabaseDialog.searchDuringIngestCheckbox.toolTipText" 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="sendInboxMessagesCheckbox">
|
||||
<Component class="javax.swing.JCheckBox" name="sendIngestMessagesCheckbox">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbCreateDatabaseDialog.sendInboxMessagesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbCreateDatabaseDialog.sendIngestMessagesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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>
|
||||
|
@ -27,31 +27,60 @@ import java.util.logging.Level;
|
||||
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.apache.commons.io.FilenameUtils;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDb.KnownFilesType;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
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 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 JFileChooser fileChooser;
|
||||
|
||||
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);
|
||||
setResizable(false);
|
||||
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() {
|
||||
File selectedFile = getSelectedFile();
|
||||
if (!FilenameUtils.getExtension(selectedFile.getName()).equalsIgnoreCase("kdb")) {
|
||||
if (JOptionPane.showConfirmDialog(this, "The file must have a .kdb extension.", "File Name Error", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.CANCEL_OPTION) {
|
||||
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;
|
||||
}
|
||||
if (selectedFile.exists()) {
|
||||
int r = JOptionPane.showConfirmDialog(this, "A file with this name already exists. Please enter a new filename.", "Existing File", JOptionPane.OK_CANCEL_OPTION);
|
||||
if (r == JOptionPane.CANCEL_OPTION) {
|
||||
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;
|
||||
@ -59,28 +88,15 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
||||
super.approveSelection();
|
||||
}
|
||||
};
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
}
|
||||
|
||||
void customizeComponents() {
|
||||
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.setDragEnabled(false);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,24 +109,25 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
||||
private void initComponents() {
|
||||
|
||||
buttonGroup1 = new javax.swing.ButtonGroup();
|
||||
okButton = new javax.swing.JButton();
|
||||
saveAsButton = new javax.swing.JButton();
|
||||
cancelButton = new javax.swing.JButton();
|
||||
databasePathTextField = new javax.swing.JTextField();
|
||||
browseButton = new javax.swing.JButton();
|
||||
knownRadioButton = new javax.swing.JRadioButton();
|
||||
knownBadRadioButton = new javax.swing.JRadioButton();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
databaseNameTextField = new javax.swing.JTextField();
|
||||
hashSetNameTextField = new javax.swing.JTextField();
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
useForIngestCheckbox = new javax.swing.JCheckBox();
|
||||
sendInboxMessagesCheckbox = new javax.swing.JCheckBox();
|
||||
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);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.okButton.text")); // NOI18N
|
||||
okButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
org.openide.awt.Mnemonics.setLocalizedText(saveAsButton, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.saveAsButton.text")); // NOI18N
|
||||
saveAsButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
okButtonActionPerformed(evt);
|
||||
saveAsButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
@ -121,15 +138,6 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
||||
}
|
||||
});
|
||||
|
||||
databasePathTextField.setText(org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.databasePathTextField.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.browseButton.text")); // NOI18N
|
||||
browseButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
browseButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
buttonGroup1.add(knownRadioButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(knownRadioButton, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.knownRadioButton.text")); // NOI18N
|
||||
knownRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
@ -149,20 +157,33 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.jLabel1.text")); // NOI18N
|
||||
|
||||
databaseNameTextField.setText(org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.databaseNameTextField.text")); // NOI18N
|
||||
hashSetNameTextField.setText(org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.hashSetNameTextField.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.jLabel2.text")); // NOI18N
|
||||
|
||||
useForIngestCheckbox.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(useForIngestCheckbox, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.useForIngestCheckbox.text")); // NOI18N
|
||||
useForIngestCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
searchDuringIngestCheckbox.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(searchDuringIngestCheckbox, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.searchDuringIngestCheckbox.text")); // NOI18N
|
||||
searchDuringIngestCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.searchDuringIngestCheckbox.toolTipText")); // NOI18N
|
||||
searchDuringIngestCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
useForIngestCheckboxActionPerformed(evt);
|
||||
searchDuringIngestCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
sendInboxMessagesCheckbox.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(sendInboxMessagesCheckbox, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.sendInboxMessagesCheckbox.text")); // NOI18N
|
||||
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);
|
||||
@ -174,142 +195,175 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(21, 21, 21)
|
||||
.addComponent(sendIngestMessagesCheckbox))
|
||||
.addComponent(searchDuringIngestCheckbox))
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(okButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cancelButton))
|
||||
.addComponent(jLabel2)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(databasePathTextField)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(browseButton))
|
||||
.addGap(20, 20, 20)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(knownRadioButton)
|
||||
.addComponent(knownBadRadioButton)))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jLabel1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(databaseNameTextField))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jLabel2)
|
||||
.addGap(0, 0, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(10, 10, 10)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(knownBadRadioButton)
|
||||
.addComponent(knownRadioButton))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(useForIngestCheckbox)
|
||||
.addComponent(sendInboxMessagesCheckbox))
|
||||
.addGap(0, 135, Short.MAX_VALUE))))
|
||||
.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, 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(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(browseButton))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel1)
|
||||
.addComponent(databaseNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(saveAsButton)
|
||||
.addComponent(jLabel1))
|
||||
.addGap(7, 7, 7)
|
||||
.addComponent(jLabel2)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(knownRadioButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(knownBadRadioButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(useForIngestCheckbox)
|
||||
.addComponent(searchDuringIngestCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(sendInboxMessagesCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(sendIngestMessagesCheckbox)
|
||||
.addGap(3, 3, 3)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(okButton)
|
||||
.addComponent(cancelButton))
|
||||
.addContainerGap())
|
||||
.addComponent(cancelButton)
|
||||
.addComponent(okButton))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
|
||||
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
|
||||
|
||||
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
|
||||
dispose();
|
||||
}//GEN-LAST:event_cancelButtonActionPerformed
|
||||
|
||||
private void saveAsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveAsButtonActionPerformed
|
||||
try {
|
||||
fileChooser.setSelectedFile(new File("hash.kdb"));
|
||||
if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
|
||||
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());
|
||||
databaseNameTextField.setText(FilenameUtils.removeExtension(databaseFile.getName()));
|
||||
if (databaseNameTextField.getText().toLowerCase().contains("nsrl")) {
|
||||
knownRadioButton.setSelected(true);
|
||||
knownRadioButtonActionPerformed(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
Logger.getLogger(HashDbCreateDatabaseDialog.class.getName()).log(Level.WARNING, "Couldn't get selected file path.", ex);
|
||||
}
|
||||
}//GEN-LAST:event_browseButtonActionPerformed
|
||||
}//GEN-LAST:event_saveAsButtonActionPerformed
|
||||
|
||||
private void knownRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_knownRadioButtonActionPerformed
|
||||
sendInboxMessagesCheckbox.setSelected(false);
|
||||
sendInboxMessagesCheckbox.setEnabled(false);
|
||||
}//GEN-LAST:event_knownRadioButtonActionPerformed
|
||||
|
||||
private void knownBadRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_knownBadRadioButtonActionPerformed
|
||||
sendInboxMessagesCheckbox.setSelected(true);
|
||||
sendInboxMessagesCheckbox.setEnabled(true);
|
||||
}//GEN-LAST:event_knownBadRadioButtonActionPerformed
|
||||
|
||||
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
|
||||
this.dispose();
|
||||
}//GEN-LAST:event_cancelButtonActionPerformed
|
||||
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
|
||||
if(databasePathTextField.getText().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this, "Database path cannot be empty");
|
||||
// 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(databaseNameTextField.getText().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this, "Database name cannot be empty");
|
||||
|
||||
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()) {
|
||||
if (knownRadioButton.isSelected()) {
|
||||
type = KnownFilesType.KNOWN;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
type = KnownFilesType.KNOWN_BAD;
|
||||
}
|
||||
|
||||
String errorMessage = "Hash database creation error";
|
||||
try
|
||||
{
|
||||
newHashDb = HashDb.createHashDatabase(databaseNameTextField.getText(), databasePathTextField.getText(), useForIngestCheckbox.isSelected(), sendInboxMessagesCheckbox.isSelected(), type);
|
||||
newHashDb = HashDbManager.getInstance().addNewHashDatabase(hashSetNameTextField.getText(), fileChooser.getSelectedFile().getCanonicalPath(), searchDuringIngestCheckbox.isSelected(), sendIngestMessagesCheckbox.isSelected(), type);
|
||||
}
|
||||
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.", "Create Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
catch (HashDatabaseFileAlreadyExistsException | DuplicateHashSetNameException | HashDatabaseAlreadyAddedException | IllegalHashDatabaseFileNameExtensionException ex) {
|
||||
Logger.getLogger(HashDbCreateDatabaseDialog.class.getName()).log(Level.WARNING, errorMessage, ex);
|
||||
JOptionPane.showMessageDialog(this, ex.getMessage(), "Create Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbCreateDatabaseDialog.class.getName()).log(Level.SEVERE, "Hash database creation error", ex);
|
||||
JOptionPane.showMessageDialog(this, "Failed to create hash database.");
|
||||
Logger.getLogger(HashDbCreateDatabaseDialog.class.getName()).log(Level.SEVERE, errorMessage, ex);
|
||||
JOptionPane.showMessageDialog(this, "Failed to create the hash database.", "Create Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
this.dispose();
|
||||
dispose();
|
||||
}//GEN-LAST:event_okButtonActionPerformed
|
||||
|
||||
private void useForIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useForIngestCheckboxActionPerformed
|
||||
}//GEN-LAST:event_useForIngestCheckboxActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton browseButton;
|
||||
private javax.swing.ButtonGroup buttonGroup1;
|
||||
private javax.swing.JButton cancelButton;
|
||||
private javax.swing.JTextField databaseNameTextField;
|
||||
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.JCheckBox sendInboxMessagesCheckbox;
|
||||
private javax.swing.JCheckBox useForIngestCheckbox;
|
||||
private javax.swing.JButton saveAsButton;
|
||||
private javax.swing.JCheckBox searchDuringIngestCheckbox;
|
||||
private javax.swing.JCheckBox sendIngestMessagesCheckbox;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
|
@ -30,47 +30,50 @@
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="okButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
|
||||
<Component id="sendIngestMessagesCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="databasePathTextField" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="browseButton" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="searchDuringIngestCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="okButton" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cancelButton" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="knownRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="knownBadRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="307" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="databaseNameTextField" max="32767" attributes="0"/>
|
||||
<Component id="hashSetNameTextField" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="databasePathTextField" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="10" pref="10" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="knownBadRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="knownRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="useForIngestCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="sendInboxMessagesCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="135" max="32767" attributes="0"/>
|
||||
<Component id="openButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -79,30 +82,38 @@
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="openButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="databasePathTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="browseButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="databaseNameTextField" 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"/>
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="knownRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="knownBadRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="useForIngestCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="sendInboxMessagesCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace pref="119" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace type="unrelated" 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"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="knownBadRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="13" max="-2" attributes="0"/>
|
||||
<Component id="searchDuringIngestCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="sendIngestMessagesCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -130,19 +141,20 @@
|
||||
</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="HashDbImportDatabaseDialog.databasePathTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="browseButton">
|
||||
<Component class="javax.swing.JButton" name="openButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.browseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.openButton.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="browseButtonActionPerformed"/>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="openButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="knownRadioButton">
|
||||
@ -179,10 +191,10 @@
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="databaseNameTextField">
|
||||
<Component class="javax.swing.JTextField" name="hashSetNameTextField">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.databaseNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.hashSetNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
@ -193,22 +205,29 @@
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="useForIngestCheckbox">
|
||||
<Component class="javax.swing.JCheckBox" name="searchDuringIngestCheckbox">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.useForIngestCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.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="sendInboxMessagesCheckbox">
|
||||
<Component class="javax.swing.JCheckBox" name="sendIngestMessagesCheckbox">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.sendInboxMessagesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.sendIngestMessagesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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="HashDbImportDatabaseDialog.jLabel3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
|
@ -27,25 +27,47 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDb.KnownFilesType;
|
||||
import javax.swing.JFrame;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
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 HashDb selectedHashDb;
|
||||
|
||||
private JFileChooser fileChooser = new JFileChooser();
|
||||
private String selectedFilePath = "";
|
||||
private HashDb selectedHashDb = null;
|
||||
|
||||
/**
|
||||
* 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 javax.swing.JFrame(), "Import Hash Database", true);
|
||||
setResizable(false);
|
||||
super(new JFrame(), "Import Hash Database", true);
|
||||
initFileChooser();
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
display();
|
||||
}
|
||||
|
||||
void customizeComponents() {
|
||||
/**
|
||||
* 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"};
|
||||
@ -54,15 +76,18 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
||||
fileChooser.setMultiSelectionEnabled(false);
|
||||
}
|
||||
|
||||
HashDb doDialog() {
|
||||
selectedHashDb = 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);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
return selectedHashDb;
|
||||
private static String shortenPath(String path) {
|
||||
String shortenedPath = path;
|
||||
if (shortenedPath.length() > 50){
|
||||
shortenedPath = shortenedPath.substring(0, 10 + shortenedPath.substring(10).indexOf(File.separator) + 1) + "..." + shortenedPath.substring((shortenedPath.length() - 20) + shortenedPath.substring(shortenedPath.length() - 20).indexOf(File.separator));
|
||||
}
|
||||
return shortenedPath;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,14 +103,15 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
||||
okButton = new javax.swing.JButton();
|
||||
cancelButton = new javax.swing.JButton();
|
||||
databasePathTextField = new javax.swing.JTextField();
|
||||
browseButton = new javax.swing.JButton();
|
||||
openButton = new javax.swing.JButton();
|
||||
knownRadioButton = new javax.swing.JRadioButton();
|
||||
knownBadRadioButton = new javax.swing.JRadioButton();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
databaseNameTextField = new javax.swing.JTextField();
|
||||
hashSetNameTextField = new javax.swing.JTextField();
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
useForIngestCheckbox = new javax.swing.JCheckBox();
|
||||
sendInboxMessagesCheckbox = new javax.swing.JCheckBox();
|
||||
searchDuringIngestCheckbox = new javax.swing.JCheckBox();
|
||||
sendIngestMessagesCheckbox = new javax.swing.JCheckBox();
|
||||
jLabel3 = new javax.swing.JLabel();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
|
||||
@ -103,12 +129,13 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
||||
}
|
||||
});
|
||||
|
||||
databasePathTextField.setEditable(false);
|
||||
databasePathTextField.setText(org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.databasePathTextField.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.browseButton.text")); // NOI18N
|
||||
browseButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
org.openide.awt.Mnemonics.setLocalizedText(openButton, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.openButton.text")); // NOI18N
|
||||
openButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
browseButtonActionPerformed(evt);
|
||||
openButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
@ -131,20 +158,22 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.jLabel1.text")); // NOI18N
|
||||
|
||||
databaseNameTextField.setText(org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.databaseNameTextField.text")); // NOI18N
|
||||
hashSetNameTextField.setText(org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.hashSetNameTextField.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.jLabel2.text")); // NOI18N
|
||||
|
||||
useForIngestCheckbox.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(useForIngestCheckbox, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.useForIngestCheckbox.text")); // NOI18N
|
||||
useForIngestCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
searchDuringIngestCheckbox.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(searchDuringIngestCheckbox, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.searchDuringIngestCheckbox.text")); // NOI18N
|
||||
searchDuringIngestCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
useForIngestCheckboxActionPerformed(evt);
|
||||
searchDuringIngestCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
sendInboxMessagesCheckbox.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(sendInboxMessagesCheckbox, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.sendInboxMessagesCheckbox.text")); // NOI18N
|
||||
sendIngestMessagesCheckbox.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(sendIngestMessagesCheckbox, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.sendIngestMessagesCheckbox.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.jLabel3.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
@ -156,90 +185,104 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(okButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cancelButton))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(databasePathTextField)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(browseButton))
|
||||
.addGap(21, 21, 21)
|
||||
.addComponent(sendIngestMessagesCheckbox))
|
||||
.addComponent(searchDuringIngestCheckbox))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(okButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cancelButton))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jLabel2)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(19, 19, 19)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(knownRadioButton)
|
||||
.addComponent(knownBadRadioButton))))
|
||||
.addGap(0, 307, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
|
||||
.addComponent(jLabel1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(databaseNameTextField))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jLabel2)
|
||||
.addGap(0, 0, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(10, 10, 10)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(knownBadRadioButton)
|
||||
.addComponent(knownRadioButton))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(useForIngestCheckbox)
|
||||
.addComponent(sendInboxMessagesCheckbox))
|
||||
.addGap(0, 135, Short.MAX_VALUE))))
|
||||
.addComponent(hashSetNameTextField))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
|
||||
.addComponent(jLabel3)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(databasePathTextField)))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(openButton)))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
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()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(openButton)
|
||||
.addComponent(databasePathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(browseButton))
|
||||
.addComponent(jLabel3))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel1)
|
||||
.addComponent(databaseNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel2)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(knownRadioButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(knownBadRadioButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(useForIngestCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(sendInboxMessagesCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(okButton)
|
||||
.addComponent(cancelButton))
|
||||
.addContainerGap())
|
||||
.addComponent(hashSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 119, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(okButton)
|
||||
.addComponent(cancelButton))
|
||||
.addContainerGap())
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(jLabel2)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(knownRadioButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(knownBadRadioButton)
|
||||
.addGap(13, 13, 13)
|
||||
.addComponent(searchDuringIngestCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(sendIngestMessagesCheckbox)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
|
||||
private void openButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openButtonActionPerformed
|
||||
if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
|
||||
File databaseFile = fileChooser.getSelectedFile();
|
||||
try {
|
||||
databasePathTextField.setText(databaseFile.getCanonicalPath());
|
||||
databaseNameTextField.setText(FilenameUtils.removeExtension(databaseFile.getName()));
|
||||
if (databaseNameTextField.getText().toLowerCase().contains("nsrl")) {
|
||||
selectedFilePath = databaseFile.getCanonicalPath();
|
||||
databasePathTextField.setText(shortenPath(selectedFilePath));
|
||||
hashSetNameTextField.setText(FilenameUtils.removeExtension(databaseFile.getName()));
|
||||
if (hashSetNameTextField.getText().toLowerCase().contains("nsrl")) {
|
||||
knownRadioButton.setSelected(true);
|
||||
knownRadioButtonActionPerformed(null);
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
Logger.getLogger(HashDbImportDatabaseDialog.class.getName()).log(Level.SEVERE, "Failed to get path of selected database", ex);
|
||||
JOptionPane.showMessageDialog(this, "Failed to get the path of the selected database.");
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_browseButtonActionPerformed
|
||||
}//GEN-LAST:event_openButtonActionPerformed
|
||||
|
||||
private void knownRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_knownRadioButtonActionPerformed
|
||||
sendInboxMessagesCheckbox.setSelected(false);
|
||||
sendInboxMessagesCheckbox.setEnabled(false);
|
||||
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
|
||||
sendInboxMessagesCheckbox.setSelected(true);
|
||||
sendInboxMessagesCheckbox.setEnabled(true);
|
||||
searchDuringIngestCheckbox.setSelected(true);
|
||||
sendIngestMessagesCheckbox.setSelected(true);
|
||||
sendIngestMessagesCheckbox.setEnabled(true);
|
||||
}//GEN-LAST:event_knownBadRadioButtonActionPerformed
|
||||
|
||||
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
|
||||
@ -247,29 +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(databasePathTextField.getText().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this, "Hash database file path cannot be empty.");
|
||||
// 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.", "Import Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if(databaseNameTextField.getText().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this, "Hash set name cannot be empty.");
|
||||
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(databasePathTextField.getText());
|
||||
File file = new File(selectedFilePath);
|
||||
if (!file.exists()) {
|
||||
JOptionPane.showMessageDialog(this, "Selected hash database does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
String filePath;
|
||||
try {
|
||||
filePath = file.getCanonicalPath();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
Logger.getLogger(HashDbImportDatabaseDialog.class.getName()).log(Level.SEVERE, "Failed to get path of selected database", ex);
|
||||
JOptionPane.showMessageDialog(this, "Failed to get path of selected database.");
|
||||
JOptionPane.showMessageDialog(this, "The selected hash database does not exist.", "Import Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -281,33 +316,44 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
||||
type = KnownFilesType.KNOWN_BAD;
|
||||
}
|
||||
|
||||
String errorMessage = "Failed to open hash database at " + selectedFilePath + ".";
|
||||
try {
|
||||
selectedHashDb = HashDb.openHashDatabase(databaseNameTextField.getText(), filePath, useForIngestCheckbox.isSelected(), sendInboxMessagesCheckbox.isSelected(), type);
|
||||
selectedHashDb = HashDbManager.getInstance().addExistingHashDatabase(hashSetNameTextField.getText(), selectedFilePath, searchDuringIngestCheckbox.isSelected(), sendIngestMessagesCheckbox.isSelected(), type);
|
||||
}
|
||||
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(HashDbImportDatabaseDialog.class.getName()).log(Level.WARNING, "Failed to open hash database at " + filePath, ex);
|
||||
JOptionPane.showMessageDialog(this, "Failed to import selected database.\nPlease verify that the selected file is a hash database.");
|
||||
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 useForIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useForIngestCheckboxActionPerformed
|
||||
}//GEN-LAST:event_useForIngestCheckboxActionPerformed
|
||||
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
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton browseButton;
|
||||
private javax.swing.ButtonGroup buttonGroup1;
|
||||
private javax.swing.JButton cancelButton;
|
||||
private javax.swing.JTextField databaseNameTextField;
|
||||
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.JCheckBox sendInboxMessagesCheckbox;
|
||||
private javax.swing.JCheckBox useForIngestCheckbox;
|
||||
private javax.swing.JButton openButton;
|
||||
private javax.swing.JCheckBox searchDuringIngestCheckbox;
|
||||
private javax.swing.JCheckBox sendIngestMessagesCheckbox;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -206,14 +207,24 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
}
|
||||
|
||||
// look up in known bad first
|
||||
TskData.FileKnown status = TskData.FileKnown.UNKNOWN;
|
||||
boolean foundBad = false;
|
||||
ProcessResult ret = ProcessResult.OK;
|
||||
for (HashDb db : knownBadHashSets) {
|
||||
try {
|
||||
long lookupstart = System.currentTimeMillis();
|
||||
if (db.lookUp(file)) {
|
||||
status = TskData.FileKnown.BAD;
|
||||
if (db.hasMd5HashOf(file)) {
|
||||
foundBad = true;
|
||||
knownBadCount += 1;
|
||||
try {
|
||||
skCase.setKnown(file, TskData.FileKnown.BAD);
|
||||
} catch (TskException ex) {
|
||||
logger.log(Level.WARNING, "Couldn't set known bad state for file " + name + " - see sleuthkit log for details", ex);
|
||||
services.postMessage(IngestMessage.createErrorMessage(++messageId, HashDbIngestModule.this, "Hash Lookup Error: " + name,
|
||||
"Error encountered while setting known bad state for " + name + "."));
|
||||
ret = ProcessResult.ERROR;
|
||||
}
|
||||
String hashSetName = db.getHashSetName();
|
||||
postHashSetHitToBlackboard(file, md5Hash, hashSetName, db.getSendIngestMessages());
|
||||
}
|
||||
lookuptime += (System.currentTimeMillis() - lookupstart);
|
||||
} catch (TskException ex) {
|
||||
@ -222,21 +233,6 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
"Error encountered while looking up known bad hash value for " + name + "."));
|
||||
ret = ProcessResult.ERROR;
|
||||
}
|
||||
|
||||
if (status.equals(TskData.FileKnown.BAD)) {
|
||||
foundBad = true;
|
||||
knownBadCount += 1;
|
||||
try {
|
||||
skCase.setKnown(file, TskData.FileKnown.BAD);
|
||||
} catch (TskException ex) {
|
||||
logger.log(Level.WARNING, "Couldn't set known bad state for file " + name + " - see sleuthkit log for details", ex);
|
||||
services.postMessage(IngestMessage.createErrorMessage(++messageId, HashDbIngestModule.this, "Hash Lookup Error: " + name,
|
||||
"Error encountered while setting known bad state for " + name + "."));
|
||||
ret = ProcessResult.ERROR;
|
||||
}
|
||||
String hashSetName = db.getHashSetName();
|
||||
processBadFile(file, md5Hash, hashSetName, db.getShowInboxMessages());
|
||||
}
|
||||
}
|
||||
|
||||
// If the file is not in the known bad sets, search for it in the known sets.
|
||||
@ -246,8 +242,16 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
for (HashDb db : knownHashSets) {
|
||||
try {
|
||||
long lookupstart = System.currentTimeMillis();
|
||||
if (db.lookUp(file)) {
|
||||
status = TskData.FileKnown.KNOWN;
|
||||
if (db.hasMd5HashOf(file)) {
|
||||
try {
|
||||
skCase.setKnown(file, TskData.FileKnown.KNOWN);
|
||||
break;
|
||||
} catch (TskException ex) {
|
||||
logger.log(Level.WARNING, "Couldn't set known state for file " + name + " - see sleuthkit log for details", ex);
|
||||
services.postMessage(IngestMessage.createErrorMessage(++messageId, HashDbIngestModule.this, "Hash Lookup Error: " + name,
|
||||
"Error encountered while setting known state for " + name + "."));
|
||||
ret = ProcessResult.ERROR;
|
||||
}
|
||||
}
|
||||
lookuptime += (System.currentTimeMillis() - lookupstart);
|
||||
} catch (TskException ex) {
|
||||
@ -256,25 +260,13 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
"Error encountered while looking up known hash value for " + name + "."));
|
||||
ret = ProcessResult.ERROR;
|
||||
}
|
||||
|
||||
if (status.equals(TskData.FileKnown.KNOWN)) {
|
||||
try {
|
||||
skCase.setKnown(file, TskData.FileKnown.KNOWN);
|
||||
break;
|
||||
} catch (TskException ex) {
|
||||
logger.log(Level.WARNING, "Couldn't set known state for file " + name + " - see sleuthkit log for details", ex);
|
||||
services.postMessage(IngestMessage.createErrorMessage(++messageId, HashDbIngestModule.this, "Hash Lookup Error: " + name,
|
||||
"Error encountered while setting known state for " + name + "."));
|
||||
ret = ProcessResult.ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void processBadFile(AbstractFile abstractFile, String md5Hash, String hashSetName, boolean showInboxMessage) {
|
||||
private void postHashSetHitToBlackboard(AbstractFile abstractFile, String md5Hash, String hashSetName, boolean showInboxMessage) {
|
||||
try {
|
||||
BlackboardArtifact badFile = abstractFile.newArtifact(ARTIFACT_TYPE.TSK_HASHSET_HIT);
|
||||
//TODO Revisit usage of deprecated constructor as per TSK-583
|
||||
|
718
HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbManager.java
Normal file → Executable file
718
HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbManager.java
Normal file → Executable file
@ -16,52 +16,68 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.sleuthkit.autopsy.hashdatabase;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
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.logging.Level;
|
||||
import java.util.Set;
|
||||
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.autopsy.hashdatabase.HashDb.KnownFilesType;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.netbeans.api.progress.ProgressHandle;
|
||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
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 classify files as known or known bad.
|
||||
* 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 {
|
||||
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";
|
||||
public class HashDbManager implements PropertyChangeListener {
|
||||
|
||||
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 Logger logger = Logger.getLogger(HashDbManager.class.getName());
|
||||
private static HashDbManager instance;
|
||||
private String xmlFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + CUR_HASHSETS_FILE_NAME;
|
||||
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 HashDbManager instance = null;
|
||||
private final String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + CONFIG_FILE_NAME;
|
||||
private List<HashDb> knownHashSets = new ArrayList<>();
|
||||
private List<HashDb> knownBadHashSets = new ArrayList<>();
|
||||
private boolean alwaysCalculateHashes;
|
||||
private Set<String> hashSetNames = new HashSet<>();
|
||||
private Set<String> hashSetPaths = new HashSet<>();
|
||||
private boolean alwaysCalculateHashes = false;
|
||||
|
||||
/**
|
||||
* Gets the singleton instance of this class.
|
||||
@ -80,71 +96,236 @@ public class HashDbManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a hash database to the configuration. Does not check for duplication
|
||||
* of hash set names and does not save the configuration - the configuration
|
||||
* is only saved on demand to support cancellation of configuration panels.
|
||||
* Gets the extension, without the dot separator, that the SleuthKit requires
|
||||
* for the hash database files that combine a database and an index and can
|
||||
* therefore be updated.
|
||||
*/
|
||||
public void addHashSet(HashDb hashDb) {
|
||||
static String getHashDatabaseFileExtension() {
|
||||
return HASH_DATABASE_FILE_EXTENSON;
|
||||
}
|
||||
|
||||
class DuplicateHashSetNameException extends Exception {
|
||||
private DuplicateHashSetNameException(String hashSetName) {
|
||||
super("The hash set name '"+ hashSetName +"' has already been used for another hash database.");
|
||||
}
|
||||
}
|
||||
|
||||
class HashDatabaseDoesNotExistException extends Exception {
|
||||
private HashDatabaseDoesNotExistException(String path) {
|
||||
super("No hash database found at\n" + path);
|
||||
}
|
||||
}
|
||||
|
||||
class HashDatabaseFileAlreadyExistsException extends Exception {
|
||||
private HashDatabaseFileAlreadyExistsException(String path) {
|
||||
super("A file already exists at\n" + path);
|
||||
}
|
||||
}
|
||||
|
||||
class HashDatabaseAlreadyAddedException extends Exception {
|
||||
private HashDatabaseAlreadyAddedException(String path) {
|
||||
super("The hash database at\n" + path + "\nhas already been created or imported.");
|
||||
}
|
||||
}
|
||||
|
||||
class IllegalHashDatabaseFileNameExtensionException extends Exception {
|
||||
private IllegalHashDatabaseFileNameExtensionException() {
|
||||
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 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 representing the hash database.
|
||||
* @throws HashDatabaseDoesNotExistException, DuplicateHashSetNameException, HashDatabaseAlreadyAddedException, TskCoreException
|
||||
*/
|
||||
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(hashSetName);
|
||||
}
|
||||
|
||||
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 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
|
||||
*/
|
||||
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 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(hashSetName);
|
||||
}
|
||||
|
||||
return addHashDatabase(SleuthkitJNI.createHashDatabase(path), hashSetName, searchDuringIngest, sendIngestMessages, knownFilesType);
|
||||
}
|
||||
|
||||
private HashDb addHashDatabase(int handle, String hashSetName, boolean searchDuringIngest, boolean sendIngestMessages, HashDb.KnownFilesType knownFilesType) throws TskCoreException {
|
||||
// Wrap an object around the handle.
|
||||
HashDb hashDb = new HashDb(handle, hashSetName, searchDuringIngest, sendIngestMessages, knownFilesType);
|
||||
|
||||
// Get the indentity data before updating the collections since the
|
||||
// accessor 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());
|
||||
if (!databasePath.equals("None")) {
|
||||
hashSetPaths.add(databasePath);
|
||||
}
|
||||
if (!indexPath.equals("None")) {
|
||||
hashSetPaths.add(indexPath);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
synchronized void indexHashDatabase(HashDb hashDb, boolean deleteIndexFile) {
|
||||
hashDb.addPropertyChangeListener(this);
|
||||
HashDbIndexer creator = new HashDbIndexer(hashDb, deleteIndexFile);
|
||||
creator.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent event) {
|
||||
if (event.getPropertyName().equals(HashDb.Event.INDEXING_DONE.name())) {
|
||||
HashDb hashDb = (HashDb)event.getNewValue();
|
||||
if (null != hashDb) {
|
||||
try {
|
||||
String indexPath = hashDb.getIndexPath();
|
||||
if (!indexPath.equals("None")) {
|
||||
hashSetPaths.add(indexPath);
|
||||
}
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error getting index path of " + hashDb.getHashSetName() + " hash database after indexing", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 void removeHashSet(HashDb hashDb) {
|
||||
synchronized void removeHashDatabase(HashDb hashDb) {
|
||||
// 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, before undertaking 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 throw.
|
||||
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.log(Level.SEVERE, "Error closing hash database at " + hashDb.getDatabasePath(), ex);
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error closing " + hashDb.getHashSetName() + " hash database when removing the database", ex);
|
||||
}
|
||||
knownHashSets.remove(hashDb);
|
||||
knownBadHashSets.remove(hashDb);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 List<HashDb> getAllHashSets() {
|
||||
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 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 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 List<HashDb> getUpdateableHashSets() {
|
||||
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) {
|
||||
@ -156,7 +337,7 @@ 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;
|
||||
@ -166,15 +347,15 @@ public class HashDbManager {
|
||||
* Sets the value for the flag that indicates whether hashes should be calculated
|
||||
* for content even if no hash databases are configured.
|
||||
*/
|
||||
public void alwaysCalculateHashes(boolean alwaysCalculateHashes) {
|
||||
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 boolean shouldAlwaysCalculateHashes() {
|
||||
synchronized boolean getAlwaysCalculateHashes() {
|
||||
return alwaysCalculateHashes;
|
||||
}
|
||||
|
||||
@ -183,7 +364,7 @@ public class HashDbManager {
|
||||
* saved on demand to support cancellation of configuration panels.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
public boolean save() {
|
||||
public synchronized boolean save() {
|
||||
return writeHashSetConfigurationToDisk();
|
||||
}
|
||||
|
||||
@ -191,32 +372,27 @@ public class HashDbManager {
|
||||
* Restores the last saved hash sets configuration. This supports
|
||||
* cancellation of configuration panels.
|
||||
*/
|
||||
public void loadLastSavedConfiguration() {
|
||||
public synchronized void loadLastSavedConfiguration() {
|
||||
closeHashDatabases(knownHashSets);
|
||||
closeHashDatabases(knownBadHashSets);
|
||||
hashSetNames.clear();
|
||||
hashSetPaths.clear();
|
||||
|
||||
if (hashSetsConfigurationFileExists()) {
|
||||
readHashSetsConfigurationFromDisk();
|
||||
}
|
||||
}
|
||||
|
||||
private void closeHashDatabases(List<HashDb> hashDbs) {
|
||||
String dbPath = "";
|
||||
try {
|
||||
for (HashDb db : hashDbs) {
|
||||
dbPath = db.getDatabasePath();
|
||||
db.close();
|
||||
private void closeHashDatabases(List<HashDb> hashDatabases) {
|
||||
for (HashDb database : hashDatabases) {
|
||||
try {
|
||||
database.close();
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error closing " + database.getHashSetName() + " hash database", ex);
|
||||
}
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error closing hash database at " + dbPath, ex);
|
||||
}
|
||||
hashDbs.clear();
|
||||
}
|
||||
|
||||
private boolean hashSetsConfigurationFileExists() {
|
||||
File f = new File(xmlFilePath);
|
||||
return f.exists() && f.canRead() && f.canWrite();
|
||||
hashDatabases.clear();
|
||||
}
|
||||
|
||||
private boolean writeHashSetConfigurationToDisk() {
|
||||
@ -225,33 +401,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, xmlFilePath, ENCODING, doc);
|
||||
success = XMLUtil.saveDoc(HashDbManager.class, configFilePath, ENCODING, doc);
|
||||
}
|
||||
catch (ParserConfigurationException e) {
|
||||
logger.log(Level.SEVERE, "Error saving hash databases", e);
|
||||
catch (ParserConfigurationException ex) {
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error saving hash databases", ex);
|
||||
}
|
||||
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();
|
||||
@ -259,102 +432,176 @@ 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() {
|
||||
final Document doc = XMLUtil.loadDoc(HashDbManager.class, xmlFilePath, XSDFILE);
|
||||
// Open the XML document that implements the configuration file.
|
||||
final Document doc = XMLUtil.loadDoc(HashDbManager.class, configFilePath, XSD_FILE_NAME);
|
||||
if (doc == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
NodeList setsNList = root.getElementsByTagName(SET_EL);
|
||||
// Get the hash set elements.
|
||||
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. Skip to the next hash database if the definition of
|
||||
// a particular hash database is not well-formed.
|
||||
String attributeErrorMessage = " attribute was not set for hash_set at index {0}, cannot make instance of HashDb class";
|
||||
String elementErrorMessage = " element was not set for hash_set at index {0}, cannot make instance of HashDb class";
|
||||
for (int i = 0; i < numSets; ++i) {
|
||||
Element setEl = (Element) setsNList.item(i);
|
||||
final String name = setEl.getAttribute(SET_NAME_ATTR);
|
||||
final String type = setEl.getAttribute(SET_TYPE_ATTR);
|
||||
final String useForIngest = setEl.getAttribute(SET_USE_FOR_INGEST_ATTR);
|
||||
final String showInboxMessages = setEl.getAttribute(SET_SHOW_INBOX_MESSAGES);
|
||||
Boolean useForIngestBool = Boolean.parseBoolean(useForIngest);
|
||||
Boolean showInboxMessagesBool = Boolean.parseBoolean(showInboxMessages);
|
||||
|
||||
String path = null;
|
||||
NodeList pathsNList = setEl.getElementsByTagName(PATH_EL);
|
||||
if (pathsNList.getLength() > 0) {
|
||||
// Shouldn't be more than 1
|
||||
Element pathEl = (Element) pathsNList.item(0);
|
||||
path = pathEl.getTextContent();
|
||||
File database = new File(path);
|
||||
if(!database.exists() && JOptionPane.showConfirmDialog(null, "Database " + name + " could not be found at location\n" + path + "\nWould you like to search for the file?", "Missing Database", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
|
||||
path = searchForFile();
|
||||
String hashSetName = setEl.getAttribute(SET_NAME_ATTRIBUTE);
|
||||
if (hashSetName.isEmpty()) {
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_NAME_ATTRIBUTE + attributeErrorMessage, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle configurations saved before duplicate hash set names were not permitted.
|
||||
if (hashSetNames.contains(hashSetName)) {
|
||||
int suffix = 0;
|
||||
String newHashSetName;
|
||||
do {
|
||||
++suffix;
|
||||
newHashSetName = hashSetName + suffix;
|
||||
}
|
||||
while (hashSetNames.contains(newHashSetName));
|
||||
JOptionPane.showMessageDialog(null, "Duplicate hash set name " + hashSetName + " found.\nReplacing with " + newHashSetName + ".", "Open Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
hashSetName = newHashSetName;
|
||||
}
|
||||
|
||||
if(name.isEmpty()) {
|
||||
logger.log(Level.WARNING, "Name was not set for hash_set at index {0}.", i);
|
||||
String knownFilesType = setEl.getAttribute(SET_TYPE_ATTRIBUTE);
|
||||
if(knownFilesType.isEmpty()) {
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, SET_TYPE_ATTRIBUTE + attributeErrorMessage, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(type.isEmpty()) {
|
||||
logger.log(Level.SEVERE, "Type was not set for hash_set at index {0}, cannot make instance of HashDb class.", i);
|
||||
return false;
|
||||
// Handle legacy known files types.
|
||||
if (knownFilesType.equals("NSRL")) {
|
||||
knownFilesType = HashDb.KnownFilesType.KNOWN.toString();
|
||||
}
|
||||
|
||||
if(useForIngest.isEmpty()) {
|
||||
logger.log(Level.WARNING, "UseForIngest was not set for hash_set at index {0}.", 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 seearchDuringIngestFlag = Boolean.parseBoolean(searchDuringIngest);
|
||||
|
||||
if(showInboxMessages.isEmpty()) {
|
||||
logger.log(Level.WARNING, "ShowInboxMessages was not set for hash_set at index {0}.", 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 sendIngestMessagesFlag = Boolean.parseBoolean(sendIngestMessages);
|
||||
|
||||
if(path == null) {
|
||||
logger.log(Level.WARNING, "No path for hash_set at index {0}, cannot make instance of HashDb class.", i);
|
||||
String dbPath;
|
||||
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.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, PATH_ELEMENT + elementErrorMessage, i);
|
||||
continue;
|
||||
}
|
||||
dbPath = getValidFilePath(hashSetName, dbPath);
|
||||
|
||||
if (null != dbPath) {
|
||||
try {
|
||||
addHashSet(HashDb.openHashDatabase(name, path, useForIngestBool, showInboxMessagesBool, KnownFilesType.valueOf(type)));
|
||||
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 " + path + " hash database.", "Open Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
JOptionPane.showMessageDialog(null, "Unable to open " + dbPath + " hash database.", "Open Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, "No valid path for hash_set at index {0}, cannot make instance of HashDb class", i);
|
||||
}
|
||||
}
|
||||
|
||||
NodeList calcList = root.getElementsByTagName(SET_CALC);
|
||||
// Get the element that stores the always calculate hashes flag.
|
||||
NodeList calcList = root.getElementsByTagName(ALWAYS_CALCULATE_HASHES_ELEMENT);
|
||||
if (calcList.getLength() > 0) {
|
||||
Element calcEl = (Element) calcList.item(0); // Shouldn't be more than 1
|
||||
final String value = calcEl.getAttribute(SET_VALUE);
|
||||
Element calcEl = (Element) calcList.item(0); // Shouldn't be more than one.
|
||||
final String value = calcEl.getAttribute(VALUE_ATTRIBUTE);
|
||||
alwaysCalculateHashes = Boolean.parseBoolean(value);
|
||||
}
|
||||
else {
|
||||
logger.log(Level.WARNING, "No element hash_calculate exists.");
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.WARNING, " element ");
|
||||
alwaysCalculateHashes = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getValidFilePath(String hashSetName, String configuredPath) {
|
||||
// Check the configured path.
|
||||
File database = new File(configuredPath);
|
||||
if (database.exists()) {
|
||||
return configuredPath;
|
||||
}
|
||||
|
||||
// Try a path that could be in an older version of the configuration file.
|
||||
String legacyPath = configuredPath + LEGACY_INDEX_FILE_EXTENSION;
|
||||
database = new File(legacyPath);
|
||||
if (database.exists()) {
|
||||
return legacyPath;
|
||||
}
|
||||
|
||||
// Give the user an opportunity to find the desired file.
|
||||
String newPath = null;
|
||||
if (JOptionPane.showConfirmDialog(null, "Database " + hashSetName + " could not be found at location\n" + configuredPath + "\nWould you like to search for the file?", "Missing Database", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
|
||||
newPath = searchForFile();
|
||||
if (null != newPath && !newPath.isEmpty()) {
|
||||
database = new File(newPath);
|
||||
if (!database.exists()) {
|
||||
newPath = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return newPath;
|
||||
}
|
||||
|
||||
private String searchForFile() {
|
||||
String filePath = null;
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setDragEnabled(false);
|
||||
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
@ -362,18 +609,223 @@ public class HashDbManager {
|
||||
FileNameExtensionFilter filter = new FileNameExtensionFilter("Hash Database File", EXTENSION);
|
||||
fc.setFileFilter(filter);
|
||||
fc.setMultiSelectionEnabled(false);
|
||||
|
||||
String filePath = null;
|
||||
if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
|
||||
File f = fc.getSelectedFile();
|
||||
try {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
return filePath;
|
||||
/**
|
||||
* Property change events published by hash database objects.
|
||||
*/
|
||||
public enum Event {
|
||||
INDEXING_DONE
|
||||
}
|
||||
|
||||
private int handle;
|
||||
private String hashSetName;
|
||||
private boolean searchDuringIngest;
|
||||
private boolean sendIngestMessages;
|
||||
private KnownFilesType knownFilesType;
|
||||
private boolean indexing;
|
||||
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener for the events defined in HashDb.Event.
|
||||
*/
|
||||
public void addPropertyChangeListener(PropertyChangeListener pcl) {
|
||||
propertyChangeSupport.addPropertyChangeListener(pcl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a listener for the events defined in HashDb.Event.
|
||||
*/
|
||||
public void removePropertyChangeListener(PropertyChangeListener pcl) {
|
||||
propertyChangeSupport.removePropertyChangeListener(pcl);
|
||||
}
|
||||
|
||||
public String getHashSetName() {
|
||||
return hashSetName;
|
||||
}
|
||||
|
||||
public String getDatabasePath() throws TskCoreException {
|
||||
return SleuthkitJNI.getHashDatabasePath(handle);
|
||||
}
|
||||
|
||||
public String getIndexPath() throws TskCoreException {
|
||||
return SleuthkitJNI.getHashDatabaseIndexPath(handle);
|
||||
}
|
||||
|
||||
public KnownFilesType getKnownFilesType() {
|
||||
return knownFilesType;
|
||||
}
|
||||
|
||||
public boolean getSearchDuringIngest() {
|
||||
return searchDuringIngest;
|
||||
}
|
||||
|
||||
void setSearchDuringIngest(boolean useForIngest) {
|
||||
this.searchDuringIngest = useForIngest;
|
||||
}
|
||||
|
||||
public boolean getSendIngestMessages() {
|
||||
return sendIngestMessages;
|
||||
}
|
||||
|
||||
void setSendIngestMessages(boolean showInboxMessages) {
|
||||
this.sendIngestMessages = showInboxMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the hash database accepts updates.
|
||||
* @return True if the database accepts updates, false otherwise.
|
||||
*/
|
||||
public boolean isUpdateable() throws TskCoreException {
|
||||
return SleuthkitJNI.isUpdateableHashDatabase(this.handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds hashes of content (if calculated) to the hash database.
|
||||
* @param content The content for which the calculated hashes, if any, are to be added to the hash database.
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
public void addHashes(Content content) throws TskCoreException {
|
||||
addHashes(content, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds hashes of content (if calculated) to the hash database.
|
||||
* @param content The content for which the calculated hashes, if any, are to be added to the hash database.
|
||||
* @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 addHashes(Content content, String comment) throws TskCoreException {
|
||||
// TODO: This only works for AbstractFiles and MD5 hashes at present.
|
||||
assert content instanceof AbstractFile;
|
||||
if (content instanceof AbstractFile) {
|
||||
AbstractFile file = (AbstractFile)content;
|
||||
if (null != file.getMd5Hash()) {
|
||||
SleuthkitJNI.addToHashDatabase(null, file.getMd5Hash(), null, null, comment, handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasMd5HashOf(Content content) throws TskCoreException {
|
||||
boolean result = false;
|
||||
assert content instanceof AbstractFile;
|
||||
if (content instanceof AbstractFile) {
|
||||
AbstractFile file = (AbstractFile)content;
|
||||
if (null != file.getMd5Hash()) {
|
||||
result = SleuthkitJNI.lookupInHashDatabase(file.getMd5Hash(), handle);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public HashInfo lookUp(Content content) throws TskCoreException {
|
||||
HashInfo result = null;
|
||||
// TODO: This only works for AbstractFiles and MD5 hashes at present.
|
||||
assert content instanceof AbstractFile;
|
||||
if (content instanceof AbstractFile) {
|
||||
AbstractFile file = (AbstractFile)content;
|
||||
if (null != file.getMd5Hash()) {
|
||||
result = SleuthkitJNI.lookupInHashDatabaseVerbose(file.getMd5Hash(), handle);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean hasLookupIndex() throws TskCoreException {
|
||||
return SleuthkitJNI.hashDatabaseHasLookupIndex(handle);
|
||||
}
|
||||
|
||||
boolean hasIndexOnly() throws TskCoreException {
|
||||
return SleuthkitJNI.hashDatabaseHasLegacyLookupIndexOnly(handle);
|
||||
}
|
||||
|
||||
boolean canBeReIndexed() throws TskCoreException {
|
||||
return SleuthkitJNI.hashDatabaseCanBeReindexed(handle);
|
||||
}
|
||||
|
||||
boolean isIndexing() {
|
||||
return indexing;
|
||||
}
|
||||
|
||||
private void close() throws TskCoreException {
|
||||
SleuthkitJNI.closeHashDatabase(handle);
|
||||
}
|
||||
}
|
||||
|
||||
private class HashDbIndexer extends SwingWorker<Object, Void> {
|
||||
private ProgressHandle progress = null;
|
||||
private HashDb hashDb = null;
|
||||
private boolean deleteIndexFile = false;
|
||||
|
||||
HashDbIndexer(HashDb hashDb, boolean deleteIndexFile) {
|
||||
this.hashDb = hashDb;
|
||||
this.deleteIndexFile = deleteIndexFile;
|
||||
};
|
||||
|
||||
@Override
|
||||
protected Object doInBackground() {
|
||||
hashDb.indexing = true;
|
||||
progress = ProgressHandleFactory.createHandle("Indexing " + hashDb.hashSetName);
|
||||
progress.start();
|
||||
progress.switchToIndeterminate();
|
||||
try {
|
||||
SleuthkitJNI.createLookupIndexForHashDatabase(hashDb.handle, deleteIndexFile);
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDb.class.getName()).log(Level.SEVERE, "Error indexing hash database", ex);
|
||||
JOptionPane.showMessageDialog(null, "Error indexing " + hashDb.getHashSetName() + " hash database.", "Hash Database Indexing Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
hashDb.indexing = false;
|
||||
progress.finish();
|
||||
hashDb.propertyChangeSupport.firePropertyChange(HashDb.Event.INDEXING_DONE.toString(), null, hashDb);
|
||||
}
|
||||
}
|
||||
}
|
@ -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.
|
||||
@ -210,7 +211,7 @@ class ModalNoButtons extends javax.swing.JDialog implements PropertyChangeListen
|
||||
this.CURRENTLYON_LABEL.setText("Currently indexing 1 database");
|
||||
if (!this.toIndex.isIndexing()) {
|
||||
this.toIndex.addPropertyChangeListener(this);
|
||||
this.toIndex.createIndex(okToDeleteOldIndexFile(toIndex));
|
||||
HashDbManager.getInstance().indexHashDatabase(toIndex, okToDeleteOldIndexFile(toIndex));
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,7 +227,7 @@ class ModalNoButtons extends javax.swing.JDialog implements PropertyChangeListen
|
||||
this.CURRENTLYON_LABEL.setText("Currently indexing 1 of " + length);
|
||||
if (!db.isIndexing()) {
|
||||
db.addPropertyChangeListener(this);
|
||||
db.createIndex(okToDeleteOldIndexFile(db));
|
||||
HashDbManager.getInstance().indexHashDatabase(db, okToDeleteOldIndexFile(db));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -252,7 +253,6 @@ class ModalNoButtons extends javax.swing.JDialog implements PropertyChangeListen
|
||||
} else {
|
||||
currentcount++;
|
||||
this.CURRENTLYON_LABEL.setText("Currently indexing " + currentcount + " of " + length);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user