Autopsy  4.17.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
PastCasesSummary.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2019 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.datasourcesummary.datamodel;
20 
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Set;
28 import java.util.logging.Level;
29 import java.util.stream.Collectors;
30 import java.util.stream.Stream;
31 import org.apache.commons.lang3.tuple.Pair;
35 import org.sleuthkit.datamodel.BlackboardArtifact;
36 import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
37 import org.sleuthkit.datamodel.BlackboardAttribute;
38 import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
39 import org.sleuthkit.datamodel.DataSource;
40 import org.sleuthkit.datamodel.SleuthkitCase;
41 import org.sleuthkit.datamodel.TskCoreException;
42 
66 
70  public static class PastCasesResult {
71 
72  private final List<Pair<String, Long>> sameIdsResults;
73  private final List<Pair<String, Long>> taggedNotable;
74 
81  public PastCasesResult(List<Pair<String, Long>> sameIdsResults, List<Pair<String, Long>> taggedNotable) {
82  this.sameIdsResults = sameIdsResults;
83  this.taggedNotable = taggedNotable;
84  }
85 
89  public List<Pair<String, Long>> getSameIdsResults() {
90  return sameIdsResults;
91  }
92 
96  public List<Pair<String, Long>> getTaggedNotable() {
97  return taggedNotable;
98  }
99  }
100 
101  private static final Set<Integer> ARTIFACT_UPDATE_TYPE_IDS = new HashSet<>(Arrays.asList(
102  ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),
103  ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()
104  ));
105 
106  private static final String CENTRAL_REPO_INGEST_NAME = CentralRepoIngestModuleFactory.getModuleName().toUpperCase().trim();
107  private static final BlackboardAttribute.Type TYPE_COMMENT = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_COMMENT);
108  private static final BlackboardAttribute.Type TYPE_ASSOCIATED_ARTIFACT = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT);
109 
110  private static final Set<Integer> CR_DEVICE_TYPE_IDS = new HashSet<>(Arrays.asList(
111  ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID(),
112  ARTIFACT_TYPE.TSK_DEVICE_INFO.getTypeID(),
113  ARTIFACT_TYPE.TSK_SIM_ATTACHED.getTypeID(),
114  ARTIFACT_TYPE.TSK_WIFI_NETWORK_ADAPTER.getTypeID()
115  ));
116 
117  private static final String CASE_SEPARATOR = ",";
118  private static final String PREFIX_END = ":";
119 
121  private final java.util.logging.Logger logger;
122 
126  public PastCasesSummary() {
127  this(
130  );
131 
132  }
133 
143  SleuthkitCaseProvider provider,
144  java.util.logging.Logger logger) {
145 
146  this.caseProvider = provider;
147  this.logger = logger;
148  }
149 
150  @Override
151  public Set<Integer> getArtifactTypeIdsForRefresh() {
153  }
154 
164  private static boolean isCentralRepoGenerated(List<String> sources) {
165  if (sources == null) {
166  return false;
167  }
168 
169  return sources.stream().anyMatch((str) -> {
170  return str != null && CENTRAL_REPO_INGEST_NAME.equalsIgnoreCase(str.trim());
171  });
172  }
173 
183  private static List<String> getCasesFromArtifact(BlackboardArtifact artifact) {
184  if (artifact == null) {
185  return Collections.emptyList();
186  }
187 
188  BlackboardAttribute commentAttr = null;
189  try {
190  commentAttr = artifact.getAttribute(TYPE_COMMENT);
191  } catch (TskCoreException ignored) {
192  // ignore if no attribute can be found
193  }
194 
195  if (commentAttr == null) {
196  return Collections.emptyList();
197  }
198 
199  if (!isCentralRepoGenerated(commentAttr.getSources())) {
200  return Collections.emptyList();
201  }
202 
203  String commentStr = commentAttr.getValueString();
204 
205  int prefixCharIdx = commentStr.indexOf(PREFIX_END);
206  if (prefixCharIdx < 0 || prefixCharIdx >= commentStr.length() - 1) {
207  return Collections.emptyList();
208  }
209 
210  String justCasesStr = commentStr.substring(prefixCharIdx + 1).trim();
211  return Stream.of(justCasesStr.split(CASE_SEPARATOR))
212  .map(String::trim)
213  .collect(Collectors.toList());
214 
215  }
216 
227  private List<Pair<String, Long>> getCaseCounts(Stream<String> cases) {
228  Collection<List<String>> groupedCases = cases
229  // group by case insensitive compare of cases
230  .collect(Collectors.groupingBy((caseStr) -> caseStr.toUpperCase().trim()))
231  .values();
232 
233  return groupedCases
234  .stream()
235  // get any cases where an actual case is found
236  .filter((lst) -> lst != null && lst.size() > 0)
237  // get non-normalized (i.e. not all caps) case name and number of items found
238  .map((lst) -> Pair.of(lst.get(0), (long) lst.size()))
239  // sorted descending
240  .sorted((a, b) -> -Long.compare(a.getValue(), b.getValue()))
241  .collect(Collectors.toList());
242  }
243 
254  private BlackboardArtifact getParentArtifact(BlackboardArtifact artifact) throws SleuthkitCaseProviderException {
255  Long parentId = DataSourceInfoUtilities.getLongOrNull(artifact, TYPE_ASSOCIATED_ARTIFACT);
256  if (parentId == null) {
257  return null;
258  }
259 
260  SleuthkitCase skCase = caseProvider.get();
261  try {
262  return skCase.getArtifactByArtifactId(parentId);
263  } catch (TskCoreException ex) {
264  logger.log(Level.WARNING,
265  String.format("There was an error fetching the parent artifact of a TSK_INTERESTING_ARTIFACT_HIT (parent id: %d)", parentId),
266  ex);
267  return null;
268  }
269  }
270 
280  private boolean hasDeviceAssociatedArtifact(BlackboardArtifact artifact) throws SleuthkitCaseProviderException {
281  BlackboardArtifact parent = getParentArtifact(artifact);
282  if (parent == null) {
283  return false;
284  }
285 
286  return CR_DEVICE_TYPE_IDS.contains(parent.getArtifactTypeID());
287  }
288 
299  public PastCasesResult getPastCasesData(DataSource dataSource)
300  throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException {
301 
302  if (dataSource == null) {
303  return null;
304  }
305 
306  SleuthkitCase skCase = caseProvider.get();
307 
308  List<String> deviceArtifactCases = new ArrayList<>();
309  List<String> nonDeviceArtifactCases = new ArrayList<>();
310 
311  for (BlackboardArtifact artifact : skCase.getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID(), dataSource.getId())) {
312  List<String> cases = getCasesFromArtifact(artifact);
313  if (cases == null || cases.isEmpty()) {
314  continue;
315  }
316 
317  if (hasDeviceAssociatedArtifact(artifact)) {
318  deviceArtifactCases.addAll(cases);
319  } else {
320  nonDeviceArtifactCases.addAll(cases);
321  }
322  }
323 
324  Stream<String> filesCases = skCase.getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(), dataSource.getId()).stream()
325  .flatMap((art) -> getCasesFromArtifact(art).stream());
326 
327  return new PastCasesResult(
328  getCaseCounts(deviceArtifactCases.stream()),
329  getCaseCounts(Stream.concat(filesCases, nonDeviceArtifactCases.stream()))
330  );
331  }
332 }
BlackboardArtifact getParentArtifact(BlackboardArtifact artifact)
PastCasesResult(List< Pair< String, Long >> sameIdsResults, List< Pair< String, Long >> taggedNotable)
List< Pair< String, Long > > getCaseCounts(Stream< String > cases)
static List< String > getCasesFromArtifact(BlackboardArtifact artifact)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
PastCasesSummary(SleuthkitCaseProvider provider, java.util.logging.Logger logger)

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