Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
CentralRepoIngestModule.java
Go to the documentation of this file.
1 /*
2  * Central Repository
3  *
4  * Copyright 2018-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.centralrepository.ingestmodule;
20 
21 import java.util.HashSet;
22 import java.util.List;
23 import java.util.Set;
24 import java.util.logging.Level;
25 import org.openide.util.NbBundle.Messages;
40 import org.sleuthkit.datamodel.AbstractFile;
41 import org.sleuthkit.datamodel.HashUtility;
42 import org.sleuthkit.datamodel.TskData;
44 import static org.sleuthkit.autopsy.centralrepository.ingestmodule.CentralRepoIngestModuleUtils.makePrevNotableAnalysisResult;
45 
51 final class CentralRepoIngestModule implements FileIngestModule {
52 
53  private static final Logger logger = Logger.getLogger(CentralRepoIngestModule.class.getName());
54  private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
55  private final boolean flagNotableItems;
56  private final boolean saveCorrAttrInstances;
57  private CorrelationAttributeInstance.Type filesType;
58  private IngestJobContext context;
59  private CentralRepository centralRepo;
60 
68  CentralRepoIngestModule(IngestSettings settings) {
69  flagNotableItems = settings.isFlagTaggedNotableItems();
70  saveCorrAttrInstances = settings.shouldCreateCorrelationProperties();
71  }
72 
73  @Override
74  public ProcessResult process(AbstractFile abstractFile) {
75  if (!flagNotableItems && !saveCorrAttrInstances) {
76  return ProcessResult.OK;
77  }
78 
79  if (!filesType.isEnabled()) {
80  return ProcessResult.OK;
81  }
82 
83  if (abstractFile.getKnown() == TskData.FileKnown.KNOWN) {
84  return ProcessResult.OK;
85  }
86 
87  if (!CorrelationAttributeUtil.isSupportedAbstractFileType(abstractFile)) {
88  return ProcessResult.OK;
89  }
90 
91  /*
92  * The correlation attribute value for a file is its MD5 hash. This
93  * module cannot do anything with a file if the hash calculation has not
94  * been done, but the decision has been made to not do a hash
95  * calculation here if the file hashing and lookup module is not in this
96  * pipeline ahead of this module (affirmed per BC, 11/8/21).
97  */
98  String md5 = abstractFile.getMd5Hash();
99  if ((md5 == null) || (HashUtility.isNoDataMd5(md5))) {
100  return ProcessResult.OK;
101  }
102 
103  if (flagNotableItems) {
104  try {
105  TimingMetric timingMetric = HealthMonitor.getTimingMetric("Central Repository: Notable artifact query");
106  Set<String> otherCases = new HashSet<>();
107  otherCases.addAll(centralRepo.getListCasesHavingArtifactInstancesKnownBad(filesType, md5));
108  HealthMonitor.submitTimingMetric(timingMetric);
109  if (!otherCases.isEmpty()) {
110  makePrevNotableAnalysisResult(abstractFile, otherCases, filesType, md5, context.getDataSource().getId(), context.getJobId());
111  }
112  } catch (CentralRepoException ex) {
113  logger.log(Level.SEVERE, "Error searching database for artifact.", ex); // NON-NLS
114  } catch (CorrelationAttributeNormalizationException ex) {
115  logger.log(Level.INFO, "Error searching database for artifact: " + ex.getMessage()); // NON-NLS
116  }
117  }
118 
119  if (saveCorrAttrInstances) {
120  List<CorrelationAttributeInstance> corrAttrs = CorrelationAttributeUtil.makeCorrAttrsToSave(abstractFile);
121  for (CorrelationAttributeInstance corrAttr : corrAttrs) {
122  try {
123  centralRepo.addAttributeInstanceBulk(corrAttr);
124  } catch (CentralRepoException ex) {
125  logger.log(Level.SEVERE, "Error adding artifact to bulk artifacts.", ex); // NON-NLS
126  }
127  }
128  }
129 
130  return ProcessResult.OK;
131  }
132 
133  @Override
134  public void shutDown() {
135  if (refCounter.decrementAndGet(context.getJobId()) == 0) {
136  try {
137  centralRepo.commitAttributeInstancesBulk();
138  } catch (CentralRepoException ex) {
139  logger.log(Level.SEVERE, String.format("Error committing bulk insert of correlation attributes (job ID=%d)", context.getJobId()), ex); // NON-NLS
140  }
141  }
142  }
143 
144  @Messages({
145  "CentralRepoIngestModule_missingFileCorrAttrTypeErrMsg=Correlation attribute type for files not found in the central repository",
146  "CentralRepoIngestModule_cannotGetCrCaseErrMsg=Case not present in the central repository",
147  "CentralRepoIngestModule_cannotGetCrDataSourceErrMsg=Data source not present in the central repository"
148  })
149  @Override
150  public void startUp(IngestJobContext context) throws IngestModuleException {
151  this.context = context;
152 
153  if (!CentralRepository.isEnabled()) {
154  throw new IngestModuleException(Bundle.CentralRepoIngestModule_crNotEnabledErrMsg());
155  }
156 
157  try {
158  centralRepo = CentralRepository.getInstance();
159  } catch (CentralRepoException ex) {
160  throw new IngestModuleException(Bundle.CentralRepoIngestModule_crInaccessibleErrMsg(), ex);
161  }
162 
163  /*
164  * Make sure the correlation attribute type definition is in the central
165  * repository. Currently (11/8/21) it is cached, but there is no harm in
166  * saving it here for use in process().
167  */
168  try {
169  filesType = centralRepo.getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID);
170  } catch (CentralRepoException ex) {
171  throw new IngestModuleException(Bundle.CentralRepoIngestModule_missingFileCorrAttrTypeErrMsg(), ex);
172  }
173 
174  /*
175  * The first module instance started for this job makes sure the current
176  * case and data source are in the central repository. Currently
177  * (11/8/21), these are cached upon creation / first retreival.
178  */
179  if (refCounter.incrementAndGet(context.getJobId()) == 1) {
180  Case currentCase;
181  try {
182  currentCase = Case.getCurrentCaseThrows();
183  } catch (NoCurrentCaseException ex) {
184  throw new IngestModuleException(Bundle.CentralRepoIngestModule_noCurrentCaseErrMsg(), ex);
185  }
186 
187  CorrelationCase centralRepoCase;
188  try {
189  centralRepoCase = centralRepo.getCase(currentCase);
190  } catch (CentralRepoException ex) {
191  throw new IngestModuleException(Bundle.CentralRepoIngestModule_cannotGetCrCaseErrMsg(), ex);
192  }
193 
194  try {
195  CorrelationDataSource.fromTSKDataSource(centralRepoCase, context.getDataSource());
196  } catch (CentralRepoException ex) {
197  throw new IngestModuleException(Bundle.CentralRepoIngestModule_cannotGetCrDataSourceErrMsg(), ex);
198  }
199  }
200  }
201 
202 }

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.