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
66 LANGUAGES_CHANGED, ENCODINGS_CHANGED
69 void fireLanguagesEvent(LanguagesEvent event) {
71 changeSupport.firePropertyChange(event.toString(), null, null);
72 }
catch (Exception e) {
73 logger.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
77 public void addPropertyChangeListener(PropertyChangeListener listener) {
78 changeSupport.addPropertyChangeListener(listener);
81 public void removePropertyChangeListener(PropertyChangeListener listener) {
82 changeSupport.removePropertyChangeListener(listener);
85 private void prepopulateLists() {
86 if (!theLists.isEmpty()) {
90 List<Keyword> phones =
new ArrayList<>();
91 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));
94 List<Keyword> ips =
new ArrayList<>();
95 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));
97 List<Keyword> emails =
new ArrayList<>();
98 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)",
99 false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL));
103 List<Keyword> urls =
new ArrayList<>();
105 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());
197 public List<String> getListNames(
boolean locked) {
198 ArrayList<String> lists =
new ArrayList<>();
199 for (String listName : theLists.keySet()) {
200 KeywordList list = theLists.get(listName);
201 if (locked == list.isLocked()) {
216 public KeywordList getListWithKeyword(String keyword) {
217 KeywordList found = null;
218 for (KeywordList list : theLists.values()) {
219 if (list.hasKeyword(keyword)) {
232 int getNumberLists() {
233 return theLists.size();
243 public int getNumberLists(
boolean locked) {
245 for (String listName : theLists.keySet()) {
246 KeywordList list = theLists.get(listName);
247 if (locked == list.isLocked()) {
261 public KeywordList getList(String name) {
262 return theLists.get(name);
272 boolean listExists(String name) {
273 return getList(name) != null;
286 boolean addList(String name, List<Keyword> newList,
boolean useForIngest,
boolean ingestMessages,
boolean locked) {
287 boolean replaced =
false;
288 KeywordList curList = getList(name);
289 final Date now =
new Date();
291 if (curList == null) {
292 theLists.put(name,
new KeywordList(name, now, now, useForIngest, ingestMessages, newList, locked));
294 changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, name);
295 }
catch (Exception e) {
296 logger.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
297 MessageNotifyUtil.Notify.show(
298 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.moduleErr"),
299 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.addList.errMsg1.msg"),
300 MessageNotifyUtil.MessageType.ERROR);
303 theLists.put(name,
new KeywordList(name, curList.getDateCreated(), now, useForIngest, ingestMessages, newList, locked));
307 changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, name);
308 }
catch (Exception e) {
309 logger.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
310 MessageNotifyUtil.Notify.show(
311 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.moduleErr"),
312 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.addList.errMsg2.msg"),
313 MessageNotifyUtil.MessageType.ERROR);
320 boolean addList(String name, List<Keyword> newList,
boolean useForIngest,
boolean ingestMessages) {
322 boolean isLocked = this.lockedLists.contains(name);
323 return addList(name, newList, useForIngest, ingestMessages, isLocked);
326 boolean addList(String name, List<Keyword> newList) {
327 return addList(name, newList,
true,
true);
330 boolean addList(KeywordList list) {
331 return addList(list.getName(), list.getKeywords(), list.getUseForIngest(), list.getIngestMessages(), list.isLocked());
341 boolean saveLists(List<KeywordList> lists) {
342 List<KeywordList> overwritten =
new ArrayList<>();
343 List<KeywordList> newLists =
new ArrayList<>();
344 for (KeywordList list : lists) {
345 if (this.listExists(list.getName())) {
346 overwritten.add(list);
350 theLists.put(list.getName(), list);
352 boolean saved = save(
true);
354 for (KeywordList list : newLists) {
356 changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
357 }
catch (Exception e) {
358 logger.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
359 MessageNotifyUtil.Notify.show(
360 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.moduleErr"),
361 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.saveList.errMsg1.msg"),
362 MessageNotifyUtil.MessageType.ERROR);
365 for (KeywordList over : overwritten) {
367 changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
368 }
catch (Exception e) {
369 logger.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
370 MessageNotifyUtil.Notify.show(
371 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.moduleErr"),
372 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.saveList.errMsg2.msg"),
373 MessageNotifyUtil.MessageType.ERROR);
388 boolean writeLists(List<KeywordList> lists) {
389 List<KeywordList> overwritten =
new ArrayList<>();
390 List<KeywordList> newLists =
new ArrayList<>();
391 for (KeywordList list : lists) {
392 if (this.listExists(list.getName())) {
393 overwritten.add(list);
397 theLists.put(list.getName(), list);
400 for (KeywordList list : newLists) {
403 changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
404 }
catch (Exception e) {
405 logger.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
406 MessageNotifyUtil.Notify.show(
407 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.moduleErr"),
408 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.writeLists.errMsg1.msg"),
409 MessageNotifyUtil.MessageType.ERROR);
413 for (KeywordList over : overwritten) {
416 changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
417 }
catch (Exception e) {
418 logger.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
419 MessageNotifyUtil.Notify.show(
420 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.moduleErr"),
421 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.writeLists.errMsg2.msg"),
422 MessageNotifyUtil.MessageType.ERROR);
436 boolean deleteList(String name) {
437 KeywordList delList = getList(name);
438 if (delList != null && !delList.isLocked()) {
439 theLists.remove(name);
443 changeSupport.firePropertyChange(ListsEvt.LIST_DELETED.toString(), null, name);
444 }
catch (Exception e) {
445 logger.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
446 MessageNotifyUtil.Notify.show(
447 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.moduleErr"),
448 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.deleteList.errMsg1.msg"),
449 MessageNotifyUtil.MessageType.ERROR);
458 public abstract boolean save();
466 public abstract boolean save(
boolean isExport);
471 public abstract boolean load();
473 private boolean listFileExists() {
474 File f =
new File(filePath);
475 return f.exists() && f.canRead() && f.canWrite();
478 public void setUseForIngest(String key,
boolean flag) {
479 theLists.get(key).setUseForIngest(flag);