Autopsy  4.5.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-2017 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;
43 import org.sleuthkit.datamodel.AbstractFile;
44 import org.sleuthkit.datamodel.BlackboardArtifact;
45 import org.sleuthkit.datamodel.BlackboardAttribute;
46 import org.sleuthkit.datamodel.TskCoreException;
49 
54 public class IngestEventsListener {
55 
56  private static final Logger LOGGER = Logger.getLogger(CorrelationAttribute.class.getName());
57 
58  final Collection<String> recentlyAddedCeArtifacts = new LinkedHashSet<>();
59  private static int ceModuleInstanceCount = 0;
60  private final ExecutorService jobProcessingExecutor;
61  private static final String INGEST_EVENT_THREAD_NAME = "Ingest-Event-Listener-%d";
62  private final PropertyChangeListener pcl1 = new IngestModuleEventListener();
63  private final PropertyChangeListener pcl2 = new IngestJobEventListener();
64 
66  jobProcessingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(INGEST_EVENT_THREAD_NAME).build());
67  }
68 
69  void shutdown() {
70  ThreadUtils.shutDownTaskExecutor(jobProcessingExecutor);
71  }
72 
73  /*
74  * Add all of our Ingest Event Listeners to the IngestManager Instance.
75  */
76  public void installListeners() {
79  }
80 
81  /*
82  * Remove all of our Ingest Event Listeners from the IngestManager Instance.
83  */
84  public void uninstallListeners() {
87  }
88 
94  public synchronized static void incrementCorrelationEngineModuleCount() {
95  ceModuleInstanceCount++; //Should be called once in the Correlation Engine module's startup method.
96  }
97 
102  public synchronized static void decrementCorrelationEngineModuleCount() {
103  if (getCeModuleInstanceCount() > 0) { //prevent it ingestJobCounter from going negative
104  ceModuleInstanceCount--; //Should be called once in the Correlation Engine module's shutdown method.
105  }
106  }
107 
112  synchronized static void resetCeModuleInstanceCount() {
113  ceModuleInstanceCount = 0; //called when a case is opened in case for some reason counter was not reset
114  }
115 
122  private synchronized static int getCeModuleInstanceCount() {
123  return ceModuleInstanceCount;
124  }
125 
126  @NbBundle.Messages({"IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository)",
127  "IngestEventsListener.prevCaseComment.text=Previous Case: ",
128  "IngestEventsListener.ingestmodule.name=Correlation Engine"})
129  static private void postCorrelatedBadArtifactToBlackboard(BlackboardArtifact bbArtifact, List<String> caseDisplayNames) {
130 
131  try {
132  AbstractFile af = bbArtifact.getSleuthkitCase().getAbstractFileById(bbArtifact.getObjectID());
133  Collection<BlackboardAttribute> attributes = new ArrayList<>();
134  String MODULE_NAME = Bundle.IngestEventsListener_ingestmodule_name();
135  BlackboardArtifact tifArtifact = af.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT);
136  BlackboardAttribute att = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME,
137  Bundle.IngestEventsListener_prevTaggedSet_text());
138  BlackboardAttribute att2 = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, MODULE_NAME,
139  Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",", "", "")));
140  attributes.add(att);
141  attributes.add(att2);
142  attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, bbArtifact.getArtifactID()));
143 
144  tifArtifact.addAttributes(attributes);
145  try {
146  // index the artifact for keyword search
148  blackboard.indexArtifact(tifArtifact);
149  } catch (Blackboard.BlackboardException ex) {
150  LOGGER.log(Level.SEVERE, "Unable to index blackboard artifact " + tifArtifact.getArtifactID(), ex); //NON-NLS
151  }
152 
153  // fire event to notify UI of this new artifact
154  IngestServices.getInstance().fireModuleDataEvent(new ModuleDataEvent(MODULE_NAME, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT));
155  } catch (TskCoreException ex) {
156  LOGGER.log(Level.SEVERE, "Failed to create BlackboardArtifact.", ex); // NON-NLS
157  } catch (IllegalStateException ex) {
158  LOGGER.log(Level.SEVERE, "Failed to create BlackboardAttribute.", ex); // NON-NLS
159  }
160  }
161 
162  private class IngestModuleEventListener implements PropertyChangeListener {
163 
164  @Override
165  public void propertyChange(PropertyChangeEvent evt) {
166  if (getCeModuleInstanceCount() > 0) {
167  EamDb dbManager;
168  try {
169  dbManager = EamDb.getInstance();
170  } catch (EamDbException ex) {
171  LOGGER.log(Level.SEVERE, "Failed to connect to Central Repository database.", ex);
172  return;
173  }
174  switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) {
175  case DATA_ADDED: {
176  jobProcessingExecutor.submit(new DataAddedTask(dbManager, evt));
177  break;
178  }
179  }
180  }
181  }
182  }
183 
184  private class IngestJobEventListener implements PropertyChangeListener {
185 
186  @Override
187  public void propertyChange(PropertyChangeEvent evt) {
188  switch (IngestManager.IngestJobEvent.valueOf(evt.getPropertyName())) {
189  case DATA_SOURCE_ANALYSIS_COMPLETED: {
190  jobProcessingExecutor.submit(new AnalysisCompleteTask());
191  break;
192  }
193  }
194  }
195 
196  }
197 
198  private final class AnalysisCompleteTask implements Runnable {
199 
200  @Override
201  public void run() {
202  // clear the tracker to reduce memory usage
203  if (getCeModuleInstanceCount() == 0) {
204  recentlyAddedCeArtifacts.clear();
205  }
206  //else another instance of the Correlation Engine Module is still being run.
207  } // DATA_SOURCE_ANALYSIS_COMPLETED
208  }
209 
210  private final class DataAddedTask implements Runnable {
211 
212  private final EamDb dbManager;
213  private final PropertyChangeEvent event;
214 
215  private DataAddedTask(EamDb db, PropertyChangeEvent evt) {
216  dbManager = db;
217  event = evt;
218  }
219 
220  @Override
221  public void run() {
222  if (!EamDb.isEnabled()) {
223  return;
224  }
225  final ModuleDataEvent mde = (ModuleDataEvent) event.getOldValue();
226  Collection<BlackboardArtifact> bbArtifacts = mde.getArtifacts();
227  if (null == bbArtifacts) { //the ModuleDataEvents don't always have a collection of artifacts set
228  return;
229  }
230  List<CorrelationAttribute> eamArtifacts = new ArrayList<>();
231 
232  for (BlackboardArtifact bbArtifact : bbArtifacts) {
233  // eamArtifact will be null OR a EamArtifact containing one EamArtifactInstance.
234  List<CorrelationAttribute> convertedArtifacts = EamArtifactUtil.getCorrelationAttributeFromBlackboardArtifact(bbArtifact, true, true);
235  for (CorrelationAttribute eamArtifact : convertedArtifacts) {
236  try {
237  // Only do something with this artifact if it's unique within the job
238  if (recentlyAddedCeArtifacts.add(eamArtifact.toString())) {
239  // Was it previously marked as bad?
240  // query db for artifact instances having this TYPE/VALUE and knownStatus = "Bad".
241  // if gettKnownStatus() is "Unknown" and this artifact instance was marked bad in a previous case,
242  // create TSK_INTERESTING_ARTIFACT_HIT artifact on BB.
243  List<String> caseDisplayNames = dbManager.getListCasesHavingArtifactInstancesKnownBad(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue());
244  if (!caseDisplayNames.isEmpty()) {
246  caseDisplayNames);
247  }
248  eamArtifacts.add(eamArtifact);
249  }
250  } catch (EamDbException ex) {
251  LOGGER.log(Level.SEVERE, "Error counting notable artifacts.", ex);
252  }
253  }
254  }
255  if (FALSE == eamArtifacts.isEmpty()) {
256  try {
257  for (CorrelationAttribute eamArtifact : eamArtifacts) {
258  dbManager.addArtifact(eamArtifact);
259  }
260  } catch (EamDbException ex) {
261  LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); //NON-NLS
262  }
263  } // DATA_ADDED
264  }
265  }
266 }
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)
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: Tue Feb 20 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.