Autopsy  4.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ExternalResultsImporter.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2016 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 localFile 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.externalresults;
20 
21 import java.io.File;
22 import java.nio.file.Path;
23 import java.nio.file.Paths;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.logging.Level;
29 import org.openide.util.NbBundle;
39 import org.sleuthkit.datamodel.AbstractFile;
40 import org.sleuthkit.datamodel.BlackboardArtifact;
41 import org.sleuthkit.datamodel.BlackboardAttribute;
42 import org.sleuthkit.datamodel.Content;
43 import org.sleuthkit.datamodel.DerivedFile;
44 import org.sleuthkit.datamodel.SleuthkitCase;
45 import org.sleuthkit.datamodel.TskCoreException;
46 import org.sleuthkit.datamodel.TskDataException;
47 
53 public final class ExternalResultsImporter {
54 
55  private static final Logger logger = Logger.getLogger(ExternalResultsImporter.class.getName());
56  private static final HashSet<Integer> standardArtifactTypeIds = new HashSet<>();
57  private final List<ErrorInfo> errors = new ArrayList<>();
59 
60  static {
61  for (BlackboardArtifact.ARTIFACT_TYPE artifactType : BlackboardArtifact.ARTIFACT_TYPE.values()) {
62  standardArtifactTypeIds.add(artifactType.getTypeID());
63  }
64  }
65 
77  public List<ErrorInfo> importResults(ExternalResults results) {
78  blackboard = Case.getCurrentCase().getServices().getBlackboard();
79  // Import files first, they may be artifactData sources.
80  importDerivedFiles(results);
81  importArtifacts(results);
82  importReports(results);
83  List<ErrorInfo> importErrors = new ArrayList<>(this.errors);
84  this.errors.clear();
85  return importErrors;
86  }
87 
88  private void importDerivedFiles(ExternalResults results) {
90  for (ExternalResults.DerivedFile fileData : results.getDerivedFiles()) {
91  String localPath = fileData.getLocalPath();
92  try {
93  File localFile = new File(localPath);
94  if (localFile.exists()) {
95  String relativePath = this.getPathRelativeToCaseFolder(localPath);
96  if (!relativePath.isEmpty()) {
97  String parentFilePath = fileData.getParentPath();
98  AbstractFile parentFile = findFileInCaseDatabase(parentFilePath);
99  if (parentFile != null) {
100  DerivedFile derivedFile = fileManager.addDerivedFile(localFile.getName(), relativePath, localFile.length(),
101  0, 0, 0, 0, // Do not currently have file times for derived files from external processes.
102  true, parentFile,
103  "", "", "", ""); // Not currently providing derivation info for derived files from external processes.
105  } else {
106  String errorMessage = NbBundle.getMessage(this.getClass(),
107  "ExternalResultsImporter.importDerivedFiles.errMsg1.text",
108  localPath, parentFilePath);
109  ExternalResultsImporter.logger.log(Level.SEVERE, errorMessage);
110  this.errors.add(new ErrorInfo(ExternalResultsImporter.class.getName(), errorMessage));
111  }
112  }
113  } else {
114  String errorMessage = NbBundle.getMessage(this.getClass(),
115  "ExternalResultsImporter.importDerivedFiles.errMsg2.text",
116  localPath);
117  ExternalResultsImporter.logger.log(Level.SEVERE, errorMessage);
118  this.errors.add(new ErrorInfo(ExternalResultsImporter.class.getName(), errorMessage));
119  }
120  } catch (TskCoreException ex) {
121  String errorMessage = NbBundle.getMessage(this.getClass(),
122  "ExternalResultsImporter.importDerivedFiles.errMsg3.text",
123  localPath);
124  ExternalResultsImporter.logger.log(Level.SEVERE, errorMessage, ex);
125  this.errors.add(new ErrorInfo(ExternalResultsImporter.class.getName(), errorMessage, ex));
126  }
127  }
128  }
129 
130  private void importArtifacts(ExternalResults results) {
131  SleuthkitCase caseDb = Case.getCurrentCase().getSleuthkitCase();
132  for (ExternalResults.Artifact artifactData : results.getArtifacts()) {
133  try {
134  // Add the artifact to the case database.
135  int artifactTypeId = caseDb.getArtifactType(artifactData.getType()).getTypeID();
136  if (artifactTypeId == -1) {
137  artifactTypeId = caseDb.addBlackboardArtifactType(artifactData.getType(), artifactData.getType()).getTypeID();
138  }
139  Content sourceFile = findFileInCaseDatabase(artifactData.getSourceFilePath());
140  if (sourceFile != null) {
141  BlackboardArtifact artifact = sourceFile.newArtifact(artifactTypeId);
142 
143  // Add the artifact's attributes to the case database.
144  Collection<BlackboardAttribute> attributes = new ArrayList<>();
145  for (ExternalResults.ArtifactAttribute attributeData : artifactData.getAttributes()) {
146  BlackboardAttribute.Type attributeType = caseDb.getAttributeType(attributeData.getType());
147  if (attributeType == null) {
148  switch (attributeData.getValueType()) {
149  case "text": //NON-NLS
150  attributeType = caseDb.addArtifactAttributeType(attributeData.getType(), BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.fromLabel("String"), attributeData.getType()); //NON-NLS
151  break;
152  case "int32": //NON-NLS
153  attributeType = caseDb.addArtifactAttributeType(attributeData.getType(), BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.fromLabel("Integer"), attributeData.getType()); //NON-NLS
154  break;
155  case "int64": //NON-NLS
156  attributeType = caseDb.addArtifactAttributeType(attributeData.getType(), BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.fromLabel("Long"), attributeData.getType()); //NON-NLS
157  break;
158  case "double": //NON-NLS
159  attributeType = caseDb.addArtifactAttributeType(attributeData.getType(), BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.fromLabel("Double"), attributeData.getType()); //NON-NLS
160  break;
161  case "datetime": //NON-NLS
162  attributeType = caseDb.addArtifactAttributeType(attributeData.getType(), BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.fromLabel("DateTime"), attributeData.getType()); //NON-NLS
163  }
164  }
165 
166  switch (attributeData.getValueType()) {
167  case "text": //NON-NLS
168  attributes.add(new BlackboardAttribute(attributeType, attributeData.getSourceModule(), attributeData.getValue()));
169  break;
170  case "int32": //NON-NLS
171  int intValue = Integer.parseInt(attributeData.getValue());
172  attributes.add(new BlackboardAttribute(attributeType, attributeData.getSourceModule(), intValue));
173  break;
174  case "int64": //NON-NLS
175  long longValue = Long.parseLong(attributeData.getValue());
176  attributes.add(new BlackboardAttribute(attributeType, attributeData.getSourceModule(), longValue));
177  break;
178  case "double": //NON-NLS
179  double doubleValue = Double.parseDouble(attributeData.getValue());
180  attributes.add(new BlackboardAttribute(attributeType, attributeData.getSourceModule(), doubleValue));
181  break;
182  case "datetime": //NON-NLS
183  long dateTimeValue = Long.parseLong(attributeData.getValue());
184  attributes.add(new BlackboardAttribute(attributeType, attributeData.getSourceModule(), dateTimeValue));
185  break;
186  default:
187  String errorMessage = NbBundle.getMessage(this.getClass(),
188  "ExternalResultsImporter.importArtifacts.caseErrMsg1.text",
189  attributeData.getType(), attributeData.getValue(),
190  artifactData.getType(), artifactData.getSourceFilePath(),
191  attributeData.getValueType());
192  ExternalResultsImporter.logger.log(Level.SEVERE, errorMessage);
193  this.errors.add(new ErrorInfo(ExternalResultsImporter.class.getName(), errorMessage));
194  break;
195  }
196  }
197  artifact.addAttributes(attributes);
198 
199  try {
200  // index the artifact for keyword search
201  blackboard.indexArtifact(artifact);
202  } catch (Blackboard.BlackboardException ex) {
203  logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.error.msg", artifact.getDisplayName()), ex); //NON-NLS
205  NbBundle.getMessage(Blackboard.class, "Blackboard.unableToIndexArtifact.exception.msg"), artifact.getDisplayName());
206  }
207 
208  if (standardArtifactTypeIds.contains(artifactTypeId)) {
209  IngestServices.getInstance().fireModuleDataEvent(new ModuleDataEvent(this.getClass().getSimpleName(), BlackboardArtifact.ARTIFACT_TYPE.fromID(artifactTypeId)));
210  }
211  } else {
212  String errorMessage = NbBundle.getMessage(this.getClass(),
213  "ExternalResultsImporter.importArtifacts.errMsg1.text",
214  artifactData.getType(), artifactData.getSourceFilePath());
215  ExternalResultsImporter.logger.log(Level.SEVERE, errorMessage);
216  this.errors.add(new ErrorInfo(ExternalResultsImporter.class.getName(), errorMessage));
217  }
218  } catch (TskCoreException | TskDataException ex) {
219  String errorMessage = NbBundle.getMessage(this.getClass(),
220  "ExternalResultsImporter.importArtifacts.errMsg2.text",
221  artifactData.getType(), artifactData.getSourceFilePath());
222  ExternalResultsImporter.logger.log(Level.SEVERE, errorMessage, ex);
223  this.errors.add(new ErrorInfo(ExternalResultsImporter.class.getName(), errorMessage, ex));
224  }
225  }
226  }
227 
228  private void importReports(ExternalResults results) {
229  for (ExternalResults.Report report : results.getReports()) {
230  String reportPath = report.getLocalPath();
231  try {
232  File reportFile = new File(reportPath);
233  if (reportFile.exists()) {
234  Case.getCurrentCase().addReport(reportPath, report.getSourceModuleName(), report.getReportName());
235  } else {
236  String errorMessage = NbBundle.getMessage(this.getClass(), "ExternalResultsImporter.importReports.errMsg1.text", reportPath);
237  ExternalResultsImporter.logger.log(Level.SEVERE, errorMessage);
238  this.errors.add(new ErrorInfo(ExternalResultsImporter.class.getName(), errorMessage));
239  }
240  } catch (TskCoreException ex) {
241  String errorMessage = NbBundle.getMessage(this.getClass(), "ExternalResultsImporter.importReports.errMsg2.text", reportPath);
242  ExternalResultsImporter.logger.log(Level.SEVERE, errorMessage, ex);
243  this.errors.add(new ErrorInfo(ExternalResultsImporter.class.getName(), errorMessage, ex));
244  }
245  }
246  }
247 
248  private AbstractFile findFileInCaseDatabase(String filePath) throws TskCoreException {
249  AbstractFile file = null;
250  // Split the path into the file name and the parent path.
251  String fileName = filePath;
252  String parentPath = "";
253  int charPos = filePath.lastIndexOf("/");
254  if (charPos >= 0) {
255  fileName = filePath.substring(charPos + 1);
256  parentPath = filePath.substring(0, charPos + 1);
257  }
258  // Find the file.
259  String condition = "name='" + fileName + "' AND parent_path='" + parentPath + "'"; //NON-NLS
260  List<AbstractFile> files = Case.getCurrentCase().getSleuthkitCase().findAllFilesWhere(condition);
261  if (!files.isEmpty()) {
262  file = files.get(0);
263  if (files.size() > 1) {
264  String errorMessage = NbBundle.getMessage(this.getClass(), "ExternalResultsImporter.findFileInCaseDatabase.errMsg1.text", filePath);
265  this.recordError(errorMessage);
266  }
267  }
268  return file;
269  }
270 
271  private String getPathRelativeToCaseFolder(String localPath) {
272  String relativePath = "";
273  String caseDirectoryPath = Case.getCurrentCase().getCaseDirectory();
274  Path path = Paths.get(localPath);
275  if (path.isAbsolute()) {
276  Path pathBase = Paths.get(caseDirectoryPath);
277  try {
278  Path pathRelative = pathBase.relativize(path);
279  relativePath = pathRelative.toString();
280  } catch (IllegalArgumentException ex) {
281  String errorMessage = NbBundle.getMessage(this.getClass(),
282  "ExternalResultsImporter.getPathRelativeToCaseFolder.errMsg1.text",
283  localPath, caseDirectoryPath);
284  this.recordError(errorMessage, ex);
285  }
286  } else {
287  String errorMessage = NbBundle.getMessage(this.getClass(),
288  "ExternalResultsImporter.getPathRelativeToCaseFolder.errMsg2.text",
289  localPath, caseDirectoryPath);
290  this.recordError(errorMessage);
291  }
292  return relativePath;
293  }
294 
295  private void recordError(String errorMessage) {
296  ExternalResultsImporter.logger.log(Level.SEVERE, errorMessage);
297  this.errors.add(new ErrorInfo(this.getClass().getName(), errorMessage));
298  }
299 
300  private void recordError(String errorMessage, Exception ex) {
301  ExternalResultsImporter.logger.log(Level.SEVERE, errorMessage, ex);
302  this.errors.add(new ErrorInfo(this.getClass().getName(), errorMessage));
303  }
304 }
void indexArtifact(BlackboardArtifact artifact)
Definition: Blackboard.java:45
void addReport(String localPath, String srcModuleName, String reportName)
Definition: Case.java:1687
synchronized DerivedFile addDerivedFile(String fileName, String localPath, long size, long ctime, long crtime, long atime, long mtime, boolean isFile, AbstractFile parentFile, String rederiveDetails, String toolName, String toolVersion, String otherDetails)
void fireModuleDataEvent(ModuleDataEvent moduleDataEvent)
void fireModuleContentEvent(ModuleContentEvent moduleContentEvent)
static void error(String title, String message)
synchronized static Logger getLogger(String name)
Definition: Logger.java:166
static synchronized IngestServices getInstance()

Copyright © 2012-2015 Basis Technology. Generated on: Wed Apr 6 2016
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.