Autopsy  4.6.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
IngestEventsListener.java
Go to the documentation of this file.
1 /*
2  * Central Repository
3  *
4  * Copyright 2015-2018 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.centralrepository.eventlisteners;
20 
21 import com.google.common.util.concurrent.ThreadFactoryBuilder;
22 import java.beans.PropertyChangeEvent;
23 import java.beans.PropertyChangeListener;
24 import static java.lang.Boolean.FALSE;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.LinkedHashSet;
28 import java.util.List;
29 import java.util.concurrent.ExecutorService;
30 import java.util.concurrent.Executors;
31 import java.util.logging.Level;
32 import java.util.stream.Collectors;
33 import org.openide.util.NbBundle;
44 import org.sleuthkit.datamodel.AbstractFile;
45 import org.sleuthkit.datamodel.BlackboardArtifact;
46 import org.sleuthkit.datamodel.BlackboardAttribute;
47 import org.sleuthkit.datamodel.TskCoreException;
50 
55 public class IngestEventsListener {
56 
57  private static final Logger LOGGER = Logger.getLogger(CorrelationAttribute.class.getName());
58 
59  final Collection<String> recentlyAddedCeArtifacts = new LinkedHashSet<>();
60  private static int correlationModuleInstanceCount;
61  private static boolean flagNotableItems;
62  private final ExecutorService jobProcessingExecutor;
63  private static final String INGEST_EVENT_THREAD_NAME = "Ingest-Event-Listener-%d";
64  private final PropertyChangeListener pcl1 = new IngestModuleEventListener();
65  private final PropertyChangeListener pcl2 = new IngestJobEventListener();
66 
68  jobProcessingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(INGEST_EVENT_THREAD_NAME).build());
69  }
70 
71  void shutdown() {
72  ThreadUtils.shutDownTaskExecutor(jobProcessingExecutor);
73  }
74 
75  /*
76  * Add all of our Ingest Event Listeners to the IngestManager Instance.
77  */
78  public void installListeners() {
81  }
82 
83  /*
84  * Remove all of our Ingest Event Listeners from the IngestManager Instance.
85  */
86  public void uninstallListeners() {
89  }
90 
95  public synchronized static void incrementCorrelationEngineModuleCount() {
96  correlationModuleInstanceCount++; //Should be called once in the Correlation Engine module's startup method.
97  }
98 
103  public synchronized static void decrementCorrelationEngineModuleCount() {
104  if (getCeModuleInstanceCount() > 0) { //prevent it ingestJobCounter from going negative
105  correlationModuleInstanceCount--; //Should be called once in the Correlation Engine module's shutdown method.
106  }
107  }
108 
113  synchronized static void resetCeModuleInstanceCount() {
114  correlationModuleInstanceCount = 0; //called when a case is opened in case for some reason counter was not reset
115  }
116 
123  public synchronized static int getCeModuleInstanceCount() {
125  }
126 
132  public synchronized static boolean isFlagNotableItems() {
133  return flagNotableItems;
134  }
135 
141  public synchronized static void setFlagNotableItems(boolean value) {
142  flagNotableItems = value;
143  }
144 
145  @NbBundle.Messages({"IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository)",
146  "IngestEventsListener.prevCaseComment.text=Previous Case: ",
147  "IngestEventsListener.ingestmodule.name=Correlation Engine"})
148  static private void postCorrelatedBadArtifactToBlackboard(BlackboardArtifact bbArtifact, List<String> caseDisplayNames) {
149 
150  try {
151  AbstractFile af = bbArtifact.getSleuthkitCase().getAbstractFileById(bbArtifact.getObjectID());
152  Collection<BlackboardAttribute> attributes = new ArrayList<>();
153  String MODULE_NAME = Bundle.IngestEventsListener_ingestmodule_name();
154  BlackboardArtifact tifArtifact = af.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT);
155  BlackboardAttribute att = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME,
156  Bundle.IngestEventsListener_prevTaggedSet_text());
157  BlackboardAttribute att2 = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, MODULE_NAME,
158  Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",", "", "")));
159  attributes.add(att);
160  attributes.add(att2);
161  attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, bbArtifact.getArtifactID()));
162 
163  tifArtifact.addAttributes(attributes);
164  try {
165  // index the artifact for keyword search
167  blackboard.indexArtifact(tifArtifact);
169  LOGGER.log(Level.SEVERE, "Unable to index blackboard artifact " + tifArtifact.getArtifactID(), ex); //NON-NLS
170  }
171 
172  // fire event to notify UI of this new artifact
173  IngestServices.getInstance().fireModuleDataEvent(new ModuleDataEvent(MODULE_NAME, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT));
174  } catch (TskCoreException ex) {
175  LOGGER.log(Level.SEVERE, "Failed to create BlackboardArtifact.", ex); // NON-NLS
176  } catch (IllegalStateException ex) {
177  LOGGER.log(Level.SEVERE, "Failed to create BlackboardAttribute.", ex); // NON-NLS
178  }
179  }
180 
181  private class IngestModuleEventListener implements PropertyChangeListener {
182 
183  @Override
184  public void propertyChange(PropertyChangeEvent evt) {
185  if (getCeModuleInstanceCount() > 0) {
186  EamDb dbManager;
187  try {
188  dbManager = EamDb.getInstance();
189  } catch (EamDbException ex) {
190  LOGGER.log(Level.SEVERE, "Failed to connect to Central Repository database.", ex);
191  return;
192  }
193  switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) {
194  case DATA_ADDED: {
195  jobProcessingExecutor.submit(new DataAddedTask(dbManager, evt, isFlagNotableItems()));
196  break;
197  }
198  }
199  }
200  }
201  }
202 
203  private class IngestJobEventListener implements PropertyChangeListener {
204 
205  @Override
206  public void propertyChange(PropertyChangeEvent evt) {
207  switch (IngestManager.IngestJobEvent.valueOf(evt.getPropertyName())) {
208  case DATA_SOURCE_ANALYSIS_COMPLETED: {
209  jobProcessingExecutor.submit(new AnalysisCompleteTask());
210  break;
211  }
212  }
213  }
214 
215  }
216 
217  private final class AnalysisCompleteTask implements Runnable {
218 
219  @Override
220  public void run() {
221  // clear the tracker to reduce memory usage
222  if (getCeModuleInstanceCount() == 0) {
223  recentlyAddedCeArtifacts.clear();
224  }
225  //else another instance of the Correlation Engine Module is still being run.
226  } // DATA_SOURCE_ANALYSIS_COMPLETED
227  }
228 
229  private final class DataAddedTask implements Runnable {
230 
231  private final EamDb dbManager;
232  private final PropertyChangeEvent event;
233  private final boolean flagNotableItemsEnabled;
234 
235  private DataAddedTask(EamDb db, PropertyChangeEvent evt, boolean flagNotableItemsEnabled) {
236  dbManager = db;
237  event = evt;
238  this.flagNotableItemsEnabled = flagNotableItemsEnabled;
239  }
240 
241  @Override
242  public void run() {
243  if (!EamDb.isEnabled()) {
244  return;
245  }
246  final ModuleDataEvent mde = (ModuleDataEvent) event.getOldValue();
247  Collection<BlackboardArtifact> bbArtifacts = mde.getArtifacts();
248  if (null == bbArtifacts) { //the ModuleDataEvents don't always have a collection of artifacts set
249  return;
250  }
251  List<CorrelationAttribute> eamArtifacts = new ArrayList<>();
252 
253  for (BlackboardArtifact bbArtifact : bbArtifacts) {
254  // eamArtifact will be null OR a EamArtifact containing one EamArtifactInstance.
255  List<CorrelationAttribute> convertedArtifacts = EamArtifactUtil.getCorrelationAttributeFromBlackboardArtifact(bbArtifact, true, true);
256  for (CorrelationAttribute eamArtifact : convertedArtifacts) {
257  try {
258  // Only do something with this artifact if it's unique within the job
259  if (recentlyAddedCeArtifacts.add(eamArtifact.toString())) {
260  // Was it previously marked as bad?
261  // query db for artifact instances having this TYPE/VALUE and knownStatus = "Bad".
262  // if gettKnownStatus() is "Unknown" and this artifact instance was marked bad in a previous case,
263  // create TSK_INTERESTING_ARTIFACT_HIT artifact on BB.
264  if (flagNotableItemsEnabled) {
265  List<String> caseDisplayNames = dbManager.getListCasesHavingArtifactInstancesKnownBad(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue());
266  if (!caseDisplayNames.isEmpty()) {
268  caseDisplayNames);
269  }
270  }
271  eamArtifacts.add(eamArtifact);
272  }
273  } catch (EamDbException ex) {
274  LOGGER.log(Level.SEVERE, "Error counting notable artifacts.", ex);
275  }
276  }
277  }
278  if (FALSE == eamArtifacts.isEmpty()) {
279  try {
280  for (CorrelationAttribute eamArtifact : eamArtifacts) {
281  dbManager.addArtifact(eamArtifact);
282  }
283  } catch (EamDbException ex) {
284  LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); //NON-NLS
285  }
286  } // DATA_ADDED
287  }
288  }
289 }
Collection< BlackboardArtifact > getArtifacts()
void removeIngestModuleEventListener(final PropertyChangeListener listener)
static synchronized IngestManager getInstance()
List< String > getListCasesHavingArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value)
void addArtifact(CorrelationAttribute eamArtifact)
void removeIngestJobEventListener(final PropertyChangeListener listener)
static void shutDownTaskExecutor(ExecutorService executor)
void addIngestJobEventListener(final PropertyChangeListener listener)
DataAddedTask(EamDb db, PropertyChangeEvent evt, boolean flagNotableItemsEnabled)
void fireModuleDataEvent(ModuleDataEvent moduleDataEvent)
void addIngestModuleEventListener(final PropertyChangeListener listener)
synchronized void indexArtifact(BlackboardArtifact artifact)
Definition: Blackboard.java:59
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static void postCorrelatedBadArtifactToBlackboard(BlackboardArtifact bbArtifact, List< String > caseDisplayNames)
static List< CorrelationAttribute > getCorrelationAttributeFromBlackboardArtifact(BlackboardArtifact bbArtifact, boolean addInstanceDetails, boolean checkEnabled)
static synchronized IngestServices getInstance()

Copyright © 2012-2016 Basis Technology. Generated on: Mon May 7 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.