19 package org.sleuthkit.autopsy.keywordsearch;
 
   21 import java.beans.PropertyChangeListener;
 
   22 import java.beans.PropertyChangeSupport;
 
   24 import java.util.ArrayList;
 
   25 import java.util.Date;
 
   26 import java.util.LinkedHashMap;
 
   27 import java.util.List;
 
   30 import org.openide.util.NbBundle;
 
   34 import java.util.logging.Level;
 
   39 abstract class KeywordSearchList {
 
   41     protected String filePath;
 
   42     Map<String, KeywordList> theLists; 
 
   43     protected static final Logger logger = Logger.getLogger(KeywordSearchList.class.getName());
 
   44     PropertyChangeSupport changeSupport; 
 
   45     protected List<String> lockedLists;
 
   47     KeywordSearchList(String filePath) {
 
   48         this.filePath = filePath;
 
   49         theLists = 
new LinkedHashMap<>();
 
   50         lockedLists = 
new ArrayList<>();
 
   51         changeSupport = 
new PropertyChangeSupport(
this);
 
   61         LIST_ADDED, LIST_DELETED, LIST_UPDATED
 
   65         LANGUAGES_CHANGED, ENCODINGS_CHANGED
 
   68     void fireLanguagesEvent(LanguagesEvent event) {
 
   70             changeSupport.firePropertyChange(event.toString(), null, null);
 
   71         } 
catch (Exception e) {
 
   72             logger.log(Level.SEVERE, 
"KeywordSearchListsAbstract listener threw exception", e); 
 
   76     public void addPropertyChangeListener(PropertyChangeListener listener) {
 
   77         changeSupport.addPropertyChangeListener(listener);
 
   80     public void removePropertyChangeListener(PropertyChangeListener listener) {
 
   81         changeSupport.removePropertyChangeListener(listener);
 
   84     private void prepopulateLists() {
 
   85         if (!theLists.isEmpty()) {
 
   89         List<Keyword> phones = 
new ArrayList<>();
 
   90         phones.add(
new Keyword(
"[(]{0,1}\\d\\d\\d[)]{0,1}[\\.-]\\d\\d\\d[\\.-]\\d\\d\\d\\d", 
false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)); 
 
   93         List<Keyword> ips = 
new ArrayList<>();
 
   94         ips.add(
new Keyword(
"(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])", 
false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IP_ADDRESS));
 
   96         List<Keyword> emails = 
new ArrayList<>();
 
   97         emails.add(
new Keyword(
"(?=.{8})[a-z0-9%+_-]+(?:\\.[a-z0-9%+_-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z]{2,4}(?<!\\.txt|\\.exe|\\.dll|\\.jpg|\\.xml)", 
 
   98                 false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL));
 
  102         List<Keyword> urls = 
new ArrayList<>();
 
  104         urls.add(
new Keyword(
"((((ht|f)tp(s?))\\://)|www\\.)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,5})(\\:[0-9]+)*(/($|[a-zA-Z0-9\\.\\,\\;\\?\\'\\\\+&%\\$#\\=~_\\-]+))*", 
false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)); 
 
  111         name = 
"Phone Numbers"; 
 
  112         lockedLists.add(name);
 
  113         addList(name, phones, 
false, 
false, 
true);
 
  115         name = 
"IP Addresses"; 
 
  116         lockedLists.add(name);
 
  117         addList(name, ips, 
false, 
false, 
true);
 
  119         name = 
"Email Addresses"; 
 
  120         lockedLists.add(name);
 
  121         addList(name, emails, 
true, 
false, 
true);
 
  124         lockedLists.add(name);
 
  125         addList(name, urls, 
false, 
false, 
true);
 
  131     public void reload() {
 
  132         boolean created = 
false;
 
  140         List<String> toClear = 
new ArrayList<>();
 
  141         for (String list : theLists.keySet()) {
 
  142             if (theLists.get(list).isLocked() == 
false) {
 
  146         for (String clearList : toClear) {
 
  147             theLists.remove(clearList);
 
  150         if (!listFileExists()) {
 
  157         if (!load() && !created) {
 
  163     public List<KeywordList> getListsL() {
 
  164         List<KeywordList> ret = 
new ArrayList<>();
 
  165         for (KeywordList list : theLists.values()) {
 
  171     public List<KeywordList> getListsL(
boolean locked) {
 
  172         List<KeywordList> ret = 
new ArrayList<>();
 
  173         for (KeywordList list : theLists.values()) {
 
  174             if (list.isLocked().equals(locked)) {
 
  186     public List<String> getListNames() {
 
  187         return new ArrayList<>(theLists.keySet());
 
  196     public List<String> getListNames(
boolean locked) {
 
  197         ArrayList<String> lists = 
new ArrayList<>();
 
  198         for (String listName : theLists.keySet()) {
 
  199             KeywordList list = theLists.get(listName);
 
  200             if (locked == list.isLocked()) {
 
  214     public KeywordList getListWithKeyword(String keyword) {
 
  215         KeywordList found = null;
 
  216         for (KeywordList list : theLists.values()) {
 
  217             if (list.hasKeyword(keyword)) {
 
  230     int getNumberLists() {
 
  231         return theLists.size();
 
  240     public int getNumberLists(
boolean locked) {
 
  242         for (String listName : theLists.keySet()) {
 
  243             KeywordList list = theLists.get(listName);
 
  244             if (locked == list.isLocked()) {
 
  257     public KeywordList getList(String name) {
 
  258         return theLists.get(name);
 
  267     boolean listExists(String name) {
 
  268         return getList(name) != null;
 
  280     boolean addList(String name, List<Keyword> newList, 
boolean useForIngest, 
boolean ingestMessages, 
boolean locked) {
 
  281         boolean replaced = 
false;
 
  282         KeywordList curList = getList(name);
 
  283         final Date now = 
new Date();
 
  285         if (curList == null) {
 
  286             theLists.put(name, 
new KeywordList(name, now, now, useForIngest, ingestMessages, newList, locked));
 
  288                 changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, name);
 
  289             } 
catch (Exception e) {
 
  290                 logger.log(Level.SEVERE, 
"KeywordSearchListsAbstract listener threw exception", e); 
 
  291                 MessageNotifyUtil.Notify.show(
 
  292                         NbBundle.getMessage(
this.getClass(), 
"KeywordSearchListsAbstract.moduleErr"),
 
  293                         NbBundle.getMessage(
this.getClass(), 
"KeywordSearchListsAbstract.addList.errMsg1.msg"),
 
  294                         MessageNotifyUtil.MessageType.ERROR);
 
  297             theLists.put(name, 
new KeywordList(name, curList.getDateCreated(), now, useForIngest, ingestMessages, newList, locked));
 
  301                 changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, name);
 
  302             } 
catch (Exception e) {
 
  303                 logger.log(Level.SEVERE, 
"KeywordSearchListsAbstract listener threw exception", e); 
 
  304                 MessageNotifyUtil.Notify.show(
 
  305                         NbBundle.getMessage(
this.getClass(), 
"KeywordSearchListsAbstract.moduleErr"),
 
  306                         NbBundle.getMessage(
this.getClass(), 
"KeywordSearchListsAbstract.addList.errMsg2.msg"),
 
  307                         MessageNotifyUtil.MessageType.ERROR);
 
  314     boolean addList(String name, List<Keyword> newList, 
boolean useForIngest, 
boolean ingestMessages) {
 
  316         boolean isLocked = this.lockedLists.contains(name);
 
  317         return addList(name, newList, useForIngest, ingestMessages, isLocked);
 
  320     boolean addList(String name, List<Keyword> newList) {
 
  321         return addList(name, newList, 
true, 
true);
 
  324     boolean addList(KeywordList list) {
 
  325         return addList(list.getName(), list.getKeywords(), list.getUseForIngest(), list.getIngestMessages(), list.isLocked());
 
  334     boolean saveLists(List<KeywordList> lists) {
 
  335         List<KeywordList> overwritten = 
new ArrayList<>();
 
  336         List<KeywordList> newLists = 
new ArrayList<>();
 
  337         for (KeywordList list : lists) {
 
  338             if (this.listExists(list.getName())) {
 
  339                 overwritten.add(list);
 
  343             theLists.put(list.getName(), list);
 
  345         boolean saved = save(
true);
 
  347             for (KeywordList list : newLists) {
 
  349                     changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
 
  350                 } 
catch (Exception e) {
 
  351                     logger.log(Level.SEVERE, 
"KeywordSearchListsAbstract listener threw exception", e); 
 
  352                     MessageNotifyUtil.Notify.show(
 
  353                             NbBundle.getMessage(
this.getClass(), 
"KeywordSearchListsAbstract.moduleErr"),
 
  354                             NbBundle.getMessage(
this.getClass(), 
"KeywordSearchListsAbstract.saveList.errMsg1.msg"),
 
  355                                                   MessageNotifyUtil.MessageType.ERROR);
 
  358             for (KeywordList over : overwritten) {
 
  360                     changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
 
  361                 } 
catch (Exception e) {
 
  362                     logger.log(Level.SEVERE, 
"KeywordSearchListsAbstract listener threw exception", e); 
 
  363                     MessageNotifyUtil.Notify.show(
 
  364                             NbBundle.getMessage(
this.getClass(), 
"KeywordSearchListsAbstract.moduleErr"),
 
  365                             NbBundle.getMessage(
this.getClass(), 
"KeywordSearchListsAbstract.saveList.errMsg2.msg"),
 
  366                             MessageNotifyUtil.MessageType.ERROR);
 
  380     boolean writeLists(List<KeywordList> lists) {
 
  381         List<KeywordList> overwritten = 
new ArrayList<>();
 
  382         List<KeywordList> newLists = 
new ArrayList<>();
 
  383         for (KeywordList list : lists) {
 
  384             if (this.listExists(list.getName())) {
 
  385                 overwritten.add(list);
 
  389             theLists.put(list.getName(), list);
 
  392         for (KeywordList list : newLists) {
 
  395                 changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
 
  396             } 
catch (Exception e) {
 
  397                 logger.log(Level.SEVERE, 
"KeywordSearchListsAbstract listener threw exception", e); 
 
  398                 MessageNotifyUtil.Notify.show(
 
  399                         NbBundle.getMessage(
this.getClass(), 
"KeywordSearchListsAbstract.moduleErr"),
 
  400                         NbBundle.getMessage(
this.getClass(), 
"KeywordSearchListsAbstract.writeLists.errMsg1.msg"),
 
  401                         MessageNotifyUtil.MessageType.ERROR);
 
  405         for (KeywordList over : overwritten) {
 
  408                 changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
 
  409             } 
catch (Exception e) {
 
  410                 logger.log(Level.SEVERE, 
"KeywordSearchListsAbstract listener threw exception", e); 
 
  411                 MessageNotifyUtil.Notify.show(
 
  412                         NbBundle.getMessage(
this.getClass(), 
"KeywordSearchListsAbstract.moduleErr"),
 
  413                         NbBundle.getMessage(
this.getClass(), 
"KeywordSearchListsAbstract.writeLists.errMsg2.msg"),
 
  414                         MessageNotifyUtil.MessageType.ERROR);
 
  427     boolean deleteList(String name) {
 
  428         KeywordList delList = getList(name);
 
  429         if (delList != null && !delList.isLocked()) {
 
  430             theLists.remove(name);
 
  434             changeSupport.firePropertyChange(ListsEvt.LIST_DELETED.toString(), null, name);
 
  435         } 
catch (Exception e) {
 
  436             logger.log(Level.SEVERE, 
"KeywordSearchListsAbstract listener threw exception", e); 
 
  437             MessageNotifyUtil.Notify.show(
 
  438                     NbBundle.getMessage(
this.getClass(), 
"KeywordSearchListsAbstract.moduleErr"),
 
  439                     NbBundle.getMessage(
this.getClass(), 
"KeywordSearchListsAbstract.deleteList.errMsg1.msg"),
 
  440                     MessageNotifyUtil.MessageType.ERROR);
 
  449     public abstract boolean save();
 
  457     public abstract boolean save(
boolean isExport);
 
  462     public abstract boolean load();
 
  464     private boolean listFileExists() {
 
  465         File f = 
new File(filePath);
 
  466         return f.exists() && f.canRead() && f.canWrite();
 
  469     public void setUseForIngest(String key, 
boolean flag) {
 
  470         theLists.get(key).setUseForIngest(flag);