mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 18:17:43 +00:00
Support importing Encase lists, preserve hierarchy
This commit is contained in:
parent
98f2b540ce
commit
3b10a8e9e8
@ -19,28 +19,99 @@
|
|||||||
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() {
|
||||||
@ -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));
|
||||||
}
|
}
|
||||||
theLists.put(theFile.getName(),
|
this.rootEntry = entriesUnsorted.remove(0);
|
||||||
new KeywordSearchList(theFile.getName(),
|
doCreateEntryStructure(this.rootEntry);
|
||||||
new Date(theFile.lastModified()),
|
doCreateListsFromEntries(this.rootEntry, "");
|
||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user