mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Resolved conflicts for merge of hashdb_sqlite_redux
This commit is contained in:
commit
a6d0c6e583
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.corecomponentinterfaces;
|
||||
|
||||
import java.util.List;
|
||||
import javax.swing.Action;
|
||||
|
||||
/**
|
||||
* Implementers of this interface provide Actions that will be added to context
|
||||
* menus in Autopsy.
|
||||
*/
|
||||
public interface ContextMenuActionsProvider {
|
||||
/**
|
||||
* Gets context menu Actions for the currently selected data model objects
|
||||
* exposed by the NetBeans Lookup of the active TopComponent. Implementers
|
||||
* should discover the selected objects by calling
|
||||
* org.openide.util.Utilities.actionsGlobalContext().lookupAll() for the
|
||||
* org.sleuthkit.datamodel classes of interest to the provider.
|
||||
* @return A list, possibly empty, of Action objects.
|
||||
*/
|
||||
public List<Action> getActions();
|
||||
}
|
49
Core/src/org/sleuthkit/autopsy/coreutils/ContextMenuExtensionPoint.java
Executable file
49
Core/src/org/sleuthkit/autopsy/coreutils/ContextMenuExtensionPoint.java
Executable file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.coreutils;
|
||||
|
||||
import org.openide.util.Lookup;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import javax.swing.Action;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.ContextMenuActionsProvider;
|
||||
|
||||
/**
|
||||
* This class implements the ContextMenuActionsProvider extension point.
|
||||
*/
|
||||
public class ContextMenuExtensionPoint {
|
||||
/**
|
||||
* Gets all of the Actions provided by registered implementers of the
|
||||
* ContextMenuActionsProvider interface.
|
||||
* @return A list, possibly empty, of Action objects.
|
||||
*/
|
||||
static public List<Action> getActions() {
|
||||
ArrayList<Action> actions = new ArrayList<>();
|
||||
Collection<? extends ContextMenuActionsProvider> actionProviders = Lookup.getDefault().lookupAll(ContextMenuActionsProvider.class);
|
||||
for (ContextMenuActionsProvider provider : actionProviders) {
|
||||
List<Action> providerActions = provider.getActions();
|
||||
if (!providerActions.isEmpty()) {
|
||||
actions.add(null); // Separator to set off this provider's actions.
|
||||
actions.addAll(provider.getActions());
|
||||
}
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 Basis Technology Corp.
|
||||
* Copyright 2011 - 2013 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.datamodel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.Action;
|
||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||
import org.sleuthkit.autopsy.actions.AddContentTagAction;
|
||||
import org.sleuthkit.autopsy.directorytree.ExtractAction;
|
||||
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
|
||||
@ -77,6 +78,7 @@ public class DirectoryNode extends AbstractFsContentNode<AbstractFile> {
|
||||
actions.add(ExtractAction.getInstance());
|
||||
actions.add(null); // creates a menu separator
|
||||
actions.add(AddContentTagAction.getInstance());
|
||||
actions.addAll(ContextMenuExtensionPoint.getActions());
|
||||
return actions.toArray(new Action[0]);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 Basis Technology Corp.
|
||||
* Copyright 2011 - 2013 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.datamodel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.Action;
|
||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||
import org.sleuthkit.autopsy.actions.AddContentTagAction;
|
||||
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
|
||||
import org.sleuthkit.autopsy.directorytree.ExtractAction;
|
||||
@ -85,6 +86,7 @@ public class FileNode extends AbstractFsContentNode<AbstractFile> {
|
||||
actionsList.add(new HashSearchAction("Search for files with the same MD5 hash", this));
|
||||
actionsList.add(null); // creates a menu separator
|
||||
actionsList.add(AddContentTagAction.getInstance());
|
||||
actionsList.addAll(ContextMenuExtensionPoint.getActions());
|
||||
return actionsList.toArray(new Action[0]);
|
||||
}
|
||||
|
||||
@ -172,4 +174,4 @@ public class FileNode extends AbstractFsContentNode<AbstractFile> {
|
||||
public boolean isLeafTypeNode() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 Basis Technology Corp.
|
||||
* Copyright 2011 - 2013 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -24,6 +24,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.swing.Action;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
|
||||
import org.sleuthkit.autopsy.directorytree.ExtractAction;
|
||||
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
|
||||
@ -102,13 +103,14 @@ public class LayoutFileNode extends AbstractAbstractFileNode<LayoutFile> {
|
||||
|
||||
@Override
|
||||
public Action[] getActions(boolean context) {
|
||||
List<Action> actionsList = new ArrayList<Action>();
|
||||
List<Action> actionsList = new ArrayList<>();
|
||||
actionsList.add(new NewWindowViewAction("View in New Window", this));
|
||||
actionsList.add(new ExternalViewerAction("Open in External Viewer", this));
|
||||
actionsList.add(null); // creates a menu separator
|
||||
actionsList.add(ExtractAction.getInstance());
|
||||
actionsList.add(null); // creates a menu separator
|
||||
actionsList.add(AddContentTagAction.getInstance());
|
||||
actionsList.addAll(ContextMenuExtensionPoint.getActions());
|
||||
return actionsList.toArray(new Action[0]);
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.swing.Action;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
|
||||
import org.sleuthkit.autopsy.directorytree.ExtractAction;
|
||||
import org.sleuthkit.autopsy.directorytree.HashSearchAction;
|
||||
@ -87,6 +88,7 @@ public class LocalFileNode extends AbstractAbstractFileNode<AbstractFile> {
|
||||
actionsList.add(new HashSearchAction("Search for files with the same MD5 hash", this));
|
||||
actionsList.add(null); // creates a menu separator
|
||||
actionsList.add(AddContentTagAction.getInstance());
|
||||
actionsList.addAll(ContextMenuExtensionPoint.getActions());
|
||||
return actionsList.toArray(new Action[0]);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 Basis Technology Corp.
|
||||
* Copyright 2011 - 2013 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -24,6 +24,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.swing.Action;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.directorytree.ExtractAction;
|
||||
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
|
||||
@ -82,6 +83,7 @@ public class VirtualDirectoryNode extends AbstractAbstractFileNode<VirtualDirect
|
||||
actions.add(ExtractAction.getInstance());
|
||||
actions.add(null); // creates a menu separator
|
||||
actions.add(AddContentTagAction.getInstance());
|
||||
actions.addAll(ContextMenuExtensionPoint.getActions());
|
||||
return actions.toArray(new Action[0]);
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.FilterNode;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||
import org.sleuthkit.autopsy.datamodel.AbstractAbstractFileNode.AbstractFilePropertyType;
|
||||
import org.sleuthkit.autopsy.datamodel.AbstractFsContentNode;
|
||||
import org.sleuthkit.autopsy.datamodel.ArtifactTypeNode;
|
||||
@ -210,6 +211,7 @@ public class DataResultFilterNode extends FilterNode {
|
||||
actions.add(null); // creates a menu separator
|
||||
actions.add(AddContentTagAction.getInstance());
|
||||
actions.add(AddBlackboardArtifactTagAction.getInstance());
|
||||
actions.addAll(ContextMenuExtensionPoint.getActions());
|
||||
}
|
||||
}
|
||||
if ((d = ban.getLookup().lookup(Directory.class)) != null) {
|
||||
@ -226,6 +228,7 @@ public class DataResultFilterNode extends FilterNode {
|
||||
actions.add(null); // creates a menu separator
|
||||
actions.add(AddContentTagAction.getInstance());
|
||||
actions.add(AddBlackboardArtifactTagAction.getInstance());
|
||||
actions.addAll(ContextMenuExtensionPoint.getActions());
|
||||
}
|
||||
}
|
||||
if ((vd = ban.getLookup().lookup(VirtualDirectory.class)) != null) {
|
||||
@ -242,6 +245,7 @@ public class DataResultFilterNode extends FilterNode {
|
||||
actions.add(null); // creates a menu separator
|
||||
actions.add(AddContentTagAction.getInstance());
|
||||
actions.add(AddBlackboardArtifactTagAction.getInstance());
|
||||
actions.addAll(ContextMenuExtensionPoint.getActions());
|
||||
}
|
||||
} else if ((lf = ban.getLookup().lookup(LayoutFile.class)) != null) {
|
||||
LayoutFileNode lfn = new LayoutFileNode(lf);
|
||||
@ -257,6 +261,7 @@ public class DataResultFilterNode extends FilterNode {
|
||||
actions.add(null); // creates a menu separator
|
||||
actions.add(AddContentTagAction.getInstance());
|
||||
actions.add(AddBlackboardArtifactTagAction.getInstance());
|
||||
actions.addAll(ContextMenuExtensionPoint.getActions());
|
||||
}
|
||||
} else if ((locF = ban.getLookup().lookup(LocalFile.class)) != null
|
||||
|| (locF = ban.getLookup().lookup(DerivedFile.class)) != null) {
|
||||
@ -273,6 +278,7 @@ public class DataResultFilterNode extends FilterNode {
|
||||
actions.add(null); // creates a menu separator
|
||||
actions.add(AddContentTagAction.getInstance());
|
||||
actions.add(AddBlackboardArtifactTagAction.getInstance());
|
||||
actions.addAll(ContextMenuExtensionPoint.getActions());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 Basis Technology Corp.
|
||||
* Copyright 2011 - 2013 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -36,6 +36,7 @@ import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.ContentVisitor;
|
||||
@ -101,40 +102,45 @@ public class ExplorerNodeActionVisitor extends ContentVisitor.Default<List<? ext
|
||||
|
||||
@Override
|
||||
public List<? extends Action> visit(final Directory d) {
|
||||
List<Action> actions = new ArrayList<Action>();
|
||||
List<Action> actions = new ArrayList<>();
|
||||
actions.add(AddContentTagAction.getInstance());
|
||||
actions.addAll(ContextMenuExtensionPoint.getActions());
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Action> visit(final VirtualDirectory d) {
|
||||
List<Action> actions = new ArrayList<Action>();
|
||||
List<Action> actions = new ArrayList<>();
|
||||
actions.add(ExtractAction.getInstance());
|
||||
actions.add(AddContentTagAction.getInstance());
|
||||
actions.addAll(ContextMenuExtensionPoint.getActions());
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Action> visit(final DerivedFile d) {
|
||||
List<Action> actions = new ArrayList<Action>();
|
||||
List<Action> actions = new ArrayList<>();
|
||||
actions.add(ExtractAction.getInstance());
|
||||
actions.add(AddContentTagAction.getInstance());
|
||||
actions.addAll(ContextMenuExtensionPoint.getActions());
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Action> visit(final LocalFile d) {
|
||||
List<Action> actions = new ArrayList<Action>();
|
||||
List<Action> actions = new ArrayList<>();
|
||||
actions.add(ExtractAction.getInstance());
|
||||
actions.add(AddContentTagAction.getInstance());
|
||||
actions.addAll(ContextMenuExtensionPoint.getActions());
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Action> visit(final org.sleuthkit.datamodel.File d) {
|
||||
List<Action> actions = new ArrayList<Action>();
|
||||
List<Action> actions = new ArrayList<>();
|
||||
actions.add(ExtractAction.getInstance());
|
||||
actions.add(AddContentTagAction.getInstance());
|
||||
actions.addAll(ContextMenuExtensionPoint.getActions());
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
@ -81,10 +81,19 @@
|
||||
<specification-version>7.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.sleuthkit.autopsy.corelibs</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>3</release-version>
|
||||
<specification-version>1.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
</module-dependencies>
|
||||
<public-packages>
|
||||
<package>org.sleuthkit.autopsy.hashdatabase</package>
|
||||
</public-packages>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
</project>
|
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 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.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
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;
|
||||
import org.openide.util.Utilities;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.actions.Presenter;
|
||||
import org.sleuthkit.autopsy.ingest.IngestConfigurator;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* 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).
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
}
|
||||
|
||||
private class AddContentToHashDbMenu extends JMenu {
|
||||
AddContentToHashDbMenu(String menuText) {
|
||||
super(menuText);
|
||||
|
||||
// Get the current set of updateable hash databases and add each
|
||||
// one as a menu item.
|
||||
List<HashDb> hashDatabases = HashDbManager.getInstance().getKnownBadHashSets();
|
||||
if (!hashDatabases.isEmpty()) {
|
||||
for (final HashDb database : HashDbManager.getInstance().getUpdateableHashSets()) {
|
||||
JMenuItem databaseItem = add(database.getDisplayName());
|
||||
databaseItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Collection<? extends AbstractFile> selectedFiles = Utilities.actionsGlobalContext().lookupAll(AbstractFile.class);
|
||||
for (AbstractFile file : selectedFiles) {
|
||||
String md5Hash = file.getMd5Hash();
|
||||
if (null != md5Hash) {
|
||||
try {
|
||||
database.add(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
JMenuItem empty = new JMenuItem("No hash databases");
|
||||
empty.setEnabled(false);
|
||||
add(empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -8,18 +8,6 @@ HashDbSimplePanel.knownLabel.text=NSRL Database:
|
||||
HashDbSimplePanel.notableLabel.text=Known Bad Database(s):
|
||||
HashDbSimplePanel.knownValLabel.text=-
|
||||
HashDbSimplePanel.notableValLabel.text=-
|
||||
HashDbSimplePanel.jLabel1.text=Enable known bad databases for ingest:
|
||||
HashDbAddDatabaseDialog.cancelButton.text=Cancel
|
||||
HashDbAddDatabaseDialog.okButton.text=OK
|
||||
HashDbAddDatabaseDialog.nsrlRadioButton.text=NSRL
|
||||
HashDbAddDatabaseDialog.knownBadRadioButton.text=Known Bad
|
||||
HashDbAddDatabaseDialog.databasePathTextField.text=
|
||||
HashDbAddDatabaseDialog.browseButton.text=Browse
|
||||
HashDbAddDatabaseDialog.jLabel1.text=Enter the name of the database:
|
||||
HashDbAddDatabaseDialog.databaseNameTextField.text=
|
||||
HashDbAddDatabaseDialog.jLabel2.text=Select the type of database:
|
||||
HashDbAddDatabaseDialog.useForIngestCheckbox.text=Enable for ingest
|
||||
HashDbAddDatabaseDialog.sendInboxMessagesCheckbox.text=Enable sending messages to inbox during ingest
|
||||
HashDbSearchPanel.hashTable.columnModel.title0=MD5 Hashes
|
||||
HashDbSearchPanel.hashTable.columnModel.title3=Title 4
|
||||
HashDbSearchPanel.hashTable.columnModel.title2=Title 3
|
||||
@ -33,32 +21,56 @@ HashDbSearchPanel.titleLabel.text=Search for files with the following MD5 hash(e
|
||||
HashDbSearchPanel.errorField.text=Error: Not all files have been hashed.
|
||||
HashDbSearchPanel.saveBox.text=Remember Hashes
|
||||
HashDbSearchPanel.cancelButton.text=Cancel
|
||||
HashDbSimplePanel.calcHashesButton.text=Calculate hashes even if no hash database is selected
|
||||
HashDbSimplePanel.nsrlDbLabel.text=NSRL Database:
|
||||
HashDbSimplePanel.nsrlDbLabelVal.text=-
|
||||
HashDbManagementPanel.hashDbIndexStatusLabel.text=No database selected
|
||||
HashDbManagementPanel.jLabel2.text=Name:
|
||||
HashDbManagementPanel.showInboxMessagesCheckBox.text=Enable sending messages to inbox during ingest
|
||||
HashDbManagementPanel.useForIngestCheckbox.text=Enable for ingest
|
||||
HashDbManagementPanel.indexButton.text=Index
|
||||
HashDbManagementPanel.indexLabel.text=Index Status:
|
||||
HashDbManagementPanel.optionsLabel.text=Options
|
||||
HashDbManagementPanel.jLabel4.text=Location:
|
||||
HashDbManagementPanel.jLabel6.text=Type:
|
||||
HashDbManagementPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes.
|
||||
HashDbManagementPanel.hashDbTypeLabel.text=No database selected
|
||||
HashDbManagementPanel.typeLabel.text=Type:
|
||||
HashDbManagementPanel.deleteButton.text=Delete Database
|
||||
HashDbManagementPanel.importButton.text=Import Database
|
||||
HashDbManagementPanel.hashDbNameLabel.text=No database selected
|
||||
HashDbManagementPanel.nameLabel.text=Name:
|
||||
HashDbManagementPanel.jButton3.text=Import Database
|
||||
HashDbManagementPanel.locationLabel.text=Location:
|
||||
HashDbManagementPanel.hashDbLocationLabel.text=No database selected
|
||||
HashDbManagementPanel.informationLabel.text=Information
|
||||
HashDbManagementPanel.hashDatabasesLabel.text=Hash Databases:
|
||||
OpenIDE-Module-Short-Description=Hash Database Ingest Module and hash db tools
|
||||
ModalNoButtons.CURRENTLYON_LABEL.text=Currently Indexing x of y
|
||||
ModalNoButtons.GO_GET_COFFEE_LABEL.text=Hash databases are currently being indexed, this may take some time.
|
||||
ModalNoButtons.CURRENTDB_LABEL.text=(CurrentDb)
|
||||
ModalNoButtons.CANCEL_BUTTON.text=Cancel
|
||||
HashDbImportDatabaseDialog.sendInboxMessagesCheckbox.text=Enable sending messages to inbox during ingest
|
||||
HashDbImportDatabaseDialog.useForIngestCheckbox.text=Enable for ingest
|
||||
HashDbImportDatabaseDialog.jLabel1.text=Display name of database:
|
||||
HashDbImportDatabaseDialog.databaseNameTextField.text=
|
||||
HashDbImportDatabaseDialog.databasePathTextField.text=
|
||||
HashDbImportDatabaseDialog.browseButton.text=Browse
|
||||
HashDbImportDatabaseDialog.nsrlRadioButton.text=NSRL
|
||||
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.knownBadRadioButton.text=Known Bad
|
||||
HashDbCreateDatabaseDialog.nsrlRadioButton.text=NSRL
|
||||
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=Display name of database:
|
||||
HashDbCreateDatabaseDialog.databaseNameTextField.text=
|
||||
HashDbConfigPanel.nameLabel.text=Name:
|
||||
HashDbConfigPanel.hashDbNameLabel.text=No database selected
|
||||
HashDbConfigPanel.hashDatabasesLabel.text=Hash Databases:
|
||||
HashDbConfigPanel.hashDbLocationLabel.text=No database selected
|
||||
HashDbConfigPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes.
|
||||
HashDbConfigPanel.jButton3.text=Import Database
|
||||
HashDbConfigPanel.jLabel6.text=Type:
|
||||
HashDbConfigPanel.jLabel4.text=Location:
|
||||
HashDbConfigPanel.jLabel2.text=Name:
|
||||
HashDbConfigPanel.optionsLabel.text=Options
|
||||
HashDbConfigPanel.typeLabel.text=Type:
|
||||
HashDbConfigPanel.locationLabel.text=Location:
|
||||
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.nsrlDbLabelVal.text=-
|
||||
HashDbSimpleConfigPanel.calcHashesButton.text=Calculate hashes even if no hash database is selected
|
||||
HashDbSimpleConfigPanel.jLabel1.text=Enable known bad databases for ingest:
|
||||
HashDbSimpleConfigPanel.nsrlDbLabel.text=NSRL Database:
|
||||
HashDbConfigPanel.newDatabaseButton.text=New Database
|
||||
HashDbConfigPanel.importDatabaseButton.text=Import Database
|
||||
HashDbConfigPanel.deleteDatabaseButton.text=Delete Database
|
@ -36,7 +36,7 @@ id = "HashDatabase")
|
||||
@org.openide.util.NbBundle.Messages({"OptionsCategory_Name_HashDatabase=Hash Database", "OptionsCategory_Keywords_HashDatabase=Hash Database"})
|
||||
public final class HashDatabaseOptionsPanelController extends OptionsPanelController {
|
||||
|
||||
private HashDbManagementPanel panel;
|
||||
private HashDbConfigPanel panel;
|
||||
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
||||
private boolean changed;
|
||||
|
||||
@ -55,7 +55,7 @@ public final class HashDatabaseOptionsPanelController extends OptionsPanelContro
|
||||
@Override
|
||||
public void cancel() {
|
||||
// Reset the XML on cancel
|
||||
HashDbXML.getCurrent().reload();
|
||||
HashDbManager.getInstance().loadLastSavedConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -88,9 +88,9 @@ public final class HashDatabaseOptionsPanelController extends OptionsPanelContro
|
||||
pcs.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
private HashDbManagementPanel getPanel() {
|
||||
private HashDbConfigPanel getPanel() {
|
||||
if (panel == null) {
|
||||
panel = new HashDbManagementPanel();
|
||||
panel = new HashDbConfigPanel();
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 Basis Technology Corp.
|
||||
* Copyright 2011 - 2013 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -20,285 +20,248 @@ package org.sleuthkit.autopsy.hashdatabase;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.netbeans.api.progress.ProgressHandle;
|
||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||
import org.openide.util.Cancellable;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.SleuthkitJNI;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
/**
|
||||
* Hash database representation of NSRL and Known Bad hash databases
|
||||
* with indexing capability
|
||||
*
|
||||
* Instances of this class represent the hash databases underlying known files
|
||||
* hash sets.
|
||||
*/
|
||||
public class HashDb implements Comparable<HashDb> {
|
||||
|
||||
enum EVENT {INDEXING_DONE };
|
||||
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
||||
public enum Event {
|
||||
INDEXING_DONE
|
||||
}
|
||||
|
||||
|
||||
public enum DBType{
|
||||
NSRL("NSRL"), KNOWN_BAD("Known Bad");
|
||||
public enum KnownFilesType{
|
||||
NSRL("NSRL"),
|
||||
KNOWN_BAD("Known Bad");
|
||||
|
||||
private String displayName;
|
||||
|
||||
private DBType(String displayName) {
|
||||
private KnownFilesType(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
String getDisplayName() {
|
||||
return this.displayName;
|
||||
}
|
||||
}
|
||||
|
||||
// Suffix added to the end of a database name to get its index file
|
||||
private static final String INDEX_SUFFIX = "-md5.idx";
|
||||
/**
|
||||
* Opens an existing 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 hash database should be used during ingest.
|
||||
* @param showInboxMessages A flag indicating whether hash set hit messages should be sent to the application inbox.
|
||||
* @param knownType The known files type of the database.
|
||||
* @return A HashDb object representation of the new hash database.
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
public static HashDb openHashDatabase(String hashSetName, String databasePath, boolean useForIngest, boolean showInboxMessages, KnownFilesType knownType) throws TskCoreException {
|
||||
return new HashDb(SleuthkitJNI.openHashDatabase(databasePath), hashSetName, databasePath, useForIngest, showInboxMessages, knownType);
|
||||
}
|
||||
|
||||
private String name;
|
||||
private List<String> databasePaths; // TODO: Length limited to one for now...
|
||||
/**
|
||||
* Creates a new hash database.
|
||||
* @param hashSetName Name used to represent the 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 knownType The known files type of 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 type) throws TskCoreException {
|
||||
return new HashDb(SleuthkitJNI.createHashDatabase(databasePath), hashSetName, databasePath, useForIngest, showInboxMessages, type);
|
||||
}
|
||||
|
||||
private static final String INDEX_FILE_EXTENSION = ".kdb";
|
||||
private static final String LEGACY_INDEX_FILE_EXTENSION = "-md5.idx";
|
||||
|
||||
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
private String displayName;
|
||||
private String databasePath;
|
||||
private boolean useForIngest;
|
||||
private boolean showInboxMessages;
|
||||
private KnownFilesType type;
|
||||
private int handle;
|
||||
private boolean indexing;
|
||||
private DBType type;
|
||||
|
||||
public HashDb(String name, List<String> databasePaths, boolean useForIngest, boolean showInboxMessages, DBType type) {
|
||||
this.name = name;
|
||||
this.databasePaths = databasePaths;
|
||||
HashDb(int handle, String name, String databasePath, boolean useForIngest, boolean showInboxMessages, KnownFilesType type) {
|
||||
this.displayName = name;
|
||||
this.databasePath = databasePath;
|
||||
this.useForIngest = useForIngest;
|
||||
this.showInboxMessages = showInboxMessages;
|
||||
this.type = type;
|
||||
this.handle = handle;
|
||||
this.indexing = false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int compareTo(HashDb o) {
|
||||
return this.displayName.compareTo(o.displayName);
|
||||
}
|
||||
|
||||
void addPropertyChangeListener(PropertyChangeListener pcl) {
|
||||
pcs.addPropertyChangeListener(pcl);
|
||||
propertyChangeSupport.addPropertyChangeListener(pcl);
|
||||
}
|
||||
|
||||
void removePropertyChangeListener(PropertyChangeListener pcl) {
|
||||
pcs.removePropertyChangeListener(pcl);
|
||||
propertyChangeSupport.removePropertyChangeListener(pcl);
|
||||
}
|
||||
|
||||
String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
String getDatabasePath() {
|
||||
return databasePath;
|
||||
}
|
||||
|
||||
KnownFilesType getKnownFilesType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
boolean getUseForIngest() {
|
||||
return useForIngest;
|
||||
}
|
||||
|
||||
boolean getShowInboxMessages() {
|
||||
return showInboxMessages;
|
||||
}
|
||||
|
||||
DBType getDbType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
List<String> getDatabasePaths() {
|
||||
return databasePaths;
|
||||
}
|
||||
|
||||
|
||||
void setUseForIngest(boolean useForIngest) {
|
||||
this.useForIngest = useForIngest;
|
||||
}
|
||||
|
||||
boolean getShowInboxMessages() {
|
||||
return showInboxMessages;
|
||||
}
|
||||
|
||||
void setShowInboxMessages(boolean showInboxMessages) {
|
||||
this.showInboxMessages = showInboxMessages;
|
||||
}
|
||||
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
void setDatabasePaths(List<String> databasePaths) {
|
||||
this.databasePaths = databasePaths;
|
||||
}
|
||||
|
||||
void setDbType(DBType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the database exists.
|
||||
* @return true if a file exists at the database path, else false
|
||||
*/
|
||||
boolean databaseExists() {
|
||||
return databaseFile().exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if Sleuth Kit can open the index for the database path.
|
||||
* @return true if the index was found and opened successfully, else false
|
||||
*/
|
||||
boolean indexExists() {
|
||||
|
||||
boolean hasLookupIndex() {
|
||||
try {
|
||||
return hasIndex(databasePaths.get(0)); // TODO: support multiple paths
|
||||
} catch (TskException ex) {
|
||||
Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Error checking if index exists.", ex);
|
||||
return SleuthkitJNI.hashDatabaseHasLookupIndex(handle);
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
// RJCTODO
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the database file.
|
||||
* @return a File initialized with the database path
|
||||
*/
|
||||
File databaseFile() {
|
||||
return new File(databasePaths.get(0)); // TODO: support multiple paths
|
||||
|
||||
boolean hasTextLookupIndexOnly() throws TskCoreException {
|
||||
return SleuthkitJNI.hashDatabaseHasLegacyLookupIndexOnly(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index file
|
||||
* @return a File initialized with an index path derived from the database
|
||||
* path
|
||||
* Indicates whether the hash database accepts updates.
|
||||
* @return True if the database accepts updates, false otherwise.
|
||||
*/
|
||||
File indexFile() {
|
||||
return new File(toIndexPath(databasePaths.get(0))); // TODO: support multiple paths
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the index file is older than the database file
|
||||
* @return true if there is are files at the index path and the database
|
||||
* path, and the index file has an older modified-time than the database
|
||||
* file, else false
|
||||
*/
|
||||
boolean isOutdated() {
|
||||
File i = indexFile();
|
||||
File db = databaseFile();
|
||||
|
||||
return i.exists() && db.exists() && isOlderThan(i, db);
|
||||
public boolean isUpdateable() throws TskCoreException {
|
||||
return SleuthkitJNI.isUpdateableHashDatabase(this.handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the database is being indexed
|
||||
* 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
|
||||
*/
|
||||
boolean isIndexing() {
|
||||
return indexing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status of the HashDb as determined from indexExists(),
|
||||
* databaseExists(), and isOutdated()
|
||||
* @return IndexStatus enum according to their definitions
|
||||
*/
|
||||
IndexStatus status() {
|
||||
boolean i = this.indexExists();
|
||||
boolean db = this.databaseExists();
|
||||
|
||||
if(indexing)
|
||||
return IndexStatus.INDEXING;
|
||||
if (i) {
|
||||
if (db) {
|
||||
return this.isOutdated() ? IndexStatus.INDEX_OUTDATED : IndexStatus.INDEX_CURRENT;
|
||||
} else {
|
||||
return IndexStatus.NO_DB;
|
||||
public void add(Content content) 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(), "", "", handle);
|
||||
}
|
||||
} else {
|
||||
return db ? IndexStatus.NO_INDEX : IndexStatus.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public TskData.FileKnown lookUp(Content content) throws TskCoreException {
|
||||
TskData.FileKnown result = TskData.FileKnown.UKNOWN;
|
||||
// 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()) {
|
||||
if (type == KnownFilesType.NSRL) {
|
||||
result = SleuthkitJNI.lookupInNSRLDatabase(file.getMd5Hash());
|
||||
}
|
||||
else {
|
||||
result = SleuthkitJNI.lookupInHashDatabase(file.getMd5Hash(), handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to index the database (overwrites any existing index)
|
||||
* @throws TskException if an error occurs in the SleuthKit bindings
|
||||
*/
|
||||
void createIndex() throws TskException {
|
||||
indexing = true;
|
||||
CreateIndex creator = new CreateIndex();
|
||||
creator.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if one file is older than an other
|
||||
* @param a first file
|
||||
* @param b second file
|
||||
* @return true if the first file's last modified data is before the second
|
||||
* file's last modified date
|
||||
*/
|
||||
private static boolean isOlderThan(File a, File b) {
|
||||
return a.lastModified() < b.lastModified();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a path points to an index by checking the suffix
|
||||
* @param path
|
||||
* @return true if index
|
||||
*/
|
||||
static boolean isIndexPath(String path) {
|
||||
return path.endsWith(INDEX_SUFFIX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives database path from an image path by removing the suffix.
|
||||
* @param indexPath
|
||||
* @return
|
||||
*/
|
||||
static String toDatabasePath(String indexPath) {
|
||||
return indexPath.substring(0, indexPath.lastIndexOf(INDEX_SUFFIX));
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives image path from an database path by appending the suffix.
|
||||
* Derives index path from an database path by appending the suffix.
|
||||
* @param databasePath
|
||||
* @return
|
||||
*/
|
||||
static String toIndexPath(String databasePath) {
|
||||
return databasePath.concat(INDEX_SUFFIX);
|
||||
return databasePath.concat(INDEX_FILE_EXTENSION);
|
||||
}
|
||||
|
||||
boolean isIndexing() {
|
||||
return indexing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls Sleuth Kit method via JNI to determine whether there is an
|
||||
* index for the given path
|
||||
* @param databasePath path Path for the database the index is of
|
||||
* (database doesn't have to actually exist)'
|
||||
* @return true if index exists
|
||||
* @throws TskException if there is an error in the JNI call
|
||||
*/
|
||||
static boolean hasIndex(String databasePath) throws TskException {
|
||||
return SleuthkitJNI.lookupIndexExists(databasePath);
|
||||
IndexStatus getStatus() throws TskCoreException {
|
||||
IndexStatus status = IndexStatus.NO_INDEX;
|
||||
|
||||
if (indexing) {
|
||||
status = IndexStatus.INDEXING;
|
||||
}
|
||||
else if (hasLookupIndex()) {
|
||||
if (hasTextLookupIndexOnly()) {
|
||||
status = IndexStatus.INDEX_ONLY;
|
||||
}
|
||||
else {
|
||||
status = IndexStatus.INDEXED;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(HashDb o) {
|
||||
return this.name.compareTo(o.name);
|
||||
|
||||
// Tries to index the database (overwrites any existing index) using a
|
||||
// SwingWorker.
|
||||
void createIndex() throws TskCoreException {
|
||||
CreateIndex creator = new CreateIndex();
|
||||
creator.execute();
|
||||
}
|
||||
|
||||
/* Thread that creates a database's index */
|
||||
|
||||
private class CreateIndex extends SwingWorker<Object,Void> {
|
||||
|
||||
private ProgressHandle progress;
|
||||
|
||||
CreateIndex(){};
|
||||
CreateIndex() {
|
||||
};
|
||||
|
||||
@Override
|
||||
protected Object doInBackground() throws Exception {
|
||||
progress = ProgressHandleFactory.createHandle("Indexing " + name);
|
||||
|
||||
/** We need proper cancel support in TSK to make the task cancellable
|
||||
new Cancellable() {
|
||||
Override
|
||||
public boolean cancel() {
|
||||
return CreateIndex.this.cancel(true);
|
||||
}
|
||||
});
|
||||
*/
|
||||
indexing = true;
|
||||
progress = ProgressHandleFactory.createHandle("Indexing " + displayName);
|
||||
progress.start();
|
||||
progress.switchToIndeterminate();
|
||||
SleuthkitJNI.createLookupIndex(databasePaths.get(0));
|
||||
SleuthkitJNI.createLookupIndexForHashDatabase(handle); // RJCTODO: There is nobody to catch, fix this.
|
||||
return null;
|
||||
}
|
||||
|
||||
/* clean up or start the worker threads */
|
||||
@Override
|
||||
protected void done() {
|
||||
indexing = false;
|
||||
progress.finish();
|
||||
pcs.firePropertyChange(EVENT.INDEXING_DONE.toString(), null, name);
|
||||
propertyChangeSupport.firePropertyChange(Event.INDEXING_DONE.toString(), null, displayName);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,21 +5,21 @@
|
||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel4">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.jLabel4.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.jLabel4.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel6">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.jLabel6.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.jLabel6.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
@ -29,7 +29,7 @@
|
||||
<Font name="Tahoma" size="14" style="0"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.jButton3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.jButton3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
@ -62,14 +62,7 @@
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="hashDatabasesLabel" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="1" max="-2" attributes="0">
|
||||
<Component id="jScrollPane1" pref="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="importButton" min="-2" pref="133" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="deleteButton" min="-2" pref="132" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Component id="jScrollPane1" min="-2" pref="275" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
@ -115,6 +108,12 @@
|
||||
</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>
|
||||
<Component id="deleteDatabaseButton" alignment="0" min="-2" pref="133" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace pref="40" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
@ -170,14 +169,16 @@
|
||||
<Component id="ingestWarningLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="jScrollPane1" pref="422" max="32767" attributes="0"/>
|
||||
<Component id="jScrollPane1" pref="391" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="importButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="deleteButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="importDatabaseButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="newDatabaseButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="deleteDatabaseButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -189,7 +190,7 @@
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/hashdatabase/warning16.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="HashDbManagementPanel.ingestWarningLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.ingestWarningLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
@ -223,13 +224,13 @@
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="deleteButton">
|
||||
<Component class="javax.swing.JButton" name="deleteDatabaseButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/hashdatabase/delete16.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="HashDbManagementPanel.deleteButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.deleteDatabaseButton.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]"/>
|
||||
@ -242,16 +243,16 @@
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteButtonActionPerformed"/>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteDatabaseButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="importButton">
|
||||
<Component class="javax.swing.JButton" name="importDatabaseButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/hashdatabase/import16.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="HashDbManagementPanel.importButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.importDatabaseButton.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]"/>
|
||||
@ -264,76 +265,76 @@
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="importButtonActionPerformed"/>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="importDatabaseButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="hashDatabasesLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.hashDatabasesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.hashDatabasesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="nameLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.nameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.nameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="hashDbNameLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.hashDbNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.hashDbNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="hashDbLocationLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.hashDbLocationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.hashDbLocationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="locationLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.locationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.locationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="typeLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.typeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.typeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="hashDbTypeLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.hashDbTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.hashDbTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="hashDbIndexStatusLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.hashDbIndexStatusLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.hashDbIndexStatusLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="indexLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.indexLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.indexLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="indexButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.indexButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.indexButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
@ -344,7 +345,7 @@
|
||||
<Component class="javax.swing.JCheckBox" name="useForIngestCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.useForIngestCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.useForIngestCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
@ -354,7 +355,7 @@
|
||||
<Component class="javax.swing.JCheckBox" name="showInboxMessagesCheckBox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.showInboxMessagesCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.showInboxMessagesCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
@ -364,14 +365,14 @@
|
||||
<Component class="javax.swing.JLabel" name="informationLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.informationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.informationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="optionsLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbManagementPanel.optionsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.optionsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
@ -379,5 +380,27 @@
|
||||
</Component>
|
||||
<Component class="javax.swing.JSeparator" name="optionsSeparator">
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="newDatabaseButton">
|
||||
<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}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[140, 25]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[140, 25]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[140, 25]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="newDatabaseButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import javax.swing.Action;
|
||||
import org.openide.util.Utilities;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.ContextMenuActionsProvider;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
@ServiceProvider(service = ContextMenuActionsProvider.class)
|
||||
public class HashDbContextMenuActionsProvider implements ContextMenuActionsProvider {
|
||||
@Override
|
||||
public List<Action> getActions() {
|
||||
ArrayList<Action> actions = new ArrayList<>();
|
||||
Collection<? extends AbstractFile> selectedFiles = Utilities.actionsGlobalContext().lookupAll(AbstractFile.class);
|
||||
if (!selectedFiles.isEmpty()) {
|
||||
actions.add(AddContentToHashDbAction.getInstance());
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
}
|
@ -0,0 +1,217 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.ButtonGroup" name="buttonGroup1">
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<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"/>
|
||||
</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="nsrlRadioButton" 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"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<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="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"/>
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="nsrlRadioButton" 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>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<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>
|
||||
<Component class="javax.swing.JButton" name="cancelButton">
|
||||
<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.cancelButton.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="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="nsrlRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="buttonGroup1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbCreateDatabaseDialog.nsrlRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="nsrlRadioButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="knownBadRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="buttonGroup1"/>
|
||||
</Property>
|
||||
<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.knownBadRadioButton.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="knownBadRadioButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<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.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="databaseNameTextField">
|
||||
<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}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||
<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.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="useForIngestCheckbox">
|
||||
<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}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="useForIngestCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="sendInboxMessagesCheckbox">
|
||||
<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}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 Basis Technology Corp.
|
||||
* Copyright 2013 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -23,57 +23,64 @@ import java.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
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 org.sleuthkit.autopsy.hashdatabase.HashDb.DBType;
|
||||
import org.sleuthkit.datamodel.SleuthkitJNI;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDb.KnownFilesType;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author dfickling
|
||||
*/
|
||||
final class HashDbAddDatabaseDialog extends javax.swing.JDialog {
|
||||
|
||||
private JFileChooser fc = new JFileChooser();
|
||||
private String databaseName;
|
||||
private static final Logger logger = Logger.getLogger(HashDbAddDatabaseDialog.class.getName());
|
||||
/**
|
||||
* Creates new form HashDbAddDatabaseDialog
|
||||
*/
|
||||
HashDbAddDatabaseDialog() {
|
||||
super(new javax.swing.JFrame(), "Add Hash Database", true);
|
||||
setResizable(false);
|
||||
final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
||||
private JFileChooser fileChooser;
|
||||
private HashDb newHashDb = null;
|
||||
|
||||
HashDbCreateDatabaseDialog() {
|
||||
super(new javax.swing.JFrame(), "Create Hash Database", true);
|
||||
setResizable(false);
|
||||
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) {
|
||||
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) {
|
||||
cancelSelection();
|
||||
}
|
||||
return;
|
||||
}
|
||||
super.approveSelection();
|
||||
}
|
||||
};
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
}
|
||||
|
||||
void customizeComponents() {
|
||||
fc.setDragEnabled(false);
|
||||
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
String[] EXTENSION = new String[] { "txt", "idx", "hash", "Hash", "hsh"};
|
||||
FileNameExtensionFilter filter = new FileNameExtensionFilter(
|
||||
"Hash Database File", EXTENSION);
|
||||
fc.setFileFilter(filter);
|
||||
fc.setMultiSelectionEnabled(false);
|
||||
fileChooser.setDragEnabled(false);
|
||||
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
String[] EXTENSION = new String[] { "txt", "kdb", "idx", "hash", "Hash", "hsh"};
|
||||
FileNameExtensionFilter filter = new FileNameExtensionFilter("Hash Database File", EXTENSION);
|
||||
fileChooser.setFileFilter(filter);
|
||||
fileChooser.setMultiSelectionEnabled(false);
|
||||
}
|
||||
|
||||
String display() {
|
||||
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
|
||||
// set the popUp window / JFrame
|
||||
int w = this.getSize().width;
|
||||
int h = this.getSize().height;
|
||||
|
||||
// set the location of the popUp Window on the center of the screen
|
||||
setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
|
||||
HashDb doDialog() {
|
||||
newHashDb = null;
|
||||
|
||||
this.setVisible(true);
|
||||
return databaseName;
|
||||
// Center and display the dialog.
|
||||
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
|
||||
this.setVisible(true);
|
||||
|
||||
return newHashDb;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,23 +107,23 @@ final class HashDbAddDatabaseDialog extends javax.swing.JDialog {
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(HashDbAddDatabaseDialog.class, "HashDbAddDatabaseDialog.okButton.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);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(HashDbAddDatabaseDialog.class, "HashDbAddDatabaseDialog.cancelButton.text")); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.cancelButton.text")); // NOI18N
|
||||
cancelButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cancelButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
databasePathTextField.setText(org.openide.util.NbBundle.getMessage(HashDbAddDatabaseDialog.class, "HashDbAddDatabaseDialog.databasePathTextField.text")); // NOI18N
|
||||
databasePathTextField.setText(org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.databasePathTextField.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(HashDbAddDatabaseDialog.class, "HashDbAddDatabaseDialog.browseButton.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);
|
||||
@ -124,7 +131,8 @@ final class HashDbAddDatabaseDialog extends javax.swing.JDialog {
|
||||
});
|
||||
|
||||
buttonGroup1.add(nsrlRadioButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(nsrlRadioButton, org.openide.util.NbBundle.getMessage(HashDbAddDatabaseDialog.class, "HashDbAddDatabaseDialog.nsrlRadioButton.text")); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(nsrlRadioButton, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.nsrlRadioButton.text")); // NOI18N
|
||||
nsrlRadioButton.setEnabled(false);
|
||||
nsrlRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
nsrlRadioButtonActionPerformed(evt);
|
||||
@ -133,21 +141,21 @@ final class HashDbAddDatabaseDialog extends javax.swing.JDialog {
|
||||
|
||||
buttonGroup1.add(knownBadRadioButton);
|
||||
knownBadRadioButton.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(knownBadRadioButton, org.openide.util.NbBundle.getMessage(HashDbAddDatabaseDialog.class, "HashDbAddDatabaseDialog.knownBadRadioButton.text")); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(knownBadRadioButton, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.knownBadRadioButton.text")); // NOI18N
|
||||
knownBadRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
knownBadRadioButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(HashDbAddDatabaseDialog.class, "HashDbAddDatabaseDialog.jLabel1.text")); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.jLabel1.text")); // NOI18N
|
||||
|
||||
databaseNameTextField.setText(org.openide.util.NbBundle.getMessage(HashDbAddDatabaseDialog.class, "HashDbAddDatabaseDialog.databaseNameTextField.text")); // NOI18N
|
||||
databaseNameTextField.setText(org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.databaseNameTextField.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(HashDbAddDatabaseDialog.class, "HashDbAddDatabaseDialog.jLabel2.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(HashDbAddDatabaseDialog.class, "HashDbAddDatabaseDialog.useForIngestCheckbox.text")); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(useForIngestCheckbox, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.useForIngestCheckbox.text")); // NOI18N
|
||||
useForIngestCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
useForIngestCheckboxActionPerformed(evt);
|
||||
@ -155,7 +163,7 @@ final class HashDbAddDatabaseDialog extends javax.swing.JDialog {
|
||||
});
|
||||
|
||||
sendInboxMessagesCheckbox.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(sendInboxMessagesCheckbox, org.openide.util.NbBundle.getMessage(HashDbAddDatabaseDialog.class, "HashDbAddDatabaseDialog.sendInboxMessagesCheckbox.text")); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(sendInboxMessagesCheckbox, org.openide.util.NbBundle.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.sendInboxMessagesCheckbox.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
@ -227,36 +235,20 @@ final class HashDbAddDatabaseDialog extends javax.swing.JDialog {
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
|
||||
String oldText = databasePathTextField.getText();
|
||||
// set the current directory of the FileChooser if the databasePath Field is valid
|
||||
File currentDir = new File(oldText);
|
||||
if (currentDir.exists()) {
|
||||
fc.setCurrentDirectory(currentDir);
|
||||
}
|
||||
int retval = fc.showOpenDialog(this);
|
||||
if (retval == JFileChooser.APPROVE_OPTION) {
|
||||
File f = fc.getSelectedFile();
|
||||
try {
|
||||
String filePath = f.getCanonicalPath();
|
||||
if (HashDb.isIndexPath(filePath)) {
|
||||
filePath = HashDb.toDatabasePath(filePath);
|
||||
}
|
||||
String derivedName = SleuthkitJNI.getDatabaseName(filePath);
|
||||
databasePathTextField.setText(filePath);
|
||||
databaseNameTextField.setText(derivedName);
|
||||
if (derivedName.toLowerCase().contains("nsrl")) {
|
||||
try {
|
||||
fileChooser.setSelectedFile(new File("hash.kdb"));
|
||||
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")) {
|
||||
nsrlRadioButton.setSelected(true);
|
||||
nsrlRadioButtonActionPerformed(null);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Couldn't get selected file path.", ex);
|
||||
} catch (TskException ex) {
|
||||
logger.log(Level.WARNING, "Invalid database: ", ex);
|
||||
int tryAgain = JOptionPane.showConfirmDialog(this, "Database file you chose cannot be opened.\n" + "If it was just an index, please try to recreate it from the database.\n" + "Would you like to choose another database?", "Invalid File", JOptionPane.YES_NO_OPTION);
|
||||
if (tryAgain == JOptionPane.YES_OPTION) {
|
||||
browseButtonActionPerformed(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
Logger.getLogger(HashDbCreateDatabaseDialog.class.getName()).log(Level.WARNING, "Couldn't get selected file path.", ex);
|
||||
}
|
||||
}//GEN-LAST:event_browseButtonActionPerformed
|
||||
|
||||
@ -283,41 +275,28 @@ final class HashDbAddDatabaseDialog extends javax.swing.JDialog {
|
||||
JOptionPane.showMessageDialog(this, "Database name cannot be empty");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
File db = new File(databasePathTextField.getText());
|
||||
File idx = new File(databasePathTextField.getText() + "-md5.idx");
|
||||
if (!db.exists() && !idx.exists()) {
|
||||
JOptionPane.showMessageDialog(this, "Selected file does not exist");
|
||||
return;
|
||||
}
|
||||
String path = db.getCanonicalPath();
|
||||
SleuthkitJNI.getDatabaseName(path);
|
||||
} catch (Exception ex) {
|
||||
JOptionPane.showMessageDialog(this, "Database file you chose cannot be opened.\n" + "If it was just an index, please try to recreate it from the database");
|
||||
return;
|
||||
}
|
||||
DBType type;
|
||||
|
||||
KnownFilesType type;
|
||||
if(nsrlRadioButton.isSelected()) {
|
||||
type = DBType.NSRL;
|
||||
type = KnownFilesType.NSRL;
|
||||
} else {
|
||||
type = DBType.KNOWN_BAD;
|
||||
type = KnownFilesType.KNOWN_BAD;
|
||||
}
|
||||
HashDb db = new HashDb(databaseNameTextField.getText(),
|
||||
Arrays.asList(new String[] {databasePathTextField.getText()}),
|
||||
useForIngestCheckbox.isSelected(),
|
||||
sendInboxMessagesCheckbox.isSelected(),
|
||||
type);
|
||||
if(type == DBType.KNOWN_BAD) {
|
||||
HashDbXML.getCurrent().addKnownBadSet(db);
|
||||
} else if(type == DBType.NSRL) {
|
||||
HashDbXML.getCurrent().setNSRLSet(db);
|
||||
}
|
||||
databaseName = databaseNameTextField.getText();
|
||||
|
||||
try
|
||||
{
|
||||
newHashDb = HashDb.createHashDatabase(databaseNameTextField.getText(), databasePathTextField.getText(), useForIngestCheckbox.isSelected(), sendInboxMessagesCheckbox.isSelected(), type);
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbCreateDatabaseDialog.class.getName()).log(Level.SEVERE, "Hash database creation error", ex);
|
||||
JOptionPane.showMessageDialog(this, "Failed to create hash database.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.dispose();
|
||||
}//GEN-LAST:event_okButtonActionPerformed
|
||||
|
||||
private void useForIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useForIngestCheckboxActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_useForIngestCheckboxActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
@ -10,6 +10,7 @@
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
@ -110,7 +111,7 @@
|
||||
<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="HashDbAddDatabaseDialog.okButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.okButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
@ -120,7 +121,7 @@
|
||||
<Component class="javax.swing.JButton" name="cancelButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbAddDatabaseDialog.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
@ -130,14 +131,14 @@
|
||||
<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="HashDbAddDatabaseDialog.databasePathTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<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">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbAddDatabaseDialog.browseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.browseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
@ -150,7 +151,7 @@
|
||||
<ComponentRef name="buttonGroup1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbAddDatabaseDialog.nsrlRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.nsrlRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
@ -164,7 +165,7 @@
|
||||
</Property>
|
||||
<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="HashDbAddDatabaseDialog.knownBadRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.knownBadRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
@ -174,21 +175,21 @@
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbAddDatabaseDialog.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="databaseNameTextField">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbAddDatabaseDialog.databaseNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.databaseNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbAddDatabaseDialog.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
@ -196,7 +197,7 @@
|
||||
<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="HashDbAddDatabaseDialog.useForIngestCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.useForIngestCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
@ -207,7 +208,7 @@
|
||||
<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="HashDbAddDatabaseDialog.sendInboxMessagesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbImportDatabaseDialog.sendInboxMessagesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
@ -0,0 +1,313 @@
|
||||
/*
|
||||
* 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.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
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 org.sleuthkit.autopsy.hashdatabase.HashDb.KnownFilesType;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
/**
|
||||
* Instances of this class allow a user to select a hash database for import.
|
||||
*/
|
||||
final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
|
||||
private JFileChooser fileChooser = new JFileChooser();
|
||||
private HashDb selectedHashDb;
|
||||
|
||||
HashDbImportDatabaseDialog() {
|
||||
super(new javax.swing.JFrame(), "Import Hash Database", true);
|
||||
setResizable(false);
|
||||
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.setMultiSelectionEnabled(false);
|
||||
}
|
||||
|
||||
HashDb doDialog() {
|
||||
selectedHashDb = null;
|
||||
|
||||
// Center and display the dialog.
|
||||
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
|
||||
this.setVisible(true);
|
||||
|
||||
return selectedHashDb;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
buttonGroup1 = new javax.swing.ButtonGroup();
|
||||
okButton = new javax.swing.JButton();
|
||||
cancelButton = new javax.swing.JButton();
|
||||
databasePathTextField = new javax.swing.JTextField();
|
||||
browseButton = new javax.swing.JButton();
|
||||
nsrlRadioButton = new javax.swing.JRadioButton();
|
||||
knownBadRadioButton = new javax.swing.JRadioButton();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
databaseNameTextField = new javax.swing.JTextField();
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
useForIngestCheckbox = new javax.swing.JCheckBox();
|
||||
sendInboxMessagesCheckbox = new javax.swing.JCheckBox();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.okButton.text")); // NOI18N
|
||||
okButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
okButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.cancelButton.text")); // NOI18N
|
||||
cancelButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cancelButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
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() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
browseButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
buttonGroup1.add(nsrlRadioButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(nsrlRadioButton, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.nsrlRadioButton.text")); // NOI18N
|
||||
nsrlRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
nsrlRadioButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
buttonGroup1.add(knownBadRadioButton);
|
||||
knownBadRadioButton.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(knownBadRadioButton, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.knownBadRadioButton.text")); // NOI18N
|
||||
knownBadRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
knownBadRadioButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
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
|
||||
|
||||
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() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
useForIngestCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
sendInboxMessagesCheckbox.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(sendInboxMessagesCheckbox, org.openide.util.NbBundle.getMessage(HashDbImportDatabaseDialog.class, "HashDbImportDatabaseDialog.sendInboxMessagesCheckbox.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.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))
|
||||
.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(nsrlRadioButton))
|
||||
.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))))
|
||||
);
|
||||
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(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(jLabel2)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(nsrlRadioButton)
|
||||
.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())
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
|
||||
if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
|
||||
File databaseFile = fileChooser.getSelectedFile();
|
||||
try {
|
||||
databasePathTextField.setText(databaseFile.getCanonicalPath());
|
||||
databaseNameTextField.setText(FilenameUtils.removeExtension(databaseFile.getName()));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
Logger.getLogger(HashDbImportDatabaseDialog.class.getName()).log(Level.SEVERE, "Failed to get path of selected database", ex);
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_browseButtonActionPerformed
|
||||
|
||||
private void nsrlRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nsrlRadioButtonActionPerformed
|
||||
sendInboxMessagesCheckbox.setSelected(false);
|
||||
sendInboxMessagesCheckbox.setEnabled(false);
|
||||
}//GEN-LAST:event_nsrlRadioButtonActionPerformed
|
||||
|
||||
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 okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
|
||||
if(databasePathTextField.getText().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this, "Database path cannot be empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(databaseNameTextField.getText().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this, "Database display name cannot be empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
File file = new File(databasePathTextField.getText());
|
||||
if (!file.exists()) {
|
||||
JOptionPane.showMessageDialog(this, "Selected 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.");
|
||||
return;
|
||||
}
|
||||
|
||||
KnownFilesType type;
|
||||
if (nsrlRadioButton.isSelected()) {
|
||||
type = KnownFilesType.NSRL;
|
||||
}
|
||||
else {
|
||||
type = KnownFilesType.KNOWN_BAD;
|
||||
}
|
||||
|
||||
try {
|
||||
selectedHashDb = HashDb.openHashDatabase(databaseNameTextField.getText(), filePath, useForIngestCheckbox.isSelected(), sendInboxMessagesCheckbox.isSelected(), type);
|
||||
|
||||
|
||||
// if (!selectedHashDb.hasTextLookupIndexOnly())
|
||||
|
||||
}
|
||||
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.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.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.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JRadioButton knownBadRadioButton;
|
||||
private javax.swing.JRadioButton nsrlRadioButton;
|
||||
private javax.swing.JButton okButton;
|
||||
private javax.swing.JCheckBox sendInboxMessagesCheckbox;
|
||||
private javax.swing.JCheckBox useForIngestCheckbox;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2013 Basis Technology Corp.
|
||||
* Copyright 2011 - 2013 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -21,8 +21,6 @@ package org.sleuthkit.autopsy.hashdatabase;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -39,33 +37,28 @@ import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||
import org.sleuthkit.datamodel.Hash;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
|
||||
public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
|
||||
private static HashDbIngestModule instance = null;
|
||||
public final static String MODULE_NAME = "Hash Lookup";
|
||||
public final static String MODULE_DESCRIPTION = "Identifies known and notables files using supplied hash databases, such as a standard NSRL database.";
|
||||
final public static String MODULE_VERSION = "1.0";
|
||||
private static final Logger logger = Logger.getLogger(HashDbIngestModule.class.getName());
|
||||
private HashDbConfigPanel panel;
|
||||
private IngestServices services;
|
||||
private SleuthkitCase skCase;
|
||||
private static int messageId = 0;
|
||||
private int knownBadCount;
|
||||
// Whether or not to do hash lookups (only set to true if there are dbs set)
|
||||
private boolean nsrlIsSet;
|
||||
private boolean knownBadIsSet;
|
||||
private int knownBadCount = 0;
|
||||
private boolean calcHashesIsSet;
|
||||
private HashDb nsrlHashSet;
|
||||
private ArrayList<HashDb> knownBadHashSets = new ArrayList<>();
|
||||
static long calctime = 0;
|
||||
static long lookuptime = 0;
|
||||
private Map<Integer, HashDb> knownBadSets = new HashMap<>();
|
||||
private HashDbManagementPanel panel;
|
||||
private final Hash hasher = new Hash();
|
||||
|
||||
private HashDbIngestModule() {
|
||||
knownBadCount = 0;
|
||||
}
|
||||
|
||||
public static synchronized HashDbIngestModule getDefault() {
|
||||
@ -75,97 +68,6 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(IngestModuleInit initContext) {
|
||||
services = IngestServices.getDefault();
|
||||
this.skCase = Case.getCurrentCase().getSleuthkitCase();
|
||||
try {
|
||||
HashDbXML hdbxml = HashDbXML.getCurrent();
|
||||
knownBadSets.clear();
|
||||
skCase.clearLookupDatabases();
|
||||
nsrlIsSet = false;
|
||||
knownBadIsSet = false;
|
||||
calcHashesIsSet = hdbxml.getCalculate();
|
||||
|
||||
HashDb nsrl = hdbxml.getNSRLSet();
|
||||
if (nsrl != null && nsrl.getUseForIngest() && IndexStatus.isIngestible(nsrl.status())) {
|
||||
nsrlIsSet = true;
|
||||
// @@@ Unchecked return value
|
||||
skCase.setNSRLDatabase(nsrl.getDatabasePaths().get(0));
|
||||
}
|
||||
|
||||
for (HashDb db : hdbxml.getKnownBadSets()) {
|
||||
IndexStatus status = db.status();
|
||||
if (db.getUseForIngest() && IndexStatus.isIngestible(status)) {
|
||||
knownBadIsSet = true;
|
||||
int ret = skCase.addKnownBadDatabase(db.getDatabasePaths().get(0)); // TODO: support multiple paths
|
||||
knownBadSets.put(ret, db);
|
||||
}
|
||||
}
|
||||
|
||||
if (!nsrlIsSet) {
|
||||
this.services.postMessage(IngestMessage.createWarningMessage(++messageId, this, "No NSRL database set", "Known file search will not be executed."));
|
||||
}
|
||||
if (!knownBadIsSet) {
|
||||
this.services.postMessage(IngestMessage.createWarningMessage(++messageId, this, "No known bad database set", "Known bad file search will not be executed."));
|
||||
}
|
||||
|
||||
} catch (TskException ex) {
|
||||
logger.log(Level.SEVERE, "Setting NSRL and Known database failed", ex);
|
||||
this.services.postMessage(IngestMessage.createErrorMessage(++messageId, this, "Error Configuring Hash Databases", "Setting NSRL and Known database failed."));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete() {
|
||||
if ((knownBadIsSet) || (nsrlIsSet)) {
|
||||
StringBuilder detailsSb = new StringBuilder();
|
||||
//details
|
||||
detailsSb.append("<table border='0' cellpadding='4' width='280'>");
|
||||
|
||||
detailsSb.append("<tr><td>Known bads found:</td>");
|
||||
detailsSb.append("<td>").append(knownBadCount).append("</td></tr>");
|
||||
|
||||
detailsSb.append("<tr><td>Total Calculation Time</td><td>").append(calctime).append("</td></tr>\n");
|
||||
detailsSb.append("<tr><td>Total Lookup Time</td><td>").append(lookuptime).append("</td></tr>\n");
|
||||
detailsSb.append("</table>");
|
||||
|
||||
detailsSb.append("<p>Databases Used:</p>\n<ul>");
|
||||
for (HashDb db : knownBadSets.values()) {
|
||||
detailsSb.append("<li>").append(db.getName()).append("</li>\n");
|
||||
}
|
||||
|
||||
detailsSb.append("</ul>");
|
||||
services.postMessage(IngestMessage.createMessage(++messageId, IngestMessage.MessageType.INFO, this, "Hash Lookup Results", detailsSb.toString()));
|
||||
clearHashDatabaseHandles();
|
||||
}
|
||||
}
|
||||
|
||||
private void clearHashDatabaseHandles() {
|
||||
try {
|
||||
skCase.clearLookupDatabases();
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Error clearing hash database handles. ", ex);
|
||||
}
|
||||
this.nsrlIsSet = false;
|
||||
this.knownBadIsSet = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* notification from manager to stop processing due to some interruption
|
||||
* (user, error, exception)
|
||||
*/
|
||||
@Override
|
||||
public void stop() {
|
||||
clearHashDatabaseHandles();
|
||||
}
|
||||
|
||||
/**
|
||||
* get specific name of the module should be unique across modules, a
|
||||
* user-friendly name of the module shown in GUI
|
||||
*
|
||||
* @return The name of this Ingest Module
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return MODULE_NAME;
|
||||
@ -181,6 +83,76 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
return MODULE_VERSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSimpleConfiguration() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public javax.swing.JPanel getSimpleConfiguration(String context) {
|
||||
return new HashDbSimpleConfigPanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveSimpleConfiguration() {
|
||||
HashDbManager.getInstance().save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAdvancedConfiguration() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public javax.swing.JPanel getAdvancedConfiguration(String context) {
|
||||
if (panel == null) {
|
||||
panel = new HashDbConfigPanel();
|
||||
}
|
||||
|
||||
panel.load();
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAdvancedConfiguration() {
|
||||
if (panel != null) {
|
||||
panel.store();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(IngestModuleInit initContext) {
|
||||
services = IngestServices.getDefault();
|
||||
skCase = Case.getCurrentCase().getSleuthkitCase();
|
||||
HashDbManager hashDbManager = HashDbManager.getInstance();
|
||||
|
||||
nsrlHashSet = null;
|
||||
knownBadHashSets.clear();
|
||||
calcHashesIsSet = hashDbManager.shouldAlwaysCalculateHashes();
|
||||
|
||||
HashDb nsrl = hashDbManager.getNSRLHashSet();
|
||||
if (nsrl != null && nsrl.getUseForIngest() && nsrl.hasLookupIndex()) {
|
||||
nsrlHashSet = nsrl;
|
||||
}
|
||||
|
||||
for (HashDb db : hashDbManager.getKnownBadHashSets()) {
|
||||
if (db.getUseForIngest() && db.hasLookupIndex()) {
|
||||
knownBadHashSets.add(db);
|
||||
}
|
||||
}
|
||||
|
||||
if (nsrlHashSet == null) {
|
||||
services.postMessage(IngestMessage.createWarningMessage(++messageId, this, "No NSRL database set", "Known file search will not be executed."));
|
||||
}
|
||||
if (knownBadHashSets.isEmpty()) {
|
||||
services.postMessage(IngestMessage.createWarningMessage(++messageId, this, "No known bad database set", "Known bad file search will not be executed."));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBackgroundJobsRunning() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessResult process(PipelineContext<IngestModuleAbstractFile>pipelineContext, AbstractFile file) {
|
||||
@ -191,51 +163,87 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
|
||||
return processFile(file);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasBackgroundJobsRunning() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSimpleConfiguration() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAdvancedConfiguration() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public javax.swing.JPanel getSimpleConfiguration(String context) {
|
||||
HashDbXML.getCurrent().reload();
|
||||
return new HashDbSimplePanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public javax.swing.JPanel getAdvancedConfiguration(String context) {
|
||||
//return HashDbManagementPanel.getDefault();
|
||||
getPanel().load();
|
||||
return getPanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAdvancedConfiguration() {
|
||||
getPanel().store();
|
||||
}
|
||||
|
||||
private HashDbManagementPanel getPanel() {
|
||||
if (panel == null) {
|
||||
panel = new HashDbManagementPanel();
|
||||
|
||||
private ProcessResult processFile(AbstractFile file) {
|
||||
// bail out if we have no hashes set
|
||||
if ((nsrlHashSet == null) && (knownBadHashSets.isEmpty()) && (calcHashesIsSet == false)) {
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveSimpleConfiguration() {
|
||||
HashDbXML.getCurrent().save();
|
||||
// calc hash value
|
||||
String name = file.getName();
|
||||
String md5Hash = file.getMd5Hash();
|
||||
if (md5Hash == null || md5Hash.isEmpty()) {
|
||||
try {
|
||||
long calcstart = System.currentTimeMillis();
|
||||
md5Hash = hasher.calculateMd5(file);
|
||||
calctime += (System.currentTimeMillis() - calcstart);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Error calculating hash of file " + name, ex);
|
||||
services.postMessage(IngestMessage.createErrorMessage(++messageId, HashDbIngestModule.this, "Read Error: " + name,
|
||||
"Error encountered while calculating the hash value for " + name + "."));
|
||||
return ProcessResult.ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// look up in known bad first
|
||||
TskData.FileKnown status = TskData.FileKnown.UKNOWN;
|
||||
boolean foundBad = false;
|
||||
ProcessResult ret = ProcessResult.OK;
|
||||
for (HashDb db : knownBadHashSets) {
|
||||
try {
|
||||
long lookupstart = System.currentTimeMillis();
|
||||
status = db.lookUp(file);
|
||||
lookuptime += (System.currentTimeMillis() - lookupstart);
|
||||
} catch (TskException ex) {
|
||||
logger.log(Level.WARNING, "Couldn't lookup known bad hash for file " + name + " - see sleuthkit log for details", ex);
|
||||
services.postMessage(IngestMessage.createErrorMessage(++messageId, HashDbIngestModule.this, "Hash Lookup Error: " + name,
|
||||
"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.getDisplayName();
|
||||
processBadFile(file, md5Hash, hashSetName, db.getShowInboxMessages());
|
||||
}
|
||||
}
|
||||
|
||||
// only do NSRL if we didn't find a known bad
|
||||
if (!foundBad && nsrlHashSet != null) {
|
||||
try {
|
||||
long lookupstart = System.currentTimeMillis();
|
||||
status = nsrlHashSet.lookUp(file);
|
||||
lookuptime += (System.currentTimeMillis() - lookupstart);
|
||||
} catch (TskException ex) {
|
||||
logger.log(Level.WARNING, "Couldn't lookup NSRL hash for file " + name + " - see sleuthkit log for details", ex);
|
||||
services.postMessage(IngestMessage.createErrorMessage(++messageId, HashDbIngestModule.this, "Hash Lookup Error: " + name,
|
||||
"Error encountered while looking up NSRL hash value for " + name + "."));
|
||||
ret = ProcessResult.ERROR;
|
||||
}
|
||||
|
||||
if (status.equals(TskData.FileKnown.KNOWN)) {
|
||||
try {
|
||||
skCase.setKnown(file, TskData.FileKnown.KNOWN);
|
||||
} 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 (NSRL) state for " + name + "."));
|
||||
ret = ProcessResult.ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void processBadFile(AbstractFile abstractFile, String md5Hash, String hashSetName, boolean showInboxMessage) {
|
||||
@ -281,100 +289,32 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete() {
|
||||
if ((!knownBadHashSets.isEmpty()) || (nsrlHashSet != null)) {
|
||||
StringBuilder detailsSb = new StringBuilder();
|
||||
//details
|
||||
detailsSb.append("<table border='0' cellpadding='4' width='280'>");
|
||||
|
||||
private ProcessResult processFile(AbstractFile file) {
|
||||
// bail out if we have no hashes set
|
||||
if ((nsrlIsSet == false) && (knownBadIsSet == false) && (calcHashesIsSet == false)) {
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
detailsSb.append("<tr><td>Known bads found:</td>");
|
||||
detailsSb.append("<td>").append(knownBadCount).append("</td></tr>");
|
||||
|
||||
// calc hash value
|
||||
String name = file.getName();
|
||||
String md5Hash = file.getMd5Hash();
|
||||
if (md5Hash == null || md5Hash.isEmpty()) {
|
||||
try {
|
||||
long calcstart = System.currentTimeMillis();
|
||||
md5Hash = hasher.calculateMd5(file);
|
||||
calctime += (System.currentTimeMillis() - calcstart);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Error calculating hash of file " + name, ex);
|
||||
services.postMessage(IngestMessage.createErrorMessage(++messageId, HashDbIngestModule.this, "Read Error: " + name,
|
||||
"Error encountered while calculating the hash value for " + name + "."));
|
||||
return ProcessResult.ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
detailsSb.append("<tr><td>Total Calculation Time</td><td>").append(calctime).append("</td></tr>\n");
|
||||
detailsSb.append("<tr><td>Total Lookup Time</td><td>").append(lookuptime).append("</td></tr>\n");
|
||||
detailsSb.append("</table>");
|
||||
|
||||
// look up in known bad first
|
||||
TskData.FileKnown status = TskData.FileKnown.UKNOWN;
|
||||
boolean foundBad = false;
|
||||
ProcessResult ret = ProcessResult.OK;
|
||||
|
||||
if (knownBadIsSet) {
|
||||
for (Map.Entry<Integer, HashDb> entry : knownBadSets.entrySet()) {
|
||||
try {
|
||||
long lookupstart = System.currentTimeMillis();
|
||||
status = skCase.knownBadLookupMd5(md5Hash, entry.getKey());
|
||||
lookuptime += (System.currentTimeMillis() - lookupstart);
|
||||
} catch (TskException ex) {
|
||||
logger.log(Level.WARNING, "Couldn't lookup known bad hash for file " + name + " - see sleuthkit log for details", ex);
|
||||
services.postMessage(IngestMessage.createErrorMessage(++messageId, HashDbIngestModule.this, "Hash Lookup Error: " + name,
|
||||
"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 = entry.getValue().getName();
|
||||
processBadFile(file, md5Hash, hashSetName, entry.getValue().getShowInboxMessages());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// only do NSRL if we didn't find a known bad
|
||||
if (!foundBad && nsrlIsSet) {
|
||||
try {
|
||||
long lookupstart = System.currentTimeMillis();
|
||||
status = skCase.nsrlLookupMd5(md5Hash);
|
||||
lookuptime += (System.currentTimeMillis() - lookupstart);
|
||||
} catch (TskException ex) {
|
||||
logger.log(Level.WARNING, "Couldn't lookup NSRL hash for file " + name + " - see sleuthkit log for details", ex);
|
||||
services.postMessage(IngestMessage.createErrorMessage(++messageId, HashDbIngestModule.this, "Hash Lookup Error: " + name,
|
||||
"Error encountered while looking up NSRL hash value for " + name + "."));
|
||||
ret = ProcessResult.ERROR;
|
||||
detailsSb.append("<p>Databases Used:</p>\n<ul>");
|
||||
for (HashDb db : knownBadHashSets) {
|
||||
detailsSb.append("<li>").append(db.getDisplayName()).append("</li>\n");
|
||||
}
|
||||
|
||||
if (status.equals(TskData.FileKnown.KNOWN)) {
|
||||
try {
|
||||
skCase.setKnown(file, TskData.FileKnown.KNOWN);
|
||||
} 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 (NSRL) state for " + name + "."));
|
||||
ret = ProcessResult.ERROR;
|
||||
}
|
||||
}
|
||||
detailsSb.append("</ul>");
|
||||
services.postMessage(IngestMessage.createMessage(++messageId, IngestMessage.MessageType.INFO, this, "Hash Lookup Results", detailsSb.toString()));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ArrayList<String> getKnownBadSetNames() {
|
||||
ArrayList<String> knownBadSetNames = new ArrayList<>();
|
||||
HashDbXML hdbxml = HashDbXML.getCurrent();
|
||||
for (HashDb db : hdbxml.getKnownBadSets()) {
|
||||
knownBadSetNames.add(db.getName());
|
||||
}
|
||||
return knownBadSetNames;
|
||||
@Override
|
||||
public void stop() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 Basis Technology Corp.
|
||||
* Copyright 2011 - 2013 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.hashdatabase;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JFileChooser;
|
||||
@ -32,14 +33,19 @@ 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.DBType;
|
||||
import org.sleuthkit.autopsy.hashdatabase.HashDb.KnownFilesType;
|
||||
import org.sleuthkit.datamodel.SleuthkitJNI;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
public class HashDbXML {
|
||||
/**
|
||||
* This class is a singleton that manages the configuration of the hash databases
|
||||
* that serve as hash sets for the identification of known files, known good files,
|
||||
* and known bad files.
|
||||
*/
|
||||
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";
|
||||
@ -51,146 +57,231 @@ public class HashDbXML {
|
||||
private static final String CUR_HASHSETS_FILE_NAME = "hashsets.xml";
|
||||
private static final String XSDFILE = "HashsetsSchema.xsd";
|
||||
private static final String ENCODING = "UTF-8";
|
||||
private static final String CUR_HASHSET_FILE = PlatformUtil.getUserConfigDirectory() + File.separator + CUR_HASHSETS_FILE_NAME;
|
||||
private static final String SET_CALC = "hash_calculate";
|
||||
private static final String SET_VALUE = "value";
|
||||
private static final Logger logger = Logger.getLogger(HashDbXML.class.getName());
|
||||
private static HashDbXML currentInstance;
|
||||
|
||||
private List<HashDb> knownBadSets;
|
||||
private HashDb nsrlSet;
|
||||
private String xmlFile;
|
||||
private boolean calculate;
|
||||
|
||||
private HashDbXML(String xmlFile) {
|
||||
knownBadSets = new ArrayList<HashDb>();
|
||||
this.xmlFile = xmlFile;
|
||||
}
|
||||
|
||||
private static final Logger logger = Logger.getLogger(HashDbManager.class.getName());
|
||||
private static HashDbManager instance;
|
||||
private String xmlFile = PlatformUtil.getUserConfigDirectory() + File.separator + CUR_HASHSETS_FILE_NAME;
|
||||
private List<HashDb> knownBadHashSets = new ArrayList<>();
|
||||
private HashDb nsrlHashSet;
|
||||
private boolean alwaysCalculateHashes;
|
||||
|
||||
/**
|
||||
* get instance for managing the current keyword list of the application
|
||||
* Gets the singleton instance of this class.
|
||||
*/
|
||||
static synchronized HashDbXML getCurrent() {
|
||||
if (currentInstance == null) {
|
||||
currentInstance = new HashDbXML(CUR_HASHSET_FILE);
|
||||
currentInstance.reload();
|
||||
public static synchronized HashDbManager getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new HashDbManager();
|
||||
}
|
||||
return currentInstance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hash sets
|
||||
*/
|
||||
public List<HashDb> getAllSets() {
|
||||
List<HashDb> ret = new ArrayList<HashDb>();
|
||||
if(nsrlSet != null) {
|
||||
ret.add(nsrlSet);
|
||||
|
||||
private HashDbManager() {
|
||||
if (hashSetsConfigurationFileExists()) {
|
||||
readHashSetsConfigurationFromDisk();
|
||||
}
|
||||
ret.addAll(knownBadSets);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Known Bad sets
|
||||
|
||||
/**
|
||||
* Adds a hash set to the configuration as the designated National Software
|
||||
* Reference Library (NSRL) hash set. Assumes that the hash set previously
|
||||
* designated as NSRL set, if any, is not being indexed. Does not save the
|
||||
* configuration.
|
||||
*/
|
||||
public List<HashDb> getKnownBadSets() {
|
||||
return knownBadSets;
|
||||
public void setNSRLHashSet(HashDb set) {
|
||||
if (nsrlHashSet != null) {
|
||||
// RJCTODO: When the closeHashDatabase() API exists, close the existing database
|
||||
}
|
||||
nsrlHashSet = set;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the NSRL set
|
||||
* Gets the hash set from the configuration, if any, that is designated as
|
||||
* the National Software Reference Library (NSRL) hash set.
|
||||
* @return A HashDb object representing the hash set or null.
|
||||
*/
|
||||
public HashDb getNSRLSet() {
|
||||
return nsrlSet;
|
||||
public HashDb getNSRLHashSet() {
|
||||
return nsrlHashSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the hash set designated as the National Software Reference
|
||||
* Library (NSRL) hash set from the configuration. Does not save the
|
||||
* configuration.
|
||||
*/
|
||||
public void removeNSRLHashSet() {
|
||||
if (nsrlHashSet != null) {
|
||||
// RJCTODO: When the closeHashDatabase() API exists, close the existing database
|
||||
}
|
||||
nsrlHashSet = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a hash set to the configuration as a known bad files hash set. Does
|
||||
* not check for duplication of sets and does not save the configuration.
|
||||
*/
|
||||
public void addKnownBadHashSet(HashDb set) {
|
||||
knownBadHashSets.add(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configured known bad files hash sets.
|
||||
* @return A list, possibly empty, of HashDb objects.
|
||||
*/
|
||||
public List<HashDb> getKnownBadHashSets() {
|
||||
return Collections.unmodifiableList(knownBadHashSets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a known bad hash set
|
||||
* Adds a hash set to the configuration. If the hash set is designated as
|
||||
* the National Software Reference Library (NSRL) hash set, it is assumed
|
||||
* the the hash set previously designated as the NSRL set, if any, is not
|
||||
* being indexed. Does not check for duplication of sets and does not save
|
||||
* the configuration.
|
||||
*/
|
||||
public void addKnownBadSet(HashDb set) {
|
||||
knownBadSets.add(set);
|
||||
//save();
|
||||
public void addHashSet(HashDb hashSet) {
|
||||
if (hashSet.getKnownFilesType() == HashDb.KnownFilesType.NSRL) {
|
||||
setNSRLHashSet(hashSet);
|
||||
}
|
||||
else {
|
||||
addKnownBadHashSet(hashSet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a known bad hash set
|
||||
* Removes a hash set from the hash sets configuration.
|
||||
*/
|
||||
public void removeHashSet(HashDb hashSetToRemove) {
|
||||
if (nsrlHashSet != null && nsrlHashSet.equals(hashSetToRemove)) {
|
||||
removeNSRLHashSet();
|
||||
}
|
||||
else {
|
||||
knownBadHashSets.remove(hashSetToRemove);
|
||||
// RJCTODO: Close HashDb
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configured known files hash sets that accept updates.
|
||||
* @return A list, possibly empty, of HashDb objects.
|
||||
*/
|
||||
public List<HashDb> getUpdateableHashSets() {
|
||||
ArrayList<HashDb> updateableDbs = new ArrayList<>();
|
||||
for (HashDb db : knownBadHashSets) {
|
||||
try {
|
||||
if (db.isUpdateable()) {
|
||||
updateableDbs.add(db);
|
||||
}
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error checking updateable status of " + db.getDatabasePath(), ex);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(updateableDbs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all of the configured hash sets.
|
||||
* @return A list, possibly empty, of HashDb objects representing the hash
|
||||
* sets.
|
||||
*/
|
||||
public List<HashDb> getAllHashSets() {
|
||||
List<HashDb> hashDbs = new ArrayList<>();
|
||||
if (nsrlHashSet != null) {
|
||||
hashDbs.add(nsrlHashSet);
|
||||
}
|
||||
hashDbs.addAll(knownBadHashSets);
|
||||
return Collections.unmodifiableList(hashDbs);
|
||||
}
|
||||
|
||||
/** Gets the configured hash set, if any, with a given name.
|
||||
* @return A HashDb object or null.
|
||||
*/
|
||||
public HashDb getHashSetByName(String name) {
|
||||
if (nsrlHashSet != null && nsrlHashSet.getDisplayName().equals(name)) {
|
||||
return nsrlHashSet;
|
||||
}
|
||||
|
||||
for (HashDb hashSet : knownBadHashSets) {
|
||||
if (hashSet.getDisplayName().equals(name)) {
|
||||
return hashSet;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// public HashDb getHashSetAt(int index)
|
||||
|
||||
// RJCTODO: Get rid of this
|
||||
/**
|
||||
* Adds a hash set to the configuration as a known bad files hash set. The
|
||||
* set is added to the internal known bad sets collection at the index
|
||||
* specified by the caller. Does not save the configuration.
|
||||
*/
|
||||
public void addKnownBadSet(int index, HashDb set) {
|
||||
knownBadSets.add(index, set);
|
||||
//save();
|
||||
knownBadHashSets.add(index, set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the NSRL hash set (override old set)
|
||||
*/
|
||||
public void setNSRLSet(HashDb set) {
|
||||
this.nsrlSet = set;
|
||||
//save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a hash known bad set
|
||||
|
||||
// RJCTODO: Get rid of this
|
||||
/**
|
||||
* Removes the known bad files hash set from the internal known bad files
|
||||
* hash sets collection at the specified index. Does not save the configuration.
|
||||
*/
|
||||
public void removeKnownBadSetAt(int index) {
|
||||
knownBadSets.remove(index);
|
||||
//save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the NSRL database
|
||||
*/
|
||||
public void removeNSRLSet() {
|
||||
this.nsrlSet = null;
|
||||
//save();
|
||||
knownBadHashSets.remove(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* load the file or create new
|
||||
* Sets the value for the flag indicates whether hashes should be calculated
|
||||
* for content even if no hash databases are configured.
|
||||
*/
|
||||
public void reload() {
|
||||
boolean created = false;
|
||||
|
||||
//TODO clearing the list causes a bug: we lose track of the state
|
||||
//whether db is being indexed, we should somehow preserve the state when loading new HashDb objects
|
||||
|
||||
knownBadSets.clear();
|
||||
nsrlSet = null;
|
||||
|
||||
if (!this.setsFileExists()) {
|
||||
//create new if it doesn't exist
|
||||
save();
|
||||
created = true;
|
||||
}
|
||||
|
||||
//load, if fails to load create new; save regardless
|
||||
load();
|
||||
if (!created) {
|
||||
//create new if failed to load
|
||||
save();
|
||||
}
|
||||
public void setShouldAlwaysCalculateHashes(boolean alwaysCalculateHashes) {
|
||||
this.alwaysCalculateHashes = alwaysCalculateHashes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the local variable calculate to the given boolean.
|
||||
* @param set the state to make calculate
|
||||
* Accesses the flag that indicates whether hashes should be calculated
|
||||
* for content even if no hash databases are configured.
|
||||
*/
|
||||
public void setCalculate(boolean set) {
|
||||
this.calculate = set;
|
||||
//save();
|
||||
public boolean shouldAlwaysCalculateHashes() {
|
||||
return alwaysCalculateHashes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the local boolean calculate.
|
||||
* @return true if calculate is true, false otherwise
|
||||
*/
|
||||
public boolean getCalculate() {
|
||||
return this.calculate;
|
||||
}
|
||||
|
||||
/**
|
||||
* writes out current sets file replacing the last one
|
||||
* Saves the hash sets configuration. Note that the configuration is only
|
||||
* saved on demand to support cancellation of configuration panels.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
public boolean save() {
|
||||
return writeHashSetConfigurationToDisk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the last saved hash sets configuration. This supports
|
||||
* cancellation of configuration panels.
|
||||
*/
|
||||
public void loadLastSavedConfiguration() {
|
||||
try {
|
||||
SleuthkitJNI.closeHashDatabases();
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
// RJCTODO: Log
|
||||
}
|
||||
|
||||
nsrlHashSet = null;
|
||||
knownBadHashSets.clear();
|
||||
if (hashSetsConfigurationFileExists()) {
|
||||
readHashSetsConfigurationFromDisk();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hashSetsConfigurationFileExists() {
|
||||
File f = new File(xmlFile);
|
||||
return f.exists() && f.canRead() && f.canWrite();
|
||||
}
|
||||
|
||||
private boolean writeHashSetConfigurationToDisk() {
|
||||
boolean success = false;
|
||||
|
||||
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
|
||||
@ -202,14 +293,15 @@ public class HashDbXML {
|
||||
Element rootEl = doc.createElement(ROOT_EL);
|
||||
doc.appendChild(rootEl);
|
||||
|
||||
for (HashDb set : knownBadSets) {
|
||||
// TODO: Remove all the multiple database paths stuff, it was a mistake.
|
||||
for (HashDb set : knownBadHashSets) {
|
||||
String useForIngest = Boolean.toString(set.getUseForIngest());
|
||||
String showInboxMessages = Boolean.toString(set.getShowInboxMessages());
|
||||
List<String> paths = set.getDatabasePaths();
|
||||
String type = DBType.KNOWN_BAD.toString();
|
||||
List<String> paths = Collections.singletonList(set.getDatabasePath());
|
||||
String type = KnownFilesType.KNOWN_BAD.toString();
|
||||
|
||||
Element setEl = doc.createElement(SET_EL);
|
||||
setEl.setAttribute(SET_NAME_ATTR, set.getName());
|
||||
setEl.setAttribute(SET_NAME_ATTR, set.getDisplayName());
|
||||
setEl.setAttribute(SET_TYPE_ATTR, type);
|
||||
setEl.setAttribute(SET_USE_FOR_INGEST_ATTR, useForIngest);
|
||||
setEl.setAttribute(SET_SHOW_INBOX_MESSAGES, showInboxMessages);
|
||||
@ -224,14 +316,15 @@ public class HashDbXML {
|
||||
rootEl.appendChild(setEl);
|
||||
}
|
||||
|
||||
if(nsrlSet != null) {
|
||||
String useForIngest = Boolean.toString(nsrlSet.getUseForIngest());
|
||||
String showInboxMessages = Boolean.toString(nsrlSet.getShowInboxMessages());
|
||||
List<String> paths = nsrlSet.getDatabasePaths();
|
||||
String type = DBType.NSRL.toString();
|
||||
// TODO: Remove all the multiple database paths stuff.
|
||||
if(nsrlHashSet != null) {
|
||||
String useForIngest = Boolean.toString(nsrlHashSet.getUseForIngest());
|
||||
String showInboxMessages = Boolean.toString(nsrlHashSet.getShowInboxMessages());
|
||||
List<String> paths = Collections.singletonList(nsrlHashSet.getDatabasePath());
|
||||
String type = KnownFilesType.NSRL.toString();
|
||||
|
||||
Element setEl = doc.createElement(SET_EL);
|
||||
setEl.setAttribute(SET_NAME_ATTR, nsrlSet.getName());
|
||||
setEl.setAttribute(SET_NAME_ATTR, nsrlHashSet.getDisplayName());
|
||||
setEl.setAttribute(SET_TYPE_ATTR, type);
|
||||
setEl.setAttribute(SET_USE_FOR_INGEST_ATTR, useForIngest);
|
||||
setEl.setAttribute(SET_SHOW_INBOX_MESSAGES, showInboxMessages);
|
||||
@ -245,24 +338,22 @@ public class HashDbXML {
|
||||
}
|
||||
rootEl.appendChild(setEl);
|
||||
}
|
||||
|
||||
String calcValue = Boolean.toString(calculate);
|
||||
|
||||
String calcValue = Boolean.toString(alwaysCalculateHashes);
|
||||
Element setCalc = doc.createElement(SET_CALC);
|
||||
setCalc.setAttribute(SET_VALUE, calcValue);
|
||||
rootEl.appendChild(setCalc);
|
||||
|
||||
success = XMLUtil.saveDoc(HashDbXML.class, xmlFile, ENCODING, doc);
|
||||
} catch (ParserConfigurationException e) {
|
||||
success = XMLUtil.saveDoc(HashDbManager.class, xmlFile, ENCODING, doc);
|
||||
}
|
||||
catch (ParserConfigurationException e) {
|
||||
logger.log(Level.SEVERE, "Error saving hash sets: can't initialize parser.", e);
|
||||
}
|
||||
return success;
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* load and parse XML, then dispose
|
||||
*/
|
||||
public boolean load() {
|
||||
final Document doc = XMLUtil.loadDoc(HashDbXML.class, xmlFile, XSDFILE);
|
||||
|
||||
private boolean readHashSetsConfigurationFromDisk() {
|
||||
final Document doc = XMLUtil.loadDoc(HashDbManager.class, xmlFile, XSDFILE);
|
||||
if (doc == null) {
|
||||
return false;
|
||||
}
|
||||
@ -285,9 +376,10 @@ public class HashDbXML {
|
||||
final String showInboxMessages = setEl.getAttribute(SET_SHOW_INBOX_MESSAGES);
|
||||
Boolean useForIngestBool = Boolean.parseBoolean(useForIngest);
|
||||
Boolean showInboxMessagesBool = Boolean.parseBoolean(showInboxMessages);
|
||||
List<String> paths = new ArrayList<String>();
|
||||
List<String> paths = new ArrayList<>();
|
||||
|
||||
// Parse all paths
|
||||
// TODO: Remove all the multiple database paths stuff.
|
||||
// RJCTODO: Rework this to do a search a bit differently, or simply indicate the file is missing...
|
||||
NodeList pathsNList = setEl.getElementsByTagName(PATH_EL);
|
||||
final int numPaths = pathsNList.getLength();
|
||||
for (int j = 0; j < numPaths; ++j) {
|
||||
@ -330,16 +422,23 @@ public class HashDbXML {
|
||||
}
|
||||
|
||||
if(paths.isEmpty()) {
|
||||
logger.log(Level.WARNING, "No paths were set for hash_set at index {0}. Removing the database.", i);
|
||||
} else {
|
||||
// No paths for this entry, the user most likely declined to search for them
|
||||
DBType typeDBType = DBType.valueOf(type);
|
||||
HashDb set = new HashDb(name, paths, useForIngestBool, showInboxMessagesBool, typeDBType);
|
||||
|
||||
if(typeDBType == DBType.KNOWN_BAD) {
|
||||
knownBadSets.add(set);
|
||||
} else if(typeDBType == DBType.NSRL) {
|
||||
this.nsrlSet = set;
|
||||
logger.log(Level.WARNING, "No paths were set for hash_set at index {0}. Removing the database.", i);
|
||||
}
|
||||
else {
|
||||
KnownFilesType typeDBType = KnownFilesType.valueOf(type);
|
||||
try {
|
||||
HashDb db = HashDb.openHashDatabase(name, paths.get(0), useForIngestBool, showInboxMessagesBool, typeDBType);
|
||||
if (typeDBType == KnownFilesType.NSRL) {
|
||||
setNSRLHashSet(db);
|
||||
}
|
||||
else {
|
||||
addKnownBadHashSet(db);
|
||||
}
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
Logger.getLogger(HashDbManager.class.getName()).log(Level.SEVERE, "Error opening hash database", ex);
|
||||
JOptionPane.showMessageDialog(null, "Unable to open " + paths.get(0) + " hash database.", "Open Hash Database Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -352,7 +451,7 @@ public class HashDbXML {
|
||||
for(int i=0; i<numCalc; i++) {
|
||||
Element calcEl = (Element) calcList.item(i);
|
||||
final String value = calcEl.getAttribute(SET_VALUE);
|
||||
calculate = Boolean.parseBoolean(value);
|
||||
alwaysCalculateHashes = Boolean.parseBoolean(value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -373,53 +472,21 @@ public class HashDbXML {
|
||||
fc.setDragEnabled(false);
|
||||
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
String[] EXTENSION = new String[] { "txt", "idx", "hash", "Hash" };
|
||||
FileNameExtensionFilter filter = new FileNameExtensionFilter(
|
||||
"Hash Database File", EXTENSION);
|
||||
FileNameExtensionFilter filter = new FileNameExtensionFilter("Hash Database File", EXTENSION);
|
||||
fc.setFileFilter(filter);
|
||||
fc.setMultiSelectionEnabled(false);
|
||||
|
||||
int retval = fc.showOpenDialog(null);
|
||||
// If the user selects an appropriate file
|
||||
if (retval == JFileChooser.APPROVE_OPTION) {
|
||||
String filePath = null;
|
||||
if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
|
||||
File f = fc.getSelectedFile();
|
||||
try {
|
||||
String filePath = f.getCanonicalPath();
|
||||
if (HashDb.isIndexPath(filePath)) {
|
||||
filePath = HashDb.toDatabasePath(filePath);
|
||||
}
|
||||
String derivedName = SleuthkitJNI.getDatabaseName(filePath);
|
||||
// If the database has the same name as before, return it
|
||||
if(derivedName.equals(name)) {
|
||||
return filePath;
|
||||
} else {
|
||||
int tryAgain = JOptionPane.showConfirmDialog(null, "Database file cannot be added because it does not have the same name as the original.\n" +
|
||||
"Would you like to try a different database?", "Invalid File", JOptionPane.YES_NO_OPTION);
|
||||
if (tryAgain == JOptionPane.YES_OPTION) {
|
||||
return searchForFile(name);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Couldn't get selected file path.", ex);
|
||||
} catch (TskCoreException ex) {
|
||||
int tryAgain = JOptionPane.showConfirmDialog(null, "Database file you chose cannot be opened.\n" + "If it was just an index, please try to recreate it from the database.\n" +
|
||||
"Would you like to choose another database?", "Invalid File", JOptionPane.YES_NO_OPTION);
|
||||
if (tryAgain == JOptionPane.YES_OPTION) {
|
||||
return searchForFile(name);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
filePath = f.getCanonicalPath();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Couldn't get selected file path", ex);
|
||||
}
|
||||
}
|
||||
// Otherwise the user cancelled, so delete the missing entry
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean setsFileExists() {
|
||||
File f = new File(xmlFile);
|
||||
return f.exists() && f.canRead() && f.canWrite();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return filePath;
|
||||
}
|
||||
}
|
@ -85,28 +85,28 @@
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbSimplePanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbSimpleConfigPanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="nsrlDbLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbSimplePanel.nsrlDbLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbSimpleConfigPanel.nsrlDbLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="calcHashesButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbSimplePanel.calcHashesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbSimpleConfigPanel.calcHashesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="nsrlDbLabelVal">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbSimplePanel.nsrlDbLabelVal.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbSimpleConfigPanel.nsrlDbLabelVal.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 Basis Technology Corp.
|
||||
* Copyright 2011 - 2013 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -16,49 +16,37 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* HashDbSimplePanel.java
|
||||
*
|
||||
* Created on May 7, 2012, 10:38:26 AM
|
||||
*/
|
||||
package org.sleuthkit.autopsy.hashdatabase;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.List;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.TableColumn;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author dfickling
|
||||
* Instances of this class are used as a file ingest module configuration panel
|
||||
* by the known files hash set lookup file ingest module.
|
||||
*/
|
||||
public class HashDbSimplePanel extends javax.swing.JPanel {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(HashDbSimplePanel.class.getName());
|
||||
public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
|
||||
private HashTableModel knownBadTableModel;
|
||||
private HashDb nsrl;
|
||||
|
||||
/** Creates new form HashDbSimplePanel */
|
||||
public HashDbSimplePanel() {
|
||||
public HashDbSimpleConfigPanel() {
|
||||
knownBadTableModel = new HashTableModel();
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
}
|
||||
|
||||
private void reloadCalc() {
|
||||
final HashDbXML xmlHandle = HashDbXML.getCurrent();
|
||||
final HashDb nsrlDb = xmlHandle.getNSRLSet();
|
||||
final boolean nsrlUsed =
|
||||
nsrlDb != null
|
||||
&& nsrlDb.getUseForIngest()== true
|
||||
&& nsrlDb.indexExists();
|
||||
final List<HashDb> knowns = xmlHandle.getKnownBadSets();
|
||||
final HashDbManager xmlHandle = HashDbManager.getInstance();
|
||||
final HashDb nsrlDb = xmlHandle.getNSRLHashSet();
|
||||
final boolean nsrlUsed = nsrlDb != null && nsrlDb.getUseForIngest()== true && nsrlDb.hasLookupIndex();
|
||||
final List<HashDb> knowns = xmlHandle.getKnownBadHashSets();
|
||||
final boolean knownExists = !knowns.isEmpty();
|
||||
boolean knownUsed = false;
|
||||
if (knownExists) {
|
||||
@ -70,31 +58,29 @@ public class HashDbSimplePanel extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
if(! nsrlUsed
|
||||
&& ! knownUsed ) {
|
||||
if (!nsrlUsed && !knownUsed ) {
|
||||
calcHashesButton.setEnabled(true);
|
||||
calcHashesButton.setSelected(true);
|
||||
xmlHandle.setCalculate(true);
|
||||
xmlHandle.setShouldAlwaysCalculateHashes(true);
|
||||
} else {
|
||||
calcHashesButton.setEnabled(false);
|
||||
calcHashesButton.setSelected(false);
|
||||
xmlHandle.setCalculate(false);
|
||||
xmlHandle.setShouldAlwaysCalculateHashes(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void customizeComponents() {
|
||||
final HashDbXML xmlHandle = HashDbXML.getCurrent();
|
||||
final HashDbManager xmlHandle = HashDbManager.getInstance();
|
||||
calcHashesButton.addActionListener( new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if(calcHashesButton.isSelected()) {
|
||||
xmlHandle.setCalculate(true);
|
||||
xmlHandle.setShouldAlwaysCalculateHashes(true);
|
||||
} else {
|
||||
xmlHandle.setCalculate(false);
|
||||
xmlHandle.setShouldAlwaysCalculateHashes(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
notableHashTable.setModel(knownBadTableModel);
|
||||
@ -104,7 +90,7 @@ public class HashDbSimplePanel extends javax.swing.JPanel {
|
||||
//customize column witdhs
|
||||
final int width1 = jScrollPane1.getPreferredSize().width;
|
||||
notableHashTable.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
|
||||
TableColumn column1 = null;
|
||||
TableColumn column1;
|
||||
for (int i = 0; i < notableHashTable.getColumnCount(); i++) {
|
||||
column1 = notableHashTable.getColumnModel().getColumn(i);
|
||||
if (i == 0) {
|
||||
@ -117,6 +103,24 @@ public class HashDbSimplePanel extends javax.swing.JPanel {
|
||||
reloadSets();
|
||||
}
|
||||
|
||||
private void reloadSets() {
|
||||
nsrl = HashDbManager.getInstance().getNSRLHashSet();
|
||||
|
||||
if (nsrl == null || nsrl.getUseForIngest() == false) {
|
||||
nsrlDbLabelVal.setText("Disabled");
|
||||
}
|
||||
else if (nsrl.hasLookupIndex() == false) {
|
||||
nsrlDbLabelVal.setText("Disabled (No index)");
|
||||
}
|
||||
else {
|
||||
nsrlDbLabelVal.setText("Enabled");
|
||||
}
|
||||
|
||||
reloadCalc();
|
||||
|
||||
knownBadTableModel.resync();
|
||||
}
|
||||
|
||||
/** This method is called from within the constructor to
|
||||
* initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is
|
||||
@ -140,13 +144,13 @@ public class HashDbSimplePanel extends javax.swing.JPanel {
|
||||
notableHashTable.setShowVerticalLines(false);
|
||||
jScrollPane1.setViewportView(notableHashTable);
|
||||
|
||||
jLabel1.setText(org.openide.util.NbBundle.getMessage(HashDbSimplePanel.class, "HashDbSimplePanel.jLabel1.text")); // NOI18N
|
||||
jLabel1.setText(org.openide.util.NbBundle.getMessage(HashDbSimpleConfigPanel.class, "HashDbSimpleConfigPanel.jLabel1.text")); // NOI18N
|
||||
|
||||
nsrlDbLabel.setText(org.openide.util.NbBundle.getMessage(HashDbSimplePanel.class, "HashDbSimplePanel.nsrlDbLabel.text")); // NOI18N
|
||||
nsrlDbLabel.setText(org.openide.util.NbBundle.getMessage(HashDbSimpleConfigPanel.class, "HashDbSimpleConfigPanel.nsrlDbLabel.text")); // NOI18N
|
||||
|
||||
calcHashesButton.setText(org.openide.util.NbBundle.getMessage(HashDbSimplePanel.class, "HashDbSimplePanel.calcHashesButton.text")); // NOI18N
|
||||
calcHashesButton.setText(org.openide.util.NbBundle.getMessage(HashDbSimpleConfigPanel.class, "HashDbSimpleConfigPanel.calcHashesButton.text")); // NOI18N
|
||||
|
||||
nsrlDbLabelVal.setText(org.openide.util.NbBundle.getMessage(HashDbSimplePanel.class, "HashDbSimplePanel.nsrlDbLabelVal.text")); // NOI18N
|
||||
nsrlDbLabelVal.setText(org.openide.util.NbBundle.getMessage(HashDbSimpleConfigPanel.class, "HashDbSimpleConfigPanel.nsrlDbLabelVal.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
@ -193,29 +197,9 @@ public class HashDbSimplePanel extends javax.swing.JPanel {
|
||||
private javax.swing.JLabel nsrlDbLabelVal;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
private void reloadSets() {
|
||||
nsrl = HashDbXML.getCurrent().getNSRLSet();
|
||||
|
||||
if (nsrl == null || nsrl.getUseForIngest() == false) {
|
||||
nsrlDbLabelVal.setText("Disabled");
|
||||
}
|
||||
else if (nsrl.indexExists() == false) {
|
||||
nsrlDbLabelVal.setText("Disabled (No index)");
|
||||
}
|
||||
else {
|
||||
nsrlDbLabelVal.setText("Enabled");
|
||||
}
|
||||
|
||||
reloadCalc();
|
||||
|
||||
knownBadTableModel.resync();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private class HashTableModel extends AbstractTableModel {
|
||||
|
||||
private HashDbXML xmlHandle = HashDbXML.getCurrent();
|
||||
private HashDbManager xmlHandle = HashDbManager.getInstance();
|
||||
|
||||
private void resync() {
|
||||
fireTableDataChanged();
|
||||
@ -223,7 +207,7 @@ public class HashDbSimplePanel extends javax.swing.JPanel {
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
int size = xmlHandle.getKnownBadSets().size();
|
||||
int size = xmlHandle.getKnownBadHashSets().size();
|
||||
return size == 0 ? 1 : size;
|
||||
}
|
||||
|
||||
@ -234,18 +218,18 @@ public class HashDbSimplePanel extends javax.swing.JPanel {
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
if (xmlHandle.getKnownBadSets().isEmpty()) {
|
||||
if (xmlHandle.getKnownBadHashSets().isEmpty()) {
|
||||
if (columnIndex == 0) {
|
||||
return "";
|
||||
} else {
|
||||
return "Disabled";
|
||||
}
|
||||
} else {
|
||||
HashDb db = xmlHandle.getKnownBadSets().get(rowIndex);
|
||||
HashDb db = xmlHandle.getKnownBadHashSets().get(rowIndex);
|
||||
if (columnIndex == 0) {
|
||||
return db.getUseForIngest();
|
||||
} else {
|
||||
return db.getName();
|
||||
return db.getDisplayName();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -258,11 +242,18 @@ public class HashDbSimplePanel extends javax.swing.JPanel {
|
||||
@Override
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
if(columnIndex == 0){
|
||||
HashDb db = xmlHandle.getKnownBadSets().get(rowIndex);
|
||||
if(((Boolean) getValueAt(rowIndex, columnIndex)) || IndexStatus.isIngestible(db.status())) {
|
||||
HashDb db = xmlHandle.getKnownBadHashSets().get(rowIndex);
|
||||
IndexStatus status = IndexStatus.NO_INDEX;
|
||||
try {
|
||||
status = db.getStatus();
|
||||
}
|
||||
catch (TskCoreException ex) {
|
||||
// RJCTODO
|
||||
}
|
||||
if(((Boolean) getValueAt(rowIndex, columnIndex)) || IndexStatus.isIngestible(status)) {
|
||||
db.setUseForIngest((Boolean) aValue);
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(HashDbSimplePanel.this, "Databases must be indexed before they can be used for ingest");
|
||||
JOptionPane.showMessageDialog(HashDbSimpleConfigPanel.this, "Databases must be indexed before they can be used for ingest");
|
||||
}
|
||||
reloadSets();
|
||||
}
|
||||
@ -272,6 +263,5 @@ public class HashDbSimplePanel extends javax.swing.JPanel {
|
||||
public Class<?> getColumnClass(int c) {
|
||||
return getValueAt(0, c).getClass();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -26,30 +26,27 @@ package org.sleuthkit.autopsy.hashdatabase;
|
||||
enum IndexStatus {
|
||||
|
||||
/**
|
||||
* The index and database both exist, and the index is older.
|
||||
* The index exists but the database does not. This indicates a text index
|
||||
* without an accompanying text database.
|
||||
*/
|
||||
INDEX_OUTDATED("WARNING: Index is older than database"),
|
||||
INDEX_ONLY("Index only"),
|
||||
/**
|
||||
* The index and database both exist, and the index is not older.
|
||||
* The database exists but the index does not. This indicates a text database
|
||||
* with no index.
|
||||
*/
|
||||
INDEX_CURRENT("Database and index exist"),
|
||||
NO_INDEX("No index"),
|
||||
/**
|
||||
* The index exists but the database does not.
|
||||
* The index is currently being generated.
|
||||
*/
|
||||
NO_DB("Index exists (no database)"),
|
||||
INDEXING("Index is currently being generated"),
|
||||
/**
|
||||
* The database exists but the index does not.
|
||||
* The index is generated.
|
||||
*/
|
||||
NO_INDEX("ERROR: Index does not exist"),
|
||||
INDEXED("Indexed"),
|
||||
/**
|
||||
* Neither the index nor the database exists.
|
||||
* An error occurred while determining status.
|
||||
*/
|
||||
NONE("ERROR: No index or database"),
|
||||
/**
|
||||
* The index is currently being generated
|
||||
*/
|
||||
INDEXING("Index is currently being generated");
|
||||
|
||||
UNKNOWN("Error determining status");
|
||||
private String message;
|
||||
|
||||
/**
|
||||
@ -68,6 +65,6 @@ enum IndexStatus {
|
||||
}
|
||||
|
||||
public static boolean isIngestible(IndexStatus status) {
|
||||
return status == NO_DB || status == INDEX_CURRENT || status == INDEX_OUTDATED;
|
||||
return status == INDEX_ONLY || status == INDEXED;
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
|
@ -42,7 +42,7 @@ class ModalNoButtons extends javax.swing.JDialog implements PropertyChangeListen
|
||||
|
||||
List<HashDb> unindexed;
|
||||
HashDb toIndex;
|
||||
HashDbManagementPanel hdbmp;
|
||||
HashDbConfigPanel hdbmp;
|
||||
int length = 0;
|
||||
int currentcount = 1;
|
||||
String currentDb = "";
|
||||
@ -53,7 +53,7 @@ class ModalNoButtons extends javax.swing.JDialog implements PropertyChangeListen
|
||||
* @param parent Swing parent frame.
|
||||
* @param unindexed the list of unindexed databases to index.
|
||||
*/
|
||||
ModalNoButtons(HashDbManagementPanel hdbmp, java.awt.Frame parent, List<HashDb> unindexed) {
|
||||
ModalNoButtons(HashDbConfigPanel hdbmp, java.awt.Frame parent, List<HashDb> unindexed) {
|
||||
super(parent, "Indexing databases", true);
|
||||
this.unindexed = unindexed;
|
||||
this.toIndex = null;
|
||||
@ -68,7 +68,7 @@ class ModalNoButtons extends javax.swing.JDialog implements PropertyChangeListen
|
||||
* @param parent Swing parent frame.
|
||||
* @param unindexed The unindexed database to index.
|
||||
*/
|
||||
ModalNoButtons(HashDbManagementPanel hdbmp, java.awt.Frame parent, HashDb unindexed){
|
||||
ModalNoButtons(HashDbConfigPanel hdbmp, java.awt.Frame parent, HashDb unindexed){
|
||||
super(parent, "Indexing database", true);
|
||||
this.unindexed = null;
|
||||
this.toIndex = unindexed;
|
||||
@ -203,7 +203,7 @@ class ModalNoButtons extends javax.swing.JDialog implements PropertyChangeListen
|
||||
*/
|
||||
private void indexThis() {
|
||||
this.INDEXING_PROGBAR.setIndeterminate(true);
|
||||
currentDb = this.toIndex.getName();
|
||||
currentDb = this.toIndex.getDisplayName();
|
||||
this.CURRENTDB_LABEL.setText("(" + currentDb + ")");
|
||||
this.length = 1;
|
||||
this.CURRENTLYON_LABEL.setText("Currently indexing 1 database");
|
||||
@ -224,7 +224,7 @@ class ModalNoButtons extends javax.swing.JDialog implements PropertyChangeListen
|
||||
length = this.unindexed.size();
|
||||
this.INDEXING_PROGBAR.setIndeterminate(true);
|
||||
for (HashDb db : this.unindexed) {
|
||||
currentDb = db.getName();
|
||||
currentDb = db.getDisplayName();
|
||||
this.CURRENTDB_LABEL.setText("(" + currentDb + ")");
|
||||
this.CURRENTLYON_LABEL.setText("Currently indexing 1 of " + length);
|
||||
if (!db.isIndexing()) {
|
||||
@ -250,7 +250,7 @@ class ModalNoButtons extends javax.swing.JDialog implements PropertyChangeListen
|
||||
* Displays the current count of indexing when one is completed, or kills this dialog if all indexing is complete.
|
||||
*/
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (evt.getPropertyName().equals(HashDb.EVENT.INDEXING_DONE.name())) {
|
||||
if (evt.getPropertyName().equals(HashDb.Event.INDEXING_DONE.name())) {
|
||||
if (currentcount >= length) {
|
||||
this.INDEXING_PROGBAR.setValue(100);
|
||||
this.setModal(false);
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 744 B |
BIN
HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/new16.png
Normal file
BIN
HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/new16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
@ -28,6 +28,7 @@ import org.openide.nodes.PropertySupport;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.openide.util.lookup.ProxyLookup;
|
||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
|
||||
import org.sleuthkit.autopsy.directorytree.ExtractAction;
|
||||
import org.sleuthkit.autopsy.actions.AddContentTagAction;
|
||||
@ -152,6 +153,7 @@ class KeywordSearchFilterNode extends FilterNode {
|
||||
actions.add(new HashSearchAction("Search for files with the same MD5 hash", getOriginal()));
|
||||
actions.add(null); // creates a menu separator
|
||||
actions.add(AddContentTagAction.getInstance());
|
||||
actions.addAll(ContextMenuExtensionPoint.getActions());
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,9 @@ import org.netbeans.junit.NbModuleSuite;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.keywordsearch.*;
|
||||
import org.sleuthkit.datamodel.SleuthkitJNI;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
|
||||
/**
|
||||
* This test expects the following system properties to be set: img_path: The
|
||||
@ -93,7 +96,8 @@ public class RegressionTest extends TestCase {
|
||||
NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(RegressionTest.class).
|
||||
clusters(".*").
|
||||
enableModules(".*");
|
||||
conf = conf.addTest("testNewCaseWizardOpen",
|
||||
conf = conf.addTest("testHashDbJni",
|
||||
"testNewCaseWizardOpen",
|
||||
"testNewCaseWizard",
|
||||
"testStartAddDataSource",
|
||||
"testConfigureIngest1",
|
||||
@ -103,7 +107,8 @@ public class RegressionTest extends TestCase {
|
||||
"testAddSourceWizard1",
|
||||
"testIngest",
|
||||
"testGenerateReportToolbar",
|
||||
"testGenerateReportButton");
|
||||
"testGenerateReportButton"
|
||||
);
|
||||
return NbModuleSuite.create(conf);
|
||||
|
||||
|
||||
@ -125,6 +130,39 @@ public class RegressionTest extends TestCase {
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
public void testHashDbJni() {
|
||||
logger.info("HashDb JNI");
|
||||
try
|
||||
{
|
||||
String hashfn = "regtestHash.kdb";
|
||||
String md5hash = "b8c51089ebcdf9f11154a021438f5bd6";
|
||||
String md5hash2 = "cb4aca35f3fd54aacf96da9cd9acadb8";
|
||||
String md5hashBad = "35b299c6fcf47ece375b3221bdc16969";
|
||||
|
||||
logger.info("Creating hash db " + hashfn);
|
||||
int handle = SleuthkitJNI.createHashDatabase(hashfn);
|
||||
|
||||
logger.info("Adding hash " + md5hash);
|
||||
SleuthkitJNI.addToHashDatabase("", md5hash, "", "", handle);
|
||||
|
||||
logger.info("Adding hash " + md5hash2);
|
||||
SleuthkitJNI.addToHashDatabase("", md5hash2, "", "", handle);
|
||||
|
||||
logger.info("Querying for known hash " + md5hash);
|
||||
TskData.FileKnown k = SleuthkitJNI.lookupInHashDatabase(md5hash, handle);
|
||||
logger.info("Query result: " + k.toString());
|
||||
|
||||
logger.info("Querying for unknown hash " + md5hashBad);
|
||||
TskData.FileKnown k2 = SleuthkitJNI.lookupInHashDatabase(md5hashBad, handle);
|
||||
logger.info("Query result: " + k2.toString());
|
||||
|
||||
} catch (TskException ex) {
|
||||
logger.log(Level.WARNING, "Database creation error: ", ex);
|
||||
logger.info("A TskException occurred.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void testNewCaseWizardOpen() {
|
||||
logger.info("New Case");
|
||||
NbDialogOperator nbdo = new NbDialogOperator("Welcome");
|
||||
|
Loading…
x
Reference in New Issue
Block a user