This commit is contained in:
adam-m 2012-06-08 09:58:41 -04:00
commit 008d11c494
8 changed files with 188 additions and 71 deletions

View File

@ -40,7 +40,6 @@ class KeywordSearchConfigurationAction extends CallableSystemAction{
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
panel.save();
dialog.close(); dialog.close();
} }
}); });

View File

@ -121,15 +121,4 @@ public class KeywordSearchConfigurationPanel extends javax.swing.JPanel {
private javax.swing.JSplitPane mainSplitPane; private javax.swing.JSplitPane mainSplitPane;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
void save() {
KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent();
KeywordSearchIngestService service = KeywordSearchIngestService.getDefault();
if (IngestManager.getDefault().isServiceRunning(service)) {
for (KeywordSearchList list : loader.getListsL()) {
if (list.getUseForIngest()) {
service.addToKeywordLists(list.getName());
}
}
}
}
} }

View File

@ -443,12 +443,6 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi
return keywordLists == null ? new ArrayList<String>() : keywordLists; return keywordLists == null ? new ArrayList<String>() : keywordLists;
} }
void addToKeywordLists(String name) {
if (!keywordLists.contains(name)) {
keywordLists.add(name);
}
}
/** /**
* Check if time to commit, if so, run commit. * Check if time to commit, if so, run commit.
* Then run search if search timer is also set. * Then run search if search timer is also set.
@ -904,4 +898,8 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi
void setSkipKnown(boolean skip) { void setSkipKnown(boolean skip) {
this.skipKnown = skip; this.skipKnown = skip;
} }
boolean getSkipKnown() {
return skipKnown;
}
} }

View File

@ -270,7 +270,7 @@ public abstract class KeywordSearchListsAbstract {
boolean deleteList(String name) { boolean deleteList(String name) {
boolean deleted = false; boolean deleted = false;
KeywordSearchList delList = getList(name); KeywordSearchList delList = getList(name);
if (delList != null) { if (delList != null && !delList.isLocked()) {
theLists.remove(name); theLists.remove(name);
deleted = save(); deleted = save();
} }

View File

@ -19,29 +19,100 @@
package org.sleuthkit.autopsy.keywordsearch; package org.sleuthkit.autopsy.keywordsearch;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.JOptionPane;
/** /**
*
* @author dfickling * @author dfickling
* KeywordSearchListsEncase adds support for Encase tab-delimited
* keyword list exports to Autopsy.
*
* load() does the I/O operation, converting lines from the text file to
* an unsorted list of EncaseFileEntrys
* The next step is to recreate the original folder hierarchy,
* and finally the EncaseFileEntries are converted to KeywordSearchLists
*
*/ */
public class KeywordSearchListsEncase extends KeywordSearchListsAbstract{ public class KeywordSearchListsEncase extends KeywordSearchListsAbstract{
ArrayList<EncaseFileEntry> entriesUnsorted;
EncaseFileEntry rootEntry;
public KeywordSearchListsEncase(String encasePath) { public KeywordSearchListsEncase(String encasePath) {
super(encasePath); super(encasePath);
} }
/**
* Follow the EncaseFileEntry hierarchy starting with given entry
* Create list for each Folder entry, add keyword for each Expression
* @param entry
* @param parentPath
*/
private void doCreateListsFromEntries(EncaseFileEntry entry, String parentPath) {
String name;
if(parentPath.isEmpty()) {
name = entry.name;
} else {
name = parentPath + "/" + entry.name;
}
List<Keyword> children = new ArrayList<Keyword>();
for(EncaseFileEntry child : entry.children) {
switch(child.type) {
case Folder:
doCreateListsFromEntries(child, name);
break;
case Expression:
if(child.flags.contains(EncaseFlag.pg)) { // Skip GREP keywords
break;
}
children.add(new Keyword(child.value, true));
break;
}
}
// Give each list a unique name
if(theLists.containsKey(name)) {
int i = 2;
while(theLists.containsKey(name + "(" + i + ")")) {
i+=1;
}
name = name + "(" + i + ")";
}
// Don't create lists if there are no keywords
if (!children.isEmpty()) {
KeywordSearchList newList = new KeywordSearchList(name, new Date(), new Date(),
true, true, children);
theLists.put(name, newList);
}
}
/**
* Convert entriesUnsorted (a list of childless and parentless EncaseFileEntries) into an EncaseFileEntry structure
*/
private void doCreateEntryStructure(EncaseFileEntry parent) {
if (!parent.isFull()) {
EncaseFileEntry child = entriesUnsorted.remove(0);
child.hasParent = true;
child.parent = parent;
parent.addChild(child);
if(!child.isFull()) {
doCreateEntryStructure(child);
}
if (!parent.isFull()) {
doCreateEntryStructure(parent);
}
}
if (parent.hasParent) {
doCreateEntryStructure(parent.parent);
}
}
@Override @Override
public boolean save() { public boolean save() {
throw new UnsupportedOperationException("Not supported yet."); throw new UnsupportedOperationException("Not supported yet.");
@ -50,37 +121,36 @@ public class KeywordSearchListsEncase extends KeywordSearchListsAbstract{
@Override @Override
public boolean load() { public boolean load() {
try { try {
File theFile = new File(filePath);
BufferedReader readBuffer = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "utf-16")); BufferedReader readBuffer = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "utf-16"));
String line; String structLine;
// If any terms are grep terms, we'll show the user a dialog at the end. String metaLine;
boolean anyGrep = false; entriesUnsorted = new ArrayList<EncaseFileEntry>();
List<Keyword> words = new ArrayList<Keyword>(); for(int line = 1; line < 6; line++) {
while ((line = readBuffer.readLine()) != null) { readBuffer.readLine();
String[] tabDelim = line.split("\t"); }
if (tabDelim.length > 2) { while ((structLine = readBuffer.readLine()) != null && (metaLine = readBuffer.readLine()) != null) {
String expr = tabDelim[2]; String[] structArr = structLine.split("\t");
if (tabDelim.length > 8) { String[] metaArr = metaLine.split("\t");
boolean literal = tabDelim[8].isEmpty() || !tabDelim[8].equals("1"); EncaseMetaType type = EncaseMetaType.getType(metaArr[0]);
anyGrep = anyGrep || !literal; String childCount = structArr[1];
//TODO: Stop skipping non-literal search terms String name = metaArr[1];
if (!expr.isEmpty() && !expr.equals("t") && literal) { String value = metaArr[2];
words.add(new Keyword(expr, literal)); ArrayList<EncaseFlag> flags = new ArrayList<EncaseFlag>();
for(int i = 0; i < 17; i++) {
if(metaArr.length < i+4) {
continue;
}
if(!metaArr[i+3].equals("")) {
flags.add(EncaseFlag.getFlag(i));
} }
} }
entriesUnsorted.add(new EncaseFileEntry(name, value, Integer.parseInt(childCount), false, null, type, flags));
} }
} this.rootEntry = entriesUnsorted.remove(0);
theLists.put(theFile.getName(), doCreateEntryStructure(this.rootEntry);
new KeywordSearchList(theFile.getName(), doCreateListsFromEntries(this.rootEntry, "");
new Date(theFile.lastModified()),
new Date(theFile.lastModified()),
true, true, words));
if(anyGrep) {
JOptionPane.showMessageDialog(null, "Importing grep (regular expression) keywords is not currently supported. Any that were in the list "
+ theFile.getName() + " have not been imported.");
}
return true; return true;
} catch (FileNotFoundException ex) { } catch (FileNotFoundException ex) {
logger.log(Level.INFO, "File at " + filePath + " does not exist!", ex); logger.log(Level.INFO, "File at " + filePath + " does not exist!", ex);
} catch (IOException ex) { } catch (IOException ex) {
@ -89,4 +159,62 @@ public class KeywordSearchListsEncase extends KeywordSearchListsAbstract{
return false; return false;
} }
private enum EncaseMetaType {
Expression, Folder;
static EncaseMetaType getType(String type) {
if(type.equals("5")) {
return Folder;
} else if(type.equals("")) {
return Expression;
} else {
throw new IllegalArgumentException("Unsupported EncaseMetaType: " + type);
}
}
}
/*
* Flags for EncaseFileEntries.
* p8 = UTF-8
* p7 = UTF-7
* pg = GREP
*/
private enum EncaseFlag {
pc, pu, pb, p8, p7, pg, an, ph, or, di, um, st, ww, pr, lo, ta, cp;
static EncaseFlag getFlag(int i) {
return EncaseFlag.values()[i];
}
}
/**
* An entry in the Encase keyword list file.
*/
private class EncaseFileEntry {
String name;
String value;
int childCount;
List<EncaseFileEntry> children;
EncaseFileEntry parent;
EncaseMetaType type;
boolean hasParent;
ArrayList<EncaseFlag> flags;
EncaseFileEntry(String name, String value, int childCount, boolean hasParent, EncaseFileEntry parent, EncaseMetaType type, ArrayList<EncaseFlag> flags) {
this.name = name;
this.value = value;
this.childCount = childCount;
this.children = new ArrayList<EncaseFileEntry>();
this.hasParent = hasParent;
this.parent = parent;
this.type = type;
this.flags = flags;
}
boolean isFull() {
return children.size() == childCount;
}
void addChild(EncaseFileEntry child) {
children.add(child);
}
}
} }

View File

@ -78,6 +78,9 @@
<TableHeader reorderingAllowed="false" resizingAllowed="true"/> <TableHeader reorderingAllowed="false" resizingAllowed="true"/>
</Property> </Property>
</Properties> </Properties>
<Events>
<EventHandler event="keyPressed" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="listsTableKeyPressed"/>
</Events>
</Component> </Component>
</SubComponents> </SubComponents>
</Container> </Container>

View File

@ -24,23 +24,18 @@
*/ */
package org.sleuthkit.autopsy.keywordsearch; package org.sleuthkit.autopsy.keywordsearch;
import java.awt.Component; import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
/** /**
* *
@ -103,6 +98,7 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel {
} }
} }
}); });
this.skipNSRLCheckBox.setSelected(KeywordSearchIngestService.getDefault().getSkipKnown());
} }
@ -124,13 +120,17 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel {
setMinimumSize(new java.awt.Dimension(200, 0)); setMinimumSize(new java.awt.Dimension(200, 0));
setPreferredSize(new java.awt.Dimension(200, 297)); setPreferredSize(new java.awt.Dimension(200, 297));
jScrollPane1.setBorder(null);
jScrollPane1.setPreferredSize(new java.awt.Dimension(200, 402)); jScrollPane1.setPreferredSize(new java.awt.Dimension(200, 402));
listsTable.setModel(tableModel); listsTable.setModel(tableModel);
listsTable.setShowHorizontalLines(false); listsTable.setShowHorizontalLines(false);
listsTable.setShowVerticalLines(false); listsTable.setShowVerticalLines(false);
listsTable.getTableHeader().setReorderingAllowed(false); listsTable.getTableHeader().setReorderingAllowed(false);
listsTable.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyPressed(java.awt.event.KeyEvent evt) {
listsTableKeyPressed(evt);
}
});
jScrollPane1.setViewportView(listsTable); jScrollPane1.setViewportView(listsTable);
newListButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsManagementPanel.class, "KeywordSearchListsManagementPanel.newListButton.text")); // NOI18N newListButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsManagementPanel.class, "KeywordSearchListsManagementPanel.newListButton.text")); // NOI18N
@ -174,7 +174,7 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel {
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 267, Short.MAX_VALUE) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE)
.addGap(0, 0, 0) .addGap(0, 0, 0)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(newListButton) .addComponent(newListButton)
@ -290,6 +290,18 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel {
KeywordSearchIngestService.getDefault().setSkipKnown(skipNSRLCheckBox.isSelected()); KeywordSearchIngestService.getDefault().setSkipKnown(skipNSRLCheckBox.isSelected());
}//GEN-LAST:event_skipNSRLCheckBoxActionPerformed }//GEN-LAST:event_skipNSRLCheckBoxActionPerformed
private void listsTableKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_listsTableKeyPressed
if(evt.getKeyCode() == KeyEvent.VK_DELETE) {
int[] selected = listsTable.getSelectedRows();
if(selected.length == 0) {
return;
}
KeywordSearchListsXML deleter = KeywordSearchListsXML.getCurrent();
String listName = deleter.getListNames().get(selected[0]);
KeywordSearchListsXML.getCurrent().deleteList(listName);
}
}//GEN-LAST:event_listsTableKeyPressed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton importButton; private javax.swing.JButton importButton;
private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane1;

View File

@ -158,12 +158,6 @@ class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer {
} }
} }
}); });
ingestListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
addToIngestAction(e);
}
};
searchListener = new ActionListener() { searchListener = new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
@ -329,12 +323,6 @@ class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer {
} }
} }
private void addToIngestAction(ActionEvent e) {
for(KeywordSearchList list : listsTableModel.getSelectedListsL()){
KeywordSearchIngestService.getDefault().addToKeywordLists(list.getName());
}
}
@Override @Override
public List<Keyword> getQueryList() { public List<Keyword> getQueryList() {
List<Keyword> ret = new ArrayList<Keyword>(); List<Keyword> ret = new ArrayList<Keyword>();