From 9f95239cc4afaa5280daa664340a3f1a23279a61 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Tue, 29 Aug 2017 12:51:18 -0400 Subject: [PATCH] Added ability to search for MD5 --- .../autopsy/filesearch/Bundle.properties | 2 + .../autopsy/filesearch/FileSearchPanel.java | 2 + .../autopsy/filesearch/HashSearchFilter.java | 66 +++++++ .../autopsy/filesearch/HashSearchPanel.form | 104 +++++++++++ .../autopsy/filesearch/HashSearchPanel.java | 176 ++++++++++++++++++ 5 files changed, 350 insertions(+) create mode 100755 Core/src/org/sleuthkit/autopsy/filesearch/HashSearchFilter.java create mode 100755 Core/src/org/sleuthkit/autopsy/filesearch/HashSearchPanel.form create mode 100755 Core/src/org/sleuthkit/autopsy/filesearch/HashSearchPanel.java diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties index c5fd4d48e4..68cfc25429 100644 --- a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties @@ -56,3 +56,5 @@ SizeSearchPanel.sizeCompareComboBox.lessThan=less than MimeTypePanel.jLabel1.text=*Note: Multiple MIME types can be selected FileSearchPanel.searchButton.text=Search MimeTypePanel.mimeTypeCheckBox.text=MIME Type: +HashSearchPanel.md5CheckBox.text=MD5: +HashSearchPanel.emptyHashMsg.text=Must enter something for hash search. \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java index 23730c99c1..d7efb0b46f 100644 --- a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java @@ -94,6 +94,8 @@ class FileSearchPanel extends javax.swing.JPanel { this.filterAreas.add(new FilterArea(NbBundle.getMessage(this.getClass(), "FileSearchPanel.filterTitle.metadata"), metadataFilters)); this.filterAreas.add(new FilterArea(NbBundle.getMessage(this.getClass(), "FileSearchPanel.filterTitle.knownStatus"), new KnownStatusSearchFilter())); + + this.filterAreas.add(new FilterArea(NbBundle.getMessage(this.getClass(), "HashSearchPanel.md5CheckBox.text"), new HashSearchFilter())); for (FilterArea fa : this.filterAreas) { fa.setMaximumSize(new Dimension(Integer.MAX_VALUE, fa.getMinimumSize().height)); diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchFilter.java new file mode 100755 index 0000000000..951f4b206e --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchFilter.java @@ -0,0 +1,66 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2017 Basis Technology Corp. + * Contact: carrier sleuthkit 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.filesearch; + +import java.awt.event.ActionListener; +import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException; + +/** + * + */ +class HashSearchFilter extends AbstractFileSearchFilter { + + private static final String EMPTY_HASH_MESSAGE = NbBundle + .getMessage(HashSearchFilter.class, "HashSearchPanel.emptyHashMsg.text"); + + public HashSearchFilter() { + this(new HashSearchPanel()); + } + + public HashSearchFilter(HashSearchPanel component) { + super(component); + } + + @Override + public boolean isEnabled() { + return this.getComponent().getHashCheckBox().isSelected(); + } + + @Override + public String getPredicate() throws FilterValidationException { + String md5Hash = this.getComponent().getSearchTextField().getText(); + + if (md5Hash.isEmpty()) { + throw new FilterValidationException(EMPTY_HASH_MESSAGE); + } + + return "md5 = '" + md5Hash.toLowerCase() + "'"; //NON-NLS + } + + @Override + public void addActionListener(ActionListener l) { + getComponent().addActionListener(l); + } + + @Override + public boolean isValid() { + return !this.getComponent().getSearchTextField().getText().isEmpty(); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchPanel.form b/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchPanel.form new file mode 100755 index 0000000000..dabb115e57 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchPanel.form @@ -0,0 +1,104 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchPanel.java new file mode 100755 index 0000000000..827cc31141 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchPanel.java @@ -0,0 +1,176 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit 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.filesearch; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.JCheckBox; +import javax.swing.JMenuItem; +import javax.swing.JTextField; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +/** + * + */ +class HashSearchPanel extends javax.swing.JPanel { + + private static final long serialVersionUID = 1L; + + /** + * Creates new form HashSearchPanel + */ + HashSearchPanel() { + initComponents(); + customizeComponents(); + setComponentsEnabled(); + } + + private void customizeComponents() { + + searchTextField.setComponentPopupMenu(rightClickMenu); + ActionListener actList = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JMenuItem jmi = (JMenuItem) e.getSource(); + if (jmi.equals(cutMenuItem)) { + searchTextField.cut(); + } else if (jmi.equals(copyMenuItem)) { + searchTextField.copy(); + } else if (jmi.equals(pasteMenuItem)) { + searchTextField.paste(); + } else if (jmi.equals(selectAllMenuItem)) { + searchTextField.selectAll(); + } + } + }; + cutMenuItem.addActionListener(actList); + copyMenuItem.addActionListener(actList); + pasteMenuItem.addActionListener(actList); + selectAllMenuItem.addActionListener(actList); + this.searchTextField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); + } + + @Override + public void removeUpdate(DocumentEvent e) { + firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); + } + + @Override + public void changedUpdate(DocumentEvent e) { + firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); + } + }); + + } + + JCheckBox getHashCheckBox() { + return hashCheckBox; + } + + JTextField getSearchTextField() { + return searchTextField; + } + + void setComponentsEnabled() { + boolean enabled = hashCheckBox.isSelected(); + this.searchTextField.setEnabled(enabled); + } + + /** + * 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") + // //GEN-BEGIN:initComponents + private void initComponents() { + + rightClickMenu = new javax.swing.JPopupMenu(); + cutMenuItem = new javax.swing.JMenuItem(); + copyMenuItem = new javax.swing.JMenuItem(); + pasteMenuItem = new javax.swing.JMenuItem(); + selectAllMenuItem = new javax.swing.JMenuItem(); + hashCheckBox = new javax.swing.JCheckBox(); + searchTextField = new javax.swing.JTextField(); + + cutMenuItem.setText(org.openide.util.NbBundle.getMessage(HashSearchPanel.class, "NameSearchPanel.cutMenuItem.text")); // NOI18N + rightClickMenu.add(cutMenuItem); + + copyMenuItem.setText(org.openide.util.NbBundle.getMessage(HashSearchPanel.class, "NameSearchPanel.copyMenuItem.text")); // NOI18N + rightClickMenu.add(copyMenuItem); + + pasteMenuItem.setText(org.openide.util.NbBundle.getMessage(HashSearchPanel.class, "NameSearchPanel.pasteMenuItem.text")); // NOI18N + rightClickMenu.add(pasteMenuItem); + + selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(HashSearchPanel.class, "NameSearchPanel.selectAllMenuItem.text")); // NOI18N + rightClickMenu.add(selectAllMenuItem); + + hashCheckBox.setFont(hashCheckBox.getFont().deriveFont(hashCheckBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + hashCheckBox.setText(org.openide.util.NbBundle.getMessage(HashSearchPanel.class, "HashSearchPanel.md5CheckBox.text")); // NOI18N + hashCheckBox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + hashCheckBoxActionPerformed(evt); + } + }); + + searchTextField.setFont(searchTextField.getFont().deriveFont(searchTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + searchTextField.setText(org.openide.util.NbBundle.getMessage(HashSearchPanel.class, "NameSearchPanel.searchTextField.text")); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(hashCheckBox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(searchTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 247, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(hashCheckBox) + .addComponent(searchTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + }// //GEN-END:initComponents + + private void hashCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hashCheckBoxActionPerformed + setComponentsEnabled(); + firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); + }//GEN-LAST:event_hashCheckBoxActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JMenuItem copyMenuItem; + private javax.swing.JMenuItem cutMenuItem; + private javax.swing.JCheckBox hashCheckBox; + private javax.swing.JMenuItem pasteMenuItem; + private javax.swing.JPopupMenu rightClickMenu; + private javax.swing.JTextField searchTextField; + private javax.swing.JMenuItem selectAllMenuItem; + // End of variables declaration//GEN-END:variables + + void addActionListener(ActionListener l) { + searchTextField.addActionListener(l); + } +}