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

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