Autopsy  3.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
KeywordSearchList.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2014 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.keywordsearch;
20 
21 import java.beans.PropertyChangeListener;
22 import java.beans.PropertyChangeSupport;
23 import java.io.File;
24 import java.util.ArrayList;
25 import java.util.Date;
26 import java.util.LinkedHashMap;
27 import java.util.List;
28 import java.util.Map;
29 
30 import org.openide.util.NbBundle;
34 import java.util.logging.Level;
35 
39 abstract class KeywordSearchList {
40 
41  protected String filePath;
42  Map<String, KeywordList> theLists; //the keyword data
43  protected static final Logger logger = Logger.getLogger(KeywordSearchList.class.getName());
44  PropertyChangeSupport changeSupport;
45  protected List<String> lockedLists;
46 
47  KeywordSearchList(String filePath) {
48  this.filePath = filePath;
49  theLists = new LinkedHashMap<>();
50  lockedLists = new ArrayList<>();
51  changeSupport = new PropertyChangeSupport(this);
52  }
53 
59  enum ListsEvt {
60 
61  LIST_ADDED, LIST_DELETED, LIST_UPDATED
62  };
63 
64  enum LanguagesEvent {
65  LANGUAGES_CHANGED, ENCODINGS_CHANGED
66  }
67 
68  void fireLanguagesEvent(LanguagesEvent event) {
69  try {
70  changeSupport.firePropertyChange(event.toString(), null, null);
71  } catch (Exception e) {
72  logger.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
73  }
74  }
75 
76  public void addPropertyChangeListener(PropertyChangeListener listener) {
77  changeSupport.addPropertyChangeListener(listener);
78  }
79 
80  public void removePropertyChangeListener(PropertyChangeListener listener) {
81  changeSupport.removePropertyChangeListener(listener);
82  }
83 
84  private void prepopulateLists() {
85  if (!theLists.isEmpty()) {
86  return;
87  }
88  //phone number
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)); //NON-NLS
91  //phones.add(new Keyword("\\d{8,10}", false));
92  //IP address
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));
95  //email
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)", //NON-NLS
98  false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL));
99  //emails.add(new Keyword("[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}",
100  // false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL));
101  //URL
102  List<Keyword> urls = new ArrayList<>();
103  //urls.add(new Keyword("http://|https://|^www\\.", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL));
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\\.\\,\\;\\?\\'\\\\+&amp;%\\$#\\=~_\\-]+))*", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)); //NON-NLS
105 
106  //urls.add(new Keyword("ssh://", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL));
107 
108  //disable messages for harcoded/locked lists
109  String name;
110 
111  name = "Phone Numbers"; //NON-NLS
112  lockedLists.add(name);
113  addList(name, phones, false, false, true);
114 
115  name = "IP Addresses"; //NON-NLS
116  lockedLists.add(name);
117  addList(name, ips, false, false, true);
118 
119  name = "Email Addresses"; //NON-NLS
120  lockedLists.add(name);
121  addList(name, emails, true, false, true);
122 
123  name = "URLs"; //NON-NLS
124  lockedLists.add(name);
125  addList(name, urls, false, false, true);
126  }
127 
131  public void reload() {
132  boolean created = false;
133 
134  //theLists.clear();
135  //populate only the first time
136  prepopulateLists();
137 
138  //reset all the lists other than locked lists (we don't save them to XML)
139  //we want to preserve state of locked lists
140  List<String> toClear = new ArrayList<>();
141  for (String list : theLists.keySet()) {
142  if (theLists.get(list).isLocked() == false) {
143  toClear.add(list);
144  }
145  }
146  for (String clearList : toClear) {
147  theLists.remove(clearList);
148  }
149 
150  if (!listFileExists()) {
151  //create new if it doesn't exist
152  save();
153  created = true;
154  }
155 
156  //load, if fails to load create new
157  if (!load() && !created) {
158  //create new if failed to load
159  save();
160  }
161  }
162 
163  public List<KeywordList> getListsL() {
164  List<KeywordList> ret = new ArrayList<>();
165  for (KeywordList list : theLists.values()) {
166  ret.add(list);
167  }
168  return ret;
169  }
170 
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)) {
175  ret.add(list);
176  }
177  }
178  return ret;
179  }
180 
186  public List<String> getListNames() {
187  return new ArrayList<>(theLists.keySet());
188  }
189 
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()) {
201  lists.add(listName);
202  }
203  }
204 
205  return lists;
206  }
207 
214  public KeywordList getListWithKeyword(String keyword) {
215  KeywordList found = null;
216  for (KeywordList list : theLists.values()) {
217  if (list.hasKeyword(keyword)) {
218  found = list;
219  break;
220  }
221  }
222  return found;
223  }
224 
230  int getNumberLists() {
231  return theLists.size();
232  }
233 
240  public int getNumberLists(boolean locked) {
241  int numLists = 0;
242  for (String listName : theLists.keySet()) {
243  KeywordList list = theLists.get(listName);
244  if (locked == list.isLocked()) {
245  ++numLists;
246  }
247  }
248  return numLists;
249  }
250 
257  public KeywordList getList(String name) {
258  return theLists.get(name);
259  }
260 
267  boolean listExists(String name) {
268  return getList(name) != null;
269  }
270 
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();
284 
285  if (curList == null) {
286  theLists.put(name, new KeywordList(name, now, now, useForIngest, ingestMessages, newList, locked));
287  try {
288  changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, name);
289  } catch (Exception e) {
290  logger.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
291  MessageNotifyUtil.Notify.show(
292  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.moduleErr"),
293  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.addList.errMsg1.msg"),
294  MessageNotifyUtil.MessageType.ERROR);
295  }
296  } else {
297  theLists.put(name, new KeywordList(name, curList.getDateCreated(), now, useForIngest, ingestMessages, newList, locked));
298  replaced = true;
299 
300  try {
301  changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, name);
302  } catch (Exception e) {
303  logger.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
304  MessageNotifyUtil.Notify.show(
305  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.moduleErr"),
306  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.addList.errMsg2.msg"),
307  MessageNotifyUtil.MessageType.ERROR);
308  }
309  }
310 
311  return replaced;
312  }
313 
314  boolean addList(String name, List<Keyword> newList, boolean useForIngest, boolean ingestMessages) {
315  //make sure that the list is readded as a locked/built in list
316  boolean isLocked = this.lockedLists.contains(name);
317  return addList(name, newList, useForIngest, ingestMessages, isLocked);
318  }
319 
320  boolean addList(String name, List<Keyword> newList) {
321  return addList(name, newList, true, true);
322  }
323 
324  boolean addList(KeywordList list) {
325  return addList(list.getName(), list.getKeywords(), list.getUseForIngest(), list.getIngestMessages(), list.isLocked());
326  }
327 
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);
340  } else {
341  newLists.add(list);
342  }
343  theLists.put(list.getName(), list);
344  }
345  boolean saved = save(true);
346  if (saved) {
347  for (KeywordList list : newLists) {
348  try {
349  changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
350  } catch (Exception e) {
351  logger.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
352  MessageNotifyUtil.Notify.show(
353  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.moduleErr"),
354  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.saveList.errMsg1.msg"),
355  MessageNotifyUtil.MessageType.ERROR);
356  }
357  }
358  for (KeywordList over : overwritten) {
359  try {
360  changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
361  } catch (Exception e) {
362  logger.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
363  MessageNotifyUtil.Notify.show(
364  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.moduleErr"),
365  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.saveList.errMsg2.msg"),
366  MessageNotifyUtil.MessageType.ERROR);
367  }
368  }
369  }
370 
371  return saved;
372  }
373 
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);
386  } else {
387  newLists.add(list);
388  }
389  theLists.put(list.getName(), list);
390  }
391 
392  for (KeywordList list : newLists) {
393 
394  try {
395  changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
396  } catch (Exception e) {
397  logger.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
398  MessageNotifyUtil.Notify.show(
399  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.moduleErr"),
400  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.writeLists.errMsg1.msg"),
401  MessageNotifyUtil.MessageType.ERROR);
402  }
403  }
404 
405  for (KeywordList over : overwritten) {
406 
407  try {
408  changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
409  } catch (Exception e) {
410  logger.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
411  MessageNotifyUtil.Notify.show(
412  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.moduleErr"),
413  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.writeLists.errMsg2.msg"),
414  MessageNotifyUtil.MessageType.ERROR);
415  }
416  }
417 
418  return true;
419  }
420 
427  boolean deleteList(String name) {
428  KeywordList delList = getList(name);
429  if (delList != null && !delList.isLocked()) {
430  theLists.remove(name);
431  }
432 
433  try {
434  changeSupport.firePropertyChange(ListsEvt.LIST_DELETED.toString(), null, name);
435  } catch (Exception e) {
436  logger.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
437  MessageNotifyUtil.Notify.show(
438  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.moduleErr"),
439  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.deleteList.errMsg1.msg"),
440  MessageNotifyUtil.MessageType.ERROR);
441  }
442 
443  return true;
444  }
445 
449  public abstract boolean save();
450 
457  public abstract boolean save(boolean isExport);
458 
462  public abstract boolean load();
463 
464  private boolean listFileExists() {
465  File f = new File(filePath);
466  return f.exists() && f.canRead() && f.canWrite();
467  }
468 
469  public void setUseForIngest(String key, boolean flag) {
470  theLists.get(key).setUseForIngest(flag);
471  }
472 }

Copyright © 2012-2015 Basis Technology. Generated on: Mon Oct 19 2015
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.