Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
GetSCOTask.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.datamodel;
20 
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.lang.ref.WeakReference;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.logging.Level;
27 import org.apache.commons.lang3.tuple.Pair;
28 import org.openide.util.NbBundle.Messages;
36 import org.sleuthkit.datamodel.Score;
37 import org.sleuthkit.datamodel.AbstractFile;
38 import org.sleuthkit.datamodel.AnalysisResult;
39 import org.sleuthkit.datamodel.Content;
40 import org.sleuthkit.datamodel.DataArtifact;
41 import org.sleuthkit.datamodel.OsAccount;
42 import org.sleuthkit.datamodel.OsAccountInstance;
43 import org.sleuthkit.datamodel.TskCoreException;
44 
50 class GetSCOTask implements Runnable {
51 
52  private final WeakReference<AbstractContentNode<?>> weakNodeRef;
53  private static final Logger logger = Logger.getLogger(GetSCOTask.class.getName());
54  private final PropertyChangeListener listener;
55 
56  GetSCOTask(WeakReference<AbstractContentNode<?>> weakContentRef, PropertyChangeListener listener) {
57  this.weakNodeRef = weakContentRef;
58  this.listener = listener;
59  }
60 
61  @Messages({"GetSCOTask.occurrences.defaultDescription=No correlation properties found",
62  "GetSCOTask.occurrences.multipleProperties=Multiple different correlation properties exist for this result"})
63  @Override
64  public void run() {
65  AbstractContentNode<?> contentNode = weakNodeRef.get();
66  //Check for stale reference or if columns are disabled
67  if (contentNode == null || UserPreferences.getHideSCOColumns()) {
68  return;
69  }
70  // get the SCO column values
71  Pair<Score, String> scoreAndDescription;
72  Pair<Long, String> countAndDescription = null;
73  scoreAndDescription = contentNode.getScorePropertyAndDescription();
74 
75  String description = Bundle.GetSCOTask_occurrences_defaultDescription();
76  List<CorrelationAttributeInstance> listOfPossibleAttributes = new ArrayList<>();
77  Content contentFromNode = contentNode.getContent();
78  //the lists returned will be empty if the CR is not enabled
79  if (contentFromNode instanceof AbstractFile) {
80  listOfPossibleAttributes.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((AbstractFile) contentFromNode));
81  } else if (contentFromNode instanceof AnalysisResult) {
82  listOfPossibleAttributes.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((AnalysisResult) contentFromNode));
83  } else if (contentFromNode instanceof DataArtifact) {
84  listOfPossibleAttributes.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((DataArtifact) contentFromNode));
85  } else if (contentFromNode instanceof OsAccount) {
86  try {
87  List<OsAccountInstance> osAccountInstances = ((OsAccount) contentFromNode).getOsAccountInstances();
88 
89  /*
90  * In the most common use cases it will not matter which
91  * OsAccountInstance is selected, so choosing the first one is
92  * the most efficient solution.
93  */
94  OsAccountInstance osAccountInstance = osAccountInstances.isEmpty() ? null : osAccountInstances.get(0);
95  /*
96  * If we have a Case whith both data sources in the CR and data
97  * sources not in the CR, some of the OsAccountInstances for
98  * this OsAccount have not been processed into the CR. In this
99  * situation the counts may not always be accurate or
100  * consistent.
101  *
102  * In order to ensure conistency in all use cases we would need
103  * to ensure we always had an OsAccountInstance whose data
104  * source was in the CR when such an OsAccountInstance was
105  * available.
106  *
107  * The following block of code has been commented out because it
108  * reduces efficiency in what are believed to be the most common
109  * use cases. It would serve the purpose of providing
110  * consistency in edge cases where users are putting some but
111  * not all the data concerning OS Accounts, which is present in
112  * a single Case, into the CR. See TODO-JIRA-8031 for a similar
113  * issue in the OO viewer.
114  */
115 
116 // if (CentralRepository.isEnabled() && !osAccountInstances.isEmpty()) {
117 // try {
118 // CentralRepository centralRepo = CentralRepository.getInstance();
119 // //Correlation Cases are cached when we get them so this shouldn't involve a round trip for every node.
120 // CorrelationCase crCase = centralRepo.getCase(Case.getCurrentCaseThrows());
121 // for (OsAccountInstance caseOsAccountInstance : osAccountInstances) {
122 // //correlation data sources are also cached so once should not involve round trips every time.
123 // CorrelationDataSource correlationDataSource = centralRepo.getDataSource(crCase, caseOsAccountInstance.getDataSource().getId());
124 // if (correlationDataSource != null) {
125 // //we have found a data source which exists in the CR we will use it instead of the arbitrary first instance
126 // osAccountInstance = caseOsAccountInstance;
127 // break;
128 // }
129 // }
130 // } catch (CentralRepoException ex) {
131 // logger.log(Level.SEVERE, "Error checking CR for data sources which exist in it", ex);
132 // } catch (NoCurrentCaseException ex) {
133 // logger.log(Level.WARNING, "The current case was closed while attempting to find a data source in the central repository", ex);
134 // }
135 // }
136  listOfPossibleAttributes.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch(osAccountInstance));
137  } catch (TskCoreException ex) {
138  logger.log(Level.SEVERE, "Unable to get the DataSource or OsAccountInstances from an OsAccount with ID: " + contentFromNode.getId(), ex);
139  }
140  }
141  DataResultViewerTable.HasCommentStatus commentStatus = contentNode.getCommentProperty(contentNode.getAllTagsFromDatabase(), listOfPossibleAttributes);
142  CorrelationAttributeInstance corInstance = null;
143  if (CentralRepository.isEnabled()) {
144  if (listOfPossibleAttributes.size() > 1) {
145  //Don't display anything if there is more than 1 correlation property for an artifact but let the user know
146  description = Bundle.GetSCOTask_occurrences_multipleProperties();
147  } else if (!listOfPossibleAttributes.isEmpty()) {
148  //there should only be one item in the list
149  corInstance = listOfPossibleAttributes.get(0);
150  }
151  countAndDescription = contentNode.getCountPropertyAndDescription(corInstance, description);
152  }
153  if (Thread.currentThread().isInterrupted()) {
154  return;
155  }
156  // signal SCO data is available.
157  if (listener != null) {
158  listener.propertyChange(new PropertyChangeEvent(
159  AutopsyEvent.SourceType.LOCAL.toString(),
160  AbstractAbstractFileNode.NodeSpecificEvents.SCO_AVAILABLE.toString(),
161  null, new SCOData(scoreAndDescription, commentStatus, countAndDescription)));
162  }
163  }
164 }

Copyright © 2012-2022 Basis Technology. Generated on: Tue Aug 1 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.