Autopsy  4.19.3
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-2021 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.stream.Collectors;
29 import java.util.stream.Stream;
30 import org.apache.commons.lang3.tuple.Pair;
34 import org.sleuthkit.datamodel.Blackboard;
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.Content;
39 import org.sleuthkit.datamodel.DataSource;
40 import org.sleuthkit.datamodel.SleuthkitCase;
41 import org.sleuthkit.datamodel.TskCoreException;
42 
65 public class PastCasesSummary {
66 
70  public static class PastCasesResult {
71 
72  private final List<Pair<String, Long>> previouslyNotable;
73  private final List<Pair<String, Long>> previouslySeenDevices;
74  private final List<Pair<String, Long>> previouslySeenResults;
75 
83  public PastCasesResult(List<Pair<String, Long>> previouslyNotable, List<Pair<String, Long>> previouslySeenDevices, List<Pair<String, Long>> previouslySeenResults) {
84  this.previouslyNotable = Collections.unmodifiableList(previouslyNotable);
85  this.previouslySeenDevices = Collections.unmodifiableList(previouslySeenDevices);
86  this.previouslySeenResults = Collections.unmodifiableList(previouslySeenResults);
87  }
88 
92  public List<Pair<String, Long>> getPreviouslyNotable() {
93  return previouslyNotable;
94  }
95 
99  public List<Pair<String, Long>> getPreviouslySeenDevices() {
100  return previouslySeenDevices;
101  }
102 
106  public List<Pair<String, Long>> getPreviouslySeenResults() {
107  return previouslySeenResults;
108  }
109  }
110 
111  private static final Set<Integer> ARTIFACT_UPDATE_TYPE_IDS = new HashSet<>(Arrays.asList(
112  ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN.getTypeID(),
113  ARTIFACT_TYPE.TSK_PREVIOUSLY_NOTABLE.getTypeID()
114  ));
115 
116  private static final String CENTRAL_REPO_INGEST_NAME = CentralRepoIngestModuleFactory.getModuleName().toUpperCase().trim();
117 
118  private static final Set<Integer> CR_DEVICE_TYPE_IDS = new HashSet<>(Arrays.asList(
119  ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID(),
120  ARTIFACT_TYPE.TSK_DEVICE_INFO.getTypeID(),
121  ARTIFACT_TYPE.TSK_SIM_ATTACHED.getTypeID(),
122  ARTIFACT_TYPE.TSK_WIFI_NETWORK_ADAPTER.getTypeID()
123  ));
124 
125  private static final String CASE_SEPARATOR = ",";
126 
128  private final java.util.logging.Logger logger;
129 
133  public PastCasesSummary() {
134  this(
137  );
138 
139  }
140 
150  SleuthkitCaseProvider provider,
151  java.util.logging.Logger logger) {
152 
153  this.caseProvider = provider;
154  this.logger = logger;
155  }
156 
166  private static boolean isCentralRepoGenerated(List<String> sources) {
167  if (sources == null) {
168  return false;
169  }
170 
171  return sources.stream().anyMatch((str) -> {
172  return str != null && CENTRAL_REPO_INGEST_NAME.equalsIgnoreCase(str.trim());
173  });
174  }
175 
184  private static List<String> getCasesFromArtifact(BlackboardArtifact artifact) {
185  if (artifact == null) {
186  return Collections.emptyList();
187  }
188 
189  BlackboardAttribute commentAttr = null;
190  try {
191  commentAttr = artifact.getAttribute(BlackboardAttribute.Type.TSK_OTHER_CASES);
192  } catch (TskCoreException ignored) {
193  // ignore if no attribute can be found
194  }
195 
196  return getCasesFromAttr(commentAttr);
197 
198  }
199 
208  private static List<String> getCasesFromAttr(BlackboardAttribute commentAttr) {
209  if (commentAttr == null) {
210  return Collections.emptyList();
211  }
212 
213  if (!isCentralRepoGenerated(commentAttr.getSources())) {
214  return Collections.emptyList();
215  }
216 
217  String justCasesStr = commentAttr.getValueString().trim();
218  return Stream.of(justCasesStr.split(CASE_SEPARATOR))
219  .map(String::trim)
220  .collect(Collectors.toList());
221  }
222 
233  private static List<Pair<String, Long>> getCaseCounts(Stream<String> cases) {
234  Collection<List<String>> groupedCases = cases
235  // group by case insensitive compare of cases
236  .collect(Collectors.groupingBy((caseStr) -> caseStr.toUpperCase().trim()))
237  .values();
238 
239  return groupedCases
240  .stream()
241  // get any cases where an actual case is found
242  .filter((lst) -> lst != null && lst.size() > 0)
243  // get non-normalized (i.e. not all caps) case name and number of items found
244  .map((lst) -> Pair.of(lst.get(0), (long) lst.size()))
245  // sorted descending
246  .sorted((a, b) -> -Long.compare(a.getValue(), b.getValue()))
247  .collect(Collectors.toList());
248  }
249 
258  private static List<Pair<String, Long>> getCaseCountsFromArtifacts(List<BlackboardArtifact> artifacts) {
259  List<String> cases = new ArrayList<>();
260  for (BlackboardArtifact art : artifacts) {
261  cases.addAll(getCasesFromArtifact(art));
262  }
263 
264  return getCaseCounts(cases.stream());
265  }
266 
278  private BlackboardArtifact getParentArtifact(BlackboardArtifact artifact) throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException {
279 
280  BlackboardArtifact sourceArtifact = null;
281  SleuthkitCase skCase = caseProvider.get();
282  Content content = skCase.getContentById(artifact.getObjectID());
283  if (content instanceof BlackboardArtifact) {
284  sourceArtifact = (BlackboardArtifact) content;
285  }
286  return sourceArtifact;
287  }
288 
299  private boolean hasDeviceAssociatedArtifact(BlackboardArtifact artifact) throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException {
300  BlackboardArtifact parent = getParentArtifact(artifact);
301  if (parent == null) {
302  return false;
303  }
304 
305  return CR_DEVICE_TYPE_IDS.contains(parent.getArtifactTypeID());
306  }
307 
319  public PastCasesResult getPastCasesData(DataSource dataSource)
320  throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException {
321 
322  if (dataSource == null) {
323  return null;
324  }
325 
326  long dataSourceId = dataSource.getId();
327 
328  Blackboard blackboard = caseProvider.get().getBlackboard();
329 
330  List<BlackboardArtifact> previouslyNotableArtifacts
331  = blackboard.getArtifacts(BlackboardArtifact.Type.TSK_PREVIOUSLY_NOTABLE.getTypeID(), dataSourceId);
332 
333  List<BlackboardArtifact> previouslySeenArtifacts
334  = blackboard.getArtifacts(BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN.getTypeID(), dataSourceId);
335 
336  List<BlackboardArtifact> previouslySeenDevice = new ArrayList<>();
337  List<BlackboardArtifact> previouslySeenNoDevice = new ArrayList<>();
338 
339  for (BlackboardArtifact art : previouslySeenArtifacts) {
340  if (hasDeviceAssociatedArtifact(art)) {
341  previouslySeenDevice.add(art);
342  } else {
343  previouslySeenNoDevice.add(art);
344  }
345  }
346 
347  return new PastCasesResult(
348  getCaseCountsFromArtifacts(previouslyNotableArtifacts),
349  getCaseCountsFromArtifacts(previouslySeenDevice),
350  getCaseCountsFromArtifacts(previouslySeenNoDevice)
351  );
352  }
353 }
PastCasesResult(List< Pair< String, Long >> previouslyNotable, List< Pair< String, Long >> previouslySeenDevices, List< Pair< String, Long >> previouslySeenResults)
static List< String > getCasesFromAttr(BlackboardAttribute commentAttr)
BlackboardArtifact getParentArtifact(BlackboardArtifact artifact)
static List< Pair< String, Long > > getCaseCounts(Stream< String > cases)
static List< Pair< String, Long > > getCaseCountsFromArtifacts(List< BlackboardArtifact > artifacts)
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-2022 Basis Technology. Generated on: Fri Oct 7 2022
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.