Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
HashDbSearchPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2018 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.modules.hashdatabase;
20 
21 import java.awt.Color;
22 import java.awt.event.ActionEvent;
23 import java.awt.event.ActionListener;
24 import java.awt.event.KeyAdapter;
25 import java.awt.event.KeyEvent;
26 import java.util.ArrayList;
27 
28 import org.openide.util.NbBundle;
30 import javax.swing.JOptionPane;
31 import javax.swing.table.DefaultTableModel;
32 import javax.swing.text.AttributeSet;
33 import javax.swing.text.BadLocationException;
34 import javax.swing.text.PlainDocument;
37 
41 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
42 class HashDbSearchPanel extends javax.swing.JPanel implements ActionListener {
43 
44  private static final Logger logger = Logger.getLogger(HashDbSearchPanel.class.getName());
45  private static HashDbSearchPanel instance;
46 
50  public static HashDbSearchPanel getDefault() {
51  if (instance == null) {
52  instance = new HashDbSearchPanel();
53  }
54  return instance;
55  }
56 
60  public void refresh() {
61  boolean running = IngestManager.getInstance().isIngestRunning();
62  if (running) {
63  titleLabel.setForeground(Color.red);
64  titleLabel.setText(NbBundle.getMessage(this.getClass(), "HashDbSearchPanel.titleText.ingestOngoing"));
65  } else {
66  titleLabel.setForeground(Color.black);
67  titleLabel.setText(NbBundle.getMessage(this.getClass(), "HashDbSearchPanel.titleLabel.text"));
68  }
69  hashField.setEditable(!running);
70  searchButton.setEnabled(!running);
71  addButton.setEnabled(!running);
72  removeButton.setEnabled(!running);
73  hashTable.setEnabled(!running);
74  hashLabel.setEnabled(!running);
75  saveBox.setEnabled(!running);
76  }
77 
81  private HashDbSearchPanel() {
82  setName(HashDbPanelSearchAction.ACTION_NAME);
83  initComponents();
84  customInit();
85  }
86 
87  final void customInit() {
88  addButton.addActionListener(this);
89  removeButton.addActionListener(this);
90  errorField.setVisible(false);
91  hashField.requestFocus();
92  // Don't let the user input more characters than in an MD5 hash
93  hashField.setDocument(new PlainDocument() {
94  @Override
95  public void insertString(int offset, String str, AttributeSet a) throws BadLocationException {
96  if ((this.getLength() + str.length()) <= 32) {
97  super.insertString(offset, str, a);
98  }
99  }
100  });
101  // Pressing enter adds the hash
102  hashField.addKeyListener(new KeyAdapter() {
103  @Override
104  public void keyPressed(KeyEvent e) {
105  if (e.getKeyChar() == KeyEvent.VK_ENTER) {
106  addButton.doClick();
107  }
108  }
109  });
110  // Pressing delete removes the selected rows
111  hashTable.addKeyListener(new KeyAdapter() {
112  @Override
113  public void keyPressed(KeyEvent e) {
114  if (e.getKeyChar() == KeyEvent.VK_DELETE) {
115  removeButton.doClick();
116  }
117  }
118  });
119  }
120 
121  void addSearchActionListener(ActionListener l) {
122  for (ActionListener al : searchButton.getActionListeners()) {
123  searchButton.removeActionListener(al);
124  }
125  searchButton.addActionListener(l);
126  }
127 
128  void addCancelActionListener(ActionListener l) {
129  cancelButton.addActionListener(l);
130  }
131 
137  @SuppressWarnings("rawtypes")
138  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
139  private void initComponents() {
140 
141  jScrollPane1 = new javax.swing.JScrollPane();
142  hashTable = new javax.swing.JTable();
143  hashField = new javax.swing.JTextField();
144  addButton = new javax.swing.JButton();
145  hashLabel = new javax.swing.JLabel();
146  searchButton = new javax.swing.JButton();
147  removeButton = new javax.swing.JButton();
148  jSeparator1 = new javax.swing.JSeparator();
149  titleLabel = new javax.swing.JLabel();
150  errorField = new javax.swing.JLabel();
151  saveBox = new javax.swing.JCheckBox();
152  cancelButton = new javax.swing.JButton();
153 
154  hashTable.setModel(new javax.swing.table.DefaultTableModel(
155  new Object [][] {
156 
157  },
158  new String [] {
159  "MD5 Hashes"
160  }
161  ) {
162  Class[] types = new Class [] {
163  java.lang.String.class
164  };
165  boolean[] canEdit = new boolean [] {
166  false
167  };
168 
169  public Class getColumnClass(int columnIndex) {
170  return types [columnIndex];
171  }
172 
173  public boolean isCellEditable(int rowIndex, int columnIndex) {
174  return canEdit [columnIndex];
175  }
176  });
177  jScrollPane1.setViewportView(hashTable);
178  if (hashTable.getColumnModel().getColumnCount() > 0) {
179  hashTable.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, "HashDbSearchPanel.hashTable.columnModel.title0")); // NOI18N
180  }
181 
182  hashField.setText(org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, "HashDbSearchPanel.hashField.text")); // NOI18N
183 
184  org.openide.awt.Mnemonics.setLocalizedText(addButton, org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, "HashDbSearchPanel.addButton.text")); // NOI18N
185 
186  org.openide.awt.Mnemonics.setLocalizedText(hashLabel, org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, "HashDbSearchPanel.hashLabel.text")); // NOI18N
187 
188  org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, "HashDbSearchPanel.searchButton.text")); // NOI18N
189 
190  org.openide.awt.Mnemonics.setLocalizedText(removeButton, org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, "HashDbSearchPanel.removeButton.text")); // NOI18N
191 
192  org.openide.awt.Mnemonics.setLocalizedText(titleLabel, org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, "HashDbSearchPanel.titleLabel.text")); // NOI18N
193 
194  errorField.setForeground(new java.awt.Color(255, 0, 0));
195  org.openide.awt.Mnemonics.setLocalizedText(errorField, org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, "HashDbSearchPanel.errorField.text")); // NOI18N
196 
197  org.openide.awt.Mnemonics.setLocalizedText(saveBox, org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, "HashDbSearchPanel.saveBox.text")); // NOI18N
198  saveBox.addActionListener(new java.awt.event.ActionListener() {
199  public void actionPerformed(java.awt.event.ActionEvent evt) {
200  saveBoxActionPerformed(evt);
201  }
202  });
203 
204  org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(HashDbSearchPanel.class, "HashDbSearchPanel.cancelButton.text")); // NOI18N
205 
206  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
207  this.setLayout(layout);
208  layout.setHorizontalGroup(
209  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
210  .addGroup(layout.createSequentialGroup()
211  .addContainerGap()
212  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
213  .addComponent(jScrollPane1)
214  .addGroup(layout.createSequentialGroup()
215  .addComponent(hashLabel)
216  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
217  .addComponent(hashField))
218  .addComponent(jSeparator1)
219  .addGroup(layout.createSequentialGroup()
220  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
221  .addComponent(titleLabel)
222  .addGroup(layout.createSequentialGroup()
223  .addGap(61, 61, 61)
224  .addComponent(addButton)
225  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
226  .addComponent(removeButton)
227  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
228  .addComponent(saveBox)))
229  .addGap(0, 0, Short.MAX_VALUE))
230  .addGroup(layout.createSequentialGroup()
231  .addComponent(errorField)
232  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
233  .addComponent(searchButton)
234  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
235  .addComponent(cancelButton)))
236  .addContainerGap())
237  );
238  layout.setVerticalGroup(
239  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
240  .addGroup(layout.createSequentialGroup()
241  .addContainerGap()
242  .addComponent(titleLabel)
243  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
244  .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 171, javax.swing.GroupLayout.PREFERRED_SIZE)
245  .addGap(18, 18, 18)
246  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
247  .addComponent(hashLabel)
248  .addComponent(hashField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
249  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
250  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
251  .addComponent(addButton)
252  .addComponent(removeButton)
253  .addComponent(saveBox))
254  .addGap(18, 18, 18)
255  .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
256  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
257  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
258  .addComponent(searchButton)
259  .addComponent(errorField)
260  .addComponent(cancelButton))
261  .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
262  );
263  }// </editor-fold>//GEN-END:initComponents
264 
265  private void saveBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveBoxActionPerformed
266  // TODO add your handling code here:
267  }//GEN-LAST:event_saveBoxActionPerformed
268 
269  // Variables declaration - do not modify//GEN-BEGIN:variables
270  private javax.swing.JButton addButton;
271  private javax.swing.JButton cancelButton;
272  private javax.swing.JLabel errorField;
273  private javax.swing.JTextField hashField;
274  private javax.swing.JLabel hashLabel;
275  private javax.swing.JTable hashTable;
276  private javax.swing.JScrollPane jScrollPane1;
277  private javax.swing.JSeparator jSeparator1;
278  private javax.swing.JButton removeButton;
279  private javax.swing.JCheckBox saveBox;
280  private javax.swing.JButton searchButton;
281  private javax.swing.JLabel titleLabel;
282  // End of variables declaration//GEN-END:variables
283 
284  @Override
285  public void actionPerformed(ActionEvent e) {
286  if (e.getSource().equals(addButton)) {
287  add();
288  } else if (e.getSource().equals(removeButton)) {
289  remove();
290  }
291  }
292 
297  @NbBundle.Messages ({
298  "HashDbSearchPanel.noOpenCase.errMsg=No open case available."
299  })
300  boolean search() {
301  // Check if any hashed have been entered
302  if (hashTable.getRowCount() != 0) {
303  // Make sure at least 1 file has an md5 hash
304  try {
305  if (HashDbSearcher.countFilesMd5Hashed() > 0) {
306  return doSearch();
307  } else {
308  JOptionPane.showMessageDialog(this,
309  NbBundle.getMessage(this.getClass(),
310  "HashDbSearchPanel.noFilesHaveMD5HashMsg"),
311  NbBundle.getMessage(this.getClass(), "HashDbSearchPanel.dlgMsg.title"),
312  JOptionPane.ERROR_MESSAGE);
313  return false;
314  }
315  } catch (NoCurrentCaseException ex) {
316  JOptionPane.showMessageDialog(this,
317  Bundle.HashDbSearchPanel_noOpenCase_errMsg(),
318  NbBundle.getMessage(this.getClass(), "HashDbSearchPanel.dlgMsg.title"),
319  JOptionPane.ERROR_MESSAGE);
320  return false;
321  }
322  } else {
323  errorField.setText(NbBundle.getMessage(this.getClass(), "HashDbSearchPanel.errorText.noHashesAddedMsg"));
324  errorField.setVisible(true);
325  return false;
326  }
327  }
328 
329  private boolean doSearch() {
330  errorField.setVisible(false);
331  // Get all the rows in the table
332  int numRows = hashTable.getRowCount();
333  ArrayList<String> hashes = new ArrayList<>();
334  for (int i = 0; i < numRows; i++) {
335  hashes.add((String) hashTable.getValueAt(i, 0));
336  }
337  // Start a new thread and find the hashes
338  HashDbSearchThread hashThread = new HashDbSearchThread(hashes);
339  hashThread.execute();
340  return true;
341  }
342 
346  void add() {
347  errorField.setVisible(false);
348  DefaultTableModel model = (DefaultTableModel) hashTable.getModel();
349  String hash = hashField.getText();
350  if (!hash.equals("")) {
351  if (hash.matches("[a-fA-F0-9]{32}")) {
352  for (int i = 0; i < model.getRowCount(); i++) {
353  if (model.getValueAt(i, 0).equals(hashField.getText())) {
354  hashField.setText("");
355  errorField.setText(
356  NbBundle.getMessage(this.getClass(), "HashDbSearchPanel.errorText.hashAlreadyAddedMsg"));
357  errorField.setVisible(true);
358  errorField.setVisible(true);
359  return;
360  }
361  }
362  model.addRow(new String[]{hash});
363  hashField.setText(""); // wipe the field
364  } else {
365  errorField.setText(NbBundle.getMessage(this.getClass(), "HashDbSearchPanel.errorText.invalidMD5HashMsg"));
366  errorField.setVisible(true);
367  }
368  }
369  hashField.requestFocus(); // select the field to type in
370  }
371 
375  void remove() {
376  DefaultTableModel model = (DefaultTableModel) hashTable.getModel();
377  int rows[] = hashTable.getSelectedRows();
378  // Loop backwards to delete highest row index first, otherwise
379  // index numbers change and the wrong rows are deleted
380  for (int i = rows.length - 1; i >= 0; i--) {
381  model.removeRow(rows[i]);
382  }
383  }
384 
388  void clear() {
389  if (!saveBox.isSelected()) {
390  DefaultTableModel model = (DefaultTableModel) hashTable.getModel();
391  int numRows = hashTable.getRowCount();
392  for (int i = numRows - 1; i >= 0; i--) {
393  model.removeRow(i);
394  }
395  }
396  errorField.setVisible(false);
397  hashField.setText("");
398  }
399 }

Copyright © 2012-2022 Basis Technology. Generated on: Tue Aug 1 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.