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;
29 import java.util.logging.Level;
30 import org.openide.util.NbBundle;
38 abstract class KeywordSearchList {
40 protected static final Logger LOGGER = Logger.getLogger(KeywordSearchList.class.getName());
42 private static final String PHONE_NUMBER_REGEX =
"[(]{0,1}\\d\\d\\d[)]{0,1}[\\.-]\\d\\d\\d[\\.-]\\d\\d\\d\\d";
43 private static final String IP_ADDRESS_REGEX =
"(([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])";
44 private static final String EMAIL_ADDRESS_REGEX =
"(?=.{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)";
45 private static final String URL_REGEX =
"((((ht|f)tp(s?))\\://)|www\\.)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,5})(\\:[0-9]+)*(/($|[a-zA-Z0-9\\.\\,\\;\\?\\'\\\\+&%\\$#\\=~_\\-]+))*";
46 private static final String CCN_REGEX =
".*[3456]([ -]?\\d){11,18}.*";
48 protected String filePath;
49 Map<String, KeywordList> theLists;
51 PropertyChangeSupport changeSupport;
52 protected List<String> lockedLists;
54 KeywordSearchList(String filePath) {
55 this.filePath = filePath;
56 theLists =
new LinkedHashMap<>();
57 lockedLists =
new ArrayList<>();
58 changeSupport =
new PropertyChangeSupport(
this);
79 void fireLanguagesEvent(LanguagesEvent event) {
81 changeSupport.firePropertyChange(event.toString(), null, null);
82 }
catch (Exception e) {
83 LOGGER.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
87 public void addPropertyChangeListener(PropertyChangeListener listener) {
88 changeSupport.addPropertyChangeListener(listener);
91 public void removePropertyChangeListener(PropertyChangeListener listener) {
92 changeSupport.removePropertyChangeListener(listener);
95 private void prepopulateLists() {
96 if (!theLists.isEmpty()) {
100 List<Keyword> phones =
new ArrayList<>();
101 phones.add(
new Keyword(PHONE_NUMBER_REGEX,
false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER));
102 lockedLists.add(
"Phone Numbers");
103 addList(
"Phone Numbers", phones,
false,
false,
true);
106 List<Keyword> ips =
new ArrayList<>();
107 ips.add(
new Keyword(IP_ADDRESS_REGEX,
false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IP_ADDRESS));
108 lockedLists.add(
"IP Addresses");
109 addList(
"IP Addresses", ips,
false,
false,
true);
112 List<Keyword> emails =
new ArrayList<>();
113 emails.add(
new Keyword(EMAIL_ADDRESS_REGEX,
false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL));
114 lockedLists.add(
"Email Addresses");
115 addList(
"Email Addresses", emails,
true,
false,
true);
118 List<Keyword> urls =
new ArrayList<>();
119 urls.add(
new Keyword(URL_REGEX,
false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL));
120 lockedLists.add(
"URLs");
121 addList(
"URLs", urls,
false,
false,
true);
124 List<Keyword> ccns =
new ArrayList<>();
125 ccns.add(
new Keyword(CCN_REGEX,
false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER));
126 lockedLists.add(
"Credit Card Numbers");
127 addList(
"Credit Card Numbers", ccns,
false,
false,
true);
133 public void reload() {
134 boolean created =
false;
142 List<String> toClear =
new ArrayList<>();
143 for (String list : theLists.keySet()) {
144 if (theLists.get(list).isEditable() ==
false) {
148 for (String clearList : toClear) {
149 theLists.remove(clearList);
152 if (!listFileExists()) {
159 if (!load() && !created) {
165 public List<KeywordList> getListsL() {
166 List<KeywordList> ret =
new ArrayList<>();
167 for (KeywordList list : theLists.values()) {
173 public List<KeywordList> getListsL(
boolean locked) {
174 List<KeywordList> ret =
new ArrayList<>();
175 for (KeywordList list : theLists.values()) {
176 if (list.isEditable().equals(locked)) {
188 public List<String> getListNames() {
189 return new ArrayList<>(theLists.keySet());
199 public List<String> getListNames(
boolean locked) {
200 ArrayList<String> lists =
new ArrayList<>();
201 for (String listName : theLists.keySet()) {
202 KeywordList list = theLists.get(listName);
203 if (locked == list.isEditable()) {
218 public KeywordList getListWithKeyword(String keyword) {
219 KeywordList found = null;
220 for (KeywordList list : theLists.values()) {
221 if (list.hasSearchTerm(keyword)) {
234 int getNumberLists() {
235 return theLists.size();
245 public int getNumberLists(
boolean locked) {
247 for (String listName : theLists.keySet()) {
248 KeywordList list = theLists.get(listName);
249 if (locked == list.isEditable()) {
263 public KeywordList getList(String name) {
264 return theLists.get(name);
274 boolean listExists(String name) {
275 return getList(name) != null;
288 boolean addList(String name, List<Keyword> newList,
boolean useForIngest,
boolean ingestMessages,
boolean locked) {
289 boolean replaced =
false;
290 KeywordList curList = getList(name);
291 final Date now =
new Date();
293 if (curList == null) {
294 theLists.put(name,
new KeywordList(name, now, now, useForIngest, ingestMessages, newList, locked));
296 changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, name);
297 }
catch (Exception e) {
298 LOGGER.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
299 MessageNotifyUtil.Notify.show(
300 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.moduleErr"),
301 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.addList.errMsg1.msg"),
302 MessageNotifyUtil.MessageType.ERROR);
305 theLists.put(name,
new KeywordList(name, curList.getDateCreated(), now, useForIngest, ingestMessages, newList, locked));
309 changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, name);
310 }
catch (Exception e) {
311 LOGGER.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
312 MessageNotifyUtil.Notify.show(
313 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.moduleErr"),
314 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.addList.errMsg2.msg"),
315 MessageNotifyUtil.MessageType.ERROR);
322 boolean addList(String name, List<Keyword> newList,
boolean useForIngest,
boolean ingestMessages) {
324 boolean isLocked = this.lockedLists.contains(name);
325 return addList(name, newList, useForIngest, ingestMessages, isLocked);
328 boolean addList(String name, List<Keyword> newList) {
329 return addList(name, newList,
true,
true);
332 boolean addList(KeywordList list) {
333 return addList(list.getName(), list.getKeywords(), list.getUseForIngest(), list.getIngestMessages(), list.isEditable());
343 boolean saveLists(List<KeywordList> lists) {
344 List<KeywordList> overwritten =
new ArrayList<>();
345 List<KeywordList> newLists =
new ArrayList<>();
346 for (KeywordList list : lists) {
347 if (this.listExists(list.getName())) {
348 overwritten.add(list);
352 theLists.put(list.getName(), list);
354 boolean saved = save(
true);
356 for (KeywordList list : newLists) {
358 changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
359 }
catch (Exception e) {
360 LOGGER.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
361 MessageNotifyUtil.Notify.show(
362 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.moduleErr"),
363 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.saveList.errMsg1.msg"),
364 MessageNotifyUtil.MessageType.ERROR);
367 for (KeywordList over : overwritten) {
369 changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
370 }
catch (Exception e) {
371 LOGGER.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
372 MessageNotifyUtil.Notify.show(
373 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.moduleErr"),
374 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.saveList.errMsg2.msg"),
375 MessageNotifyUtil.MessageType.ERROR);
390 boolean writeLists(List<KeywordList> lists) {
391 List<KeywordList> overwritten =
new ArrayList<>();
392 List<KeywordList> newLists =
new ArrayList<>();
393 for (KeywordList list : lists) {
394 if (this.listExists(list.getName())) {
395 overwritten.add(list);
399 theLists.put(list.getName(), list);
402 for (KeywordList list : newLists) {
405 changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
406 }
catch (Exception e) {
407 LOGGER.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
408 MessageNotifyUtil.Notify.show(
409 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.moduleErr"),
410 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.writeLists.errMsg1.msg"),
411 MessageNotifyUtil.MessageType.ERROR);
415 for (KeywordList over : overwritten) {
418 changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
419 }
catch (Exception e) {
420 LOGGER.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
421 MessageNotifyUtil.Notify.show(
422 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.moduleErr"),
423 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.writeLists.errMsg2.msg"),
424 MessageNotifyUtil.MessageType.ERROR);
438 boolean deleteList(String name) {
439 KeywordList delList = getList(name);
440 if (delList != null && !delList.isEditable()) {
441 theLists.remove(name);
445 changeSupport.firePropertyChange(ListsEvt.LIST_DELETED.toString(), null, name);
446 }
catch (Exception e) {
447 LOGGER.log(Level.SEVERE,
"KeywordSearchListsAbstract listener threw exception", e);
448 MessageNotifyUtil.Notify.show(
449 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.moduleErr"),
450 NbBundle.getMessage(
this.getClass(),
"KeywordSearchListsAbstract.deleteList.errMsg1.msg"),
451 MessageNotifyUtil.MessageType.ERROR);
460 public abstract boolean save();
468 public abstract boolean save(
boolean isExport);
473 public abstract boolean load();
475 private boolean listFileExists() {
476 File f =
new File(filePath);
477 return f.exists() && f.canRead() && f.canWrite();
480 public void setUseForIngest(String key,
boolean flag) {
481 theLists.get(key).setUseForIngest(flag);