Autopsy  4.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-2016 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 import java.util.logging.Level;
30 import org.openide.util.NbBundle;
33 import org.sleuthkit.datamodel.BlackboardAttribute;
34 
38 abstract class KeywordSearchList {
39 
40  protected static final Logger LOGGER = Logger.getLogger(KeywordSearchList.class.getName());
41 
42  private static final String PHONE_NUMBER_REGEX = "[(]{0,1}\\d\\d\\d[)]{0,1}[\\.-]\\d\\d\\d[\\.-]\\d\\d\\d\\d"; //NON-NLS
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])"; //NON-NLS
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)"; //NON-NLS
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\\.\\,\\;\\?\\'\\\\+&amp;%\\$#\\=~_\\-]+))*"; //NON-NLS
46  private static final String CCN_REGEX = ".*[3456]([ -]?\\d){11,18}.*"; //12-19 digits, with possible single spaces or dashes in between. first digit is 3,4,5, or 6 //NON-NLS
47 
48  protected String filePath;
49  Map<String, KeywordList> theLists; //the keyword data
50 
51  PropertyChangeSupport changeSupport;
52  protected List<String> lockedLists;
53 
54  KeywordSearchList(String filePath) {
55  this.filePath = filePath;
56  theLists = new LinkedHashMap<>();
57  lockedLists = new ArrayList<>();
58  changeSupport = new PropertyChangeSupport(this);
59  }
60 
66  enum ListsEvt {
67 
68  LIST_ADDED,
69  LIST_DELETED,
70  LIST_UPDATED
71  };
72 
73  enum LanguagesEvent {
74 
75  LANGUAGES_CHANGED,
76  ENCODINGS_CHANGED
77  }
78 
79  void fireLanguagesEvent(LanguagesEvent event) {
80  try {
81  changeSupport.firePropertyChange(event.toString(), null, null);
82  } catch (Exception e) {
83  LOGGER.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
84  }
85  }
86 
87  public void addPropertyChangeListener(PropertyChangeListener listener) {
88  changeSupport.addPropertyChangeListener(listener);
89  }
90 
91  public void removePropertyChangeListener(PropertyChangeListener listener) {
92  changeSupport.removePropertyChangeListener(listener);
93  }
94 
95  private void prepopulateLists() {
96  if (!theLists.isEmpty()) {
97  return;
98  }
99  //phone number
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);
104 
105  //IP address
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);
110 
111  //email
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);
116 
117  //URL
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);
122 
123  //CCN
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);
128  }
129 
133  public void reload() {
134  boolean created = false;
135 
136  //theLists.clear();
137  //populate only the first time
138  prepopulateLists();
139 
140  //reset all the lists other than locked lists (we don't save them to XML)
141  //we want to preserve state of locked lists
142  List<String> toClear = new ArrayList<>();
143  for (String list : theLists.keySet()) {
144  if (theLists.get(list).isEditable() == false) {
145  toClear.add(list);
146  }
147  }
148  for (String clearList : toClear) {
149  theLists.remove(clearList);
150  }
151 
152  if (!listFileExists()) {
153  //create new if it doesn't exist
154  save();
155  created = true;
156  }
157 
158  //load, if fails to load create new
159  if (!load() && !created) {
160  //create new if failed to load
161  save();
162  }
163  }
164 
165  public List<KeywordList> getListsL() {
166  List<KeywordList> ret = new ArrayList<>();
167  for (KeywordList list : theLists.values()) {
168  ret.add(list);
169  }
170  return ret;
171  }
172 
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)) {
177  ret.add(list);
178  }
179  }
180  return ret;
181  }
182 
188  public List<String> getListNames() {
189  return new ArrayList<>(theLists.keySet());
190  }
191 
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()) {
204  lists.add(listName);
205  }
206  }
207 
208  return lists;
209  }
210 
218  public KeywordList getListWithKeyword(String keyword) {
219  KeywordList found = null;
220  for (KeywordList list : theLists.values()) {
221  if (list.hasSearchTerm(keyword)) {
222  found = list;
223  break;
224  }
225  }
226  return found;
227  }
228 
234  int getNumberLists() {
235  return theLists.size();
236  }
237 
245  public int getNumberLists(boolean locked) {
246  int numLists = 0;
247  for (String listName : theLists.keySet()) {
248  KeywordList list = theLists.get(listName);
249  if (locked == list.isEditable()) {
250  ++numLists;
251  }
252  }
253  return numLists;
254  }
255 
263  public KeywordList getList(String name) {
264  return theLists.get(name);
265  }
266 
274  boolean listExists(String name) {
275  return getList(name) != null;
276  }
277 
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();
292 
293  if (curList == null) {
294  theLists.put(name, new KeywordList(name, now, now, useForIngest, ingestMessages, newList, locked));
295  try {
296  changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, name);
297  } catch (Exception e) {
298  LOGGER.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
299  MessageNotifyUtil.Notify.show(
300  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.moduleErr"),
301  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.addList.errMsg1.msg"),
302  MessageNotifyUtil.MessageType.ERROR);
303  }
304  } else {
305  theLists.put(name, new KeywordList(name, curList.getDateCreated(), now, useForIngest, ingestMessages, newList, locked));
306  replaced = true;
307 
308  try {
309  changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, name);
310  } catch (Exception e) {
311  LOGGER.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
312  MessageNotifyUtil.Notify.show(
313  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.moduleErr"),
314  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.addList.errMsg2.msg"),
315  MessageNotifyUtil.MessageType.ERROR);
316  }
317  }
318 
319  return replaced;
320  }
321 
322  boolean addList(String name, List<Keyword> newList, boolean useForIngest, boolean ingestMessages) {
323  //make sure that the list is readded as a locked/built in list
324  boolean isLocked = this.lockedLists.contains(name);
325  return addList(name, newList, useForIngest, ingestMessages, isLocked);
326  }
327 
328  boolean addList(String name, List<Keyword> newList) {
329  return addList(name, newList, true, true);
330  }
331 
332  boolean addList(KeywordList list) {
333  return addList(list.getName(), list.getKeywords(), list.getUseForIngest(), list.getIngestMessages(), list.isEditable());
334  }
335 
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);
349  } else {
350  newLists.add(list);
351  }
352  theLists.put(list.getName(), list);
353  }
354  boolean saved = save(true);
355  if (saved) {
356  for (KeywordList list : newLists) {
357  try {
358  changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
359  } catch (Exception e) {
360  LOGGER.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
361  MessageNotifyUtil.Notify.show(
362  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.moduleErr"),
363  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.saveList.errMsg1.msg"),
364  MessageNotifyUtil.MessageType.ERROR);
365  }
366  }
367  for (KeywordList over : overwritten) {
368  try {
369  changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
370  } catch (Exception e) {
371  LOGGER.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
372  MessageNotifyUtil.Notify.show(
373  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.moduleErr"),
374  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.saveList.errMsg2.msg"),
375  MessageNotifyUtil.MessageType.ERROR);
376  }
377  }
378  }
379 
380  return saved;
381  }
382 
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);
396  } else {
397  newLists.add(list);
398  }
399  theLists.put(list.getName(), list);
400  }
401 
402  for (KeywordList list : newLists) {
403 
404  try {
405  changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
406  } catch (Exception e) {
407  LOGGER.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
408  MessageNotifyUtil.Notify.show(
409  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.moduleErr"),
410  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.writeLists.errMsg1.msg"),
411  MessageNotifyUtil.MessageType.ERROR);
412  }
413  }
414 
415  for (KeywordList over : overwritten) {
416 
417  try {
418  changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
419  } catch (Exception e) {
420  LOGGER.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
421  MessageNotifyUtil.Notify.show(
422  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.moduleErr"),
423  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.writeLists.errMsg2.msg"),
424  MessageNotifyUtil.MessageType.ERROR);
425  }
426  }
427 
428  return true;
429  }
430 
438  boolean deleteList(String name) {
439  KeywordList delList = getList(name);
440  if (delList != null && !delList.isEditable()) {
441  theLists.remove(name);
442  }
443 
444  try {
445  changeSupport.firePropertyChange(ListsEvt.LIST_DELETED.toString(), null, name);
446  } catch (Exception e) {
447  LOGGER.log(Level.SEVERE, "KeywordSearchListsAbstract listener threw exception", e); //NON-NLS
448  MessageNotifyUtil.Notify.show(
449  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.moduleErr"),
450  NbBundle.getMessage(this.getClass(), "KeywordSearchListsAbstract.deleteList.errMsg1.msg"),
451  MessageNotifyUtil.MessageType.ERROR);
452  }
453 
454  return true;
455  }
456 
460  public abstract boolean save();
461 
468  public abstract boolean save(boolean isExport);
469 
473  public abstract boolean load();
474 
475  private boolean listFileExists() {
476  File f = new File(filePath);
477  return f.exists() && f.canRead() && f.canWrite();
478  }
479 
480  public void setUseForIngest(String key, boolean flag) {
481  theLists.get(key).setUseForIngest(flag);
482  }
483 }

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