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);