Autopsy  4.14.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
AddLogicalImageTask.java
Go to the documentation of this file.
1 /*
2  * Autopsy
3  *
4  * Copyright 2019 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.logicalimager.dsp;
20 
21 import java.io.BufferedReader;
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FilenameFilter;
25 import java.io.IOException;
26 import java.io.InputStreamReader;
27 import java.nio.file.Files;
28 import java.nio.file.Path;
29 import java.nio.file.Paths;
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.HashMap;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.logging.Level;
37 import javax.annotation.concurrent.GuardedBy;
38 import org.apache.commons.io.FileUtils;
39 import org.openide.util.NbBundle.Messages;
46 import org.sleuthkit.datamodel.AbstractFile;
47 import org.sleuthkit.datamodel.Blackboard;
48 import org.sleuthkit.datamodel.BlackboardArtifact;
49 import org.sleuthkit.datamodel.BlackboardAttribute;
50 import org.sleuthkit.datamodel.Content;
51 import org.sleuthkit.datamodel.LocalFilesDataSource;
52 import org.sleuthkit.datamodel.SleuthkitCase;
53 import org.sleuthkit.datamodel.TskCoreException;
54 
60 final class AddLogicalImageTask implements Runnable {
61 
62  private final static Logger LOGGER = Logger.getLogger(AddLogicalImageTask.class.getName());
63  private final static String SEARCH_RESULTS_TXT = "SearchResults.txt"; //NON-NLS
64  private final static String USERS_TXT = "_users.txt"; //NON-NLS
65  private final static String MODULE_NAME = "Logical Imager"; //NON-NLS
66  private final static String ROOT_STR = "root"; // NON-NLS
67  private final static String VHD_EXTENSION = ".vhd"; // NON-NLS
68  private final static int REPORT_PROGRESS_INTERVAL = 100;
69  private final static int POST_ARTIFACT_INTERVAL = 1000;
70  private final String deviceId;
71  private final String timeZone;
72  private final File src;
73  private final File dest;
74  private final DataSourceProcessorCallback callback;
75  private final DataSourceProcessorProgressMonitor progressMonitor;
76  private final Blackboard blackboard;
77  private final Case currentCase;
78 
79  private volatile boolean cancelled;
80  private volatile boolean createVHD;
81  private long totalFiles;
82  private Map<String, Long> imagePathToObjIdMap;
83 
84  private final Object addMultipleImagesLock;
85  @GuardedBy("addMultipleImagesLock")
86  private AddMultipleImagesTask addMultipleImagesTask = null;
87 
88  AddLogicalImageTask(String deviceId,
89  String timeZone,
90  File src, File dest,
91  DataSourceProcessorProgressMonitor progressMonitor,
93  ) throws NoCurrentCaseException {
94  this.deviceId = deviceId;
95  this.timeZone = timeZone;
96  this.src = src;
97  this.dest = dest;
98  this.progressMonitor = progressMonitor;
99  this.callback = callback;
100  this.currentCase = Case.getCurrentCase();
101  this.blackboard = this.currentCase.getServices().getArtifactsBlackboard();
102  this.addMultipleImagesLock = new Object();
103  }
104 
109  @Messages({
110  "# {0} - src", "# {1} - dest", "AddLogicalImageTask.copyingImageFromTo=Copying image from {0} to {1}",
111  "AddLogicalImageTask.doneCopying=Done copying",
112  "# {0} - src", "# {1} - dest", "AddLogicalImageTask.failedToCopyDirectory=Failed to copy directory {0} to {1}",
113  "# {0} - file", "AddLogicalImageTask.addingToReport=Adding {0} to report",
114  "# {0} - file", "AddLogicalImageTask.doneAddingToReport=Done adding {0} to report",
115  "AddLogicalImageTask.ingestionCancelled=Ingestion cancelled",
116  "# {0} - file", "AddLogicalImageTask.failToGetCanonicalPath=Fail to get canonical path for {0}",
117  "# {0} - sparseImageDirectory", "AddLogicalImageTask.directoryDoesNotContainSparseImage=Directory {0} does not contain any images",
118  "AddLogicalImageTask.noCurrentCase=No current case",
119  "AddLogicalImageTask.addingInterestingFiles=Adding search results as interesting files",
120  "AddLogicalImageTask.doneAddingInterestingFiles=Done adding search results as interesting files",
121  "# {0} - SearchResults.txt", "# {1} - directory", "AddLogicalImageTask.cannotFindFiles=Cannot find {0} in {1}",
122  "# {0} - reason", "AddLogicalImageTask.failedToAddInterestingFiles=Failed to add interesting files: {0}",
123  "AddLogicalImageTask.addingExtractedFiles=Adding extracted files",
124  "AddLogicalImageTask.doneAddingExtractedFiles=Done adding extracted files",
125  "# {0} - reason", "AddLogicalImageTask.failedToGetTotalFilesCount=Failed to get total files count: {0}",
126  "AddLogicalImageTask.addImageCancelled=Add image cancelled"
127  })
128  @Override
129  public void run() {
130  List<String> errorList = new ArrayList<>();
131  List<Content> emptyDataSources = new ArrayList<>();
132 
133  try {
134  progressMonitor.setProgressText(Bundle.AddLogicalImageTask_copyingImageFromTo(src.toString(), dest.toString()));
135  FileUtils.copyDirectory(src, dest);
136  progressMonitor.setProgressText(Bundle.AddLogicalImageTask_doneCopying());
137  } catch (IOException ex) {
138  // Copy directory failed
139  String msg = Bundle.AddLogicalImageTask_failedToCopyDirectory(src.toString(), dest.toString());
140  errorList.add(msg);
141  }
142 
143  if (cancelled) {
144  // Don't delete destination directory once we started adding interesting files.
145  // At this point the database and destination directory are complete.
146  deleteDestinationDirectory();
147  errorList.add(Bundle.AddLogicalImageTask_addImageCancelled());
148  callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
149  return;
150  }
151 
152  // Add the SearchResults.txt and *_users.txt to the case report
153  String resultsFilename;
154  if (Paths.get(dest.toString(), SEARCH_RESULTS_TXT).toFile().exists()) {
155  resultsFilename = SEARCH_RESULTS_TXT;
156  } else {
157  errorList.add(Bundle.AddLogicalImageTask_cannotFindFiles(SEARCH_RESULTS_TXT, dest.toString()));
158  callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
159  return;
160  }
161 
162  progressMonitor.setProgressText(Bundle.AddLogicalImageTask_addingToReport(resultsFilename));
163  String status = addReport(Paths.get(dest.toString(), resultsFilename), resultsFilename + " " + src.getName());
164  if (status != null) {
165  errorList.add(status);
166  callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
167  return;
168  }
169  progressMonitor.setProgressText(Bundle.AddLogicalImageTask_doneAddingToReport(resultsFilename));
170 
171  // All all *_users.txt files to report
172  File[] userFiles = dest.listFiles(new FilenameFilter() {
173  @Override
174  public boolean accept(File dir, String name) {
175  return name.endsWith(USERS_TXT);
176  }
177  });
178 
179  for (File userFile : userFiles) {
180  progressMonitor.setProgressText(Bundle.AddLogicalImageTask_addingToReport(userFile.getName()));
181  status = addReport(userFile.toPath(), userFile.getName() + " " + src.getName());
182  if (status != null) {
183  errorList.add(status);
184  callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
185  return;
186  }
187  progressMonitor.setProgressText(Bundle.AddLogicalImageTask_doneAddingToReport(userFile.getName()));
188  }
189 
190  // Get all VHD files in the dest directory
191  List<String> imagePaths = new ArrayList<>();
192  for (File f : dest.listFiles()) {
193  if (f.getName().endsWith(VHD_EXTENSION)) {
194  try {
195  imagePaths.add(f.getCanonicalPath());
196  } catch (IOException ioe) {
197  String msg = Bundle.AddLogicalImageTask_failToGetCanonicalPath(f.getName());
198  errorList.add(msg);
199  callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
200  return;
201  }
202  }
203  }
204 
205  Path resultsPath = Paths.get(dest.toString(), resultsFilename);
206  try {
207  totalFiles = Files.lines(resultsPath).count() - 1; // skip the header line
208  } catch (IOException ex) {
209  errorList.add(Bundle.AddLogicalImageTask_failedToGetTotalFilesCount(ex.getMessage()));
210  callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
211  return;
212  }
213 
214  List<Content> newDataSources = new ArrayList<>();
215  Map<String, List<Long>> interestingFileMap = new HashMap<>();
216 
217  if (imagePaths.isEmpty()) {
218  createVHD = false;
219  // No VHD in src directory, try ingest the root directory as local files
220  File root = Paths.get(dest.toString(), ROOT_STR).toFile();
221  if (root.exists() && root.isDirectory()) {
222  imagePaths.add(root.getAbsolutePath());
223  } else {
224  String msg = Bundle.AddLogicalImageTask_directoryDoesNotContainSparseImage(dest);
225  errorList.add(msg);
226  callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
227  return;
228  }
229 
230  try {
231  progressMonitor.setProgressText(Bundle.AddLogicalImageTask_addingExtractedFiles());
232  interestingFileMap = addExtractedFiles(dest, resultsPath, newDataSources);
233  progressMonitor.setProgressText(Bundle.AddLogicalImageTask_doneAddingExtractedFiles());
234  } catch (IOException | TskCoreException ex) {
235  errorList.add(ex.getMessage());
236  LOGGER.log(Level.SEVERE, String.format("Failed to add datasource: %s", ex.getMessage()), ex); // NON-NLS
237  callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
238  return;
239  }
240  } else {
241  createVHD = true;
242  // ingest the VHDs
243  try {
244  synchronized (addMultipleImagesLock) {
245  if (cancelled) {
246  LOGGER.log(Level.SEVERE, "Add VHD cancelled"); // NON-NLS
247  errorList.add(Bundle.AddLogicalImageTask_addImageCancelled());
248  callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
249  return;
250  }
251  addMultipleImagesTask = new AddMultipleImagesTask(deviceId, imagePaths, timeZone , progressMonitor);
252  }
253  addMultipleImagesTask.run();
254  if (addMultipleImagesTask.getResult() == DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS) {
255  LOGGER.log(Level.SEVERE, "Failed to add VHD datasource"); // NON-NLS
256  callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, addMultipleImagesTask.getErrorMessages(), emptyDataSources);
257  return;
258  }
259  try {
260  interestingFileMap = getInterestingFileMapForVHD(Paths.get(dest.toString(), resultsFilename));
261  } catch (TskCoreException | IOException ex) {
262  errorList.add(Bundle.AddLogicalImageTask_failedToAddInterestingFiles(ex.getMessage()));
263  LOGGER.log(Level.SEVERE, "Failed to add interesting files", ex); // NON-NLS
264  callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.NONCRITICAL_ERRORS, errorList, emptyDataSources);
265  }
266 
267  } catch (NoCurrentCaseException ex) {
268  String msg = Bundle.AddLogicalImageTask_noCurrentCase();
269  errorList.add(msg);
270  callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
271  return;
272  }
273  }
274 
275  if (cancelled) {
276  if (!createVHD) {
277  // TODO: When 5453 is fixed, we should be able to delete it when adding VHD.
278  deleteDestinationDirectory();
279  }
280  errorList.add(Bundle.AddLogicalImageTask_addImageCancelled());
281  callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errorList, emptyDataSources);
282  return;
283  }
284 
285  try {
286  progressMonitor.setProgressText(Bundle.AddLogicalImageTask_addingInterestingFiles());
287  addInterestingFiles(interestingFileMap);
288  progressMonitor.setProgressText(Bundle.AddLogicalImageTask_doneAddingInterestingFiles());
289  if (createVHD) {
290  callback.done(addMultipleImagesTask.getResult(), addMultipleImagesTask.getErrorMessages(), addMultipleImagesTask.getNewDataSources());
291  } else {
292  callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS, errorList, newDataSources);
293  }
294  } catch (IOException | TskCoreException ex) {
295  errorList.add(Bundle.AddLogicalImageTask_failedToAddInterestingFiles(ex.getMessage()));
296  LOGGER.log(Level.SEVERE, "Failed to add interesting files", ex); // NON-NLS
297  callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.NONCRITICAL_ERRORS, errorList, emptyDataSources);
298  }
299  }
300 
310  @Messages({
311  "# {0} - file", "# {1} - exception message", "AddLogicalImageTask.failedToAddReport=Failed to add report {0}. Reason= {1}"
312  })
313  private String addReport(Path reportPath, String reportName) {
314  if (!reportPath.toFile().exists()) {
315  return null; // if the reportPath doesn't exist, just ignore it.
316  }
317  try {
318  Case.getCurrentCase().addReport(reportPath.toString(), "LogicalImager", reportName); //NON-NLS
319  return null;
320  } catch (TskCoreException ex) {
321  String msg = Bundle.AddLogicalImageTask_failedToAddReport(reportPath.toString(), ex.getMessage());
322  LOGGER.log(Level.SEVERE, String.format("Failed to add report %s. Reason= %s", reportPath.toString(), ex.getMessage()), ex); // NON-NLS
323  return msg;
324  }
325  }
326 
331  void cancelTask() {
332  LOGGER.log(Level.WARNING, "AddLogicalImageTask cancelled, processing may be incomplete"); // NON-NLS
333  synchronized (addMultipleImagesLock) {
334  cancelled = true;
335  if (addMultipleImagesTask != null) {
336  addMultipleImagesTask.cancelTask();
337  }
338  }
339  }
340 
341  private Map<String, Long> imagePathsToDataSourceObjId(Map<Long, List<String>> imagePaths) {
342  Map<String, Long> imagePathToObjId = new HashMap<>();
343  for (Map.Entry<Long, List<String>> entry : imagePaths.entrySet()) {
344  Long key = entry.getKey();
345  List<String> names = entry.getValue();
346  for (String name : names) {
347  imagePathToObjId.put(name, key);
348  }
349  }
350  return imagePathToObjId;
351  }
352 
353  @Messages({
354  "# {0} - line number", "# {1} - fields length", "# {2} - expected length", "AddLogicalImageTask.notEnoughFields=File does not contain enough fields at line {0}, got {1}, expecting {2}",
355  "# {0} - target image path", "AddLogicalImageTask.cannotFindDataSourceObjId=Cannot find obj_id in tsk_image_names for {0}",
356  "# {0} - file number", "# {1} - total files", "AddLogicalImageTask.addingInterestingFile=Adding interesting files ({0}/{1})",
357  "AddLogicalImageTask.logicalImagerResults=Logical Imager results"
358  })
359  private void addInterestingFiles(Map<String, List<Long>> interestingFileMap) throws IOException, TskCoreException {
360  int lineNumber = 0;
361  List<BlackboardArtifact> artifacts = new ArrayList<>();
362 
363  Iterator<Map.Entry<String, List<Long>>> iterator = interestingFileMap.entrySet().iterator();
364  while (iterator.hasNext()) {
365 
366  if (cancelled) {
367  // Don't delete destination directory once we started adding interesting files.
368  // At this point the database and destination directory are complete.
369  break;
370  }
371 
372  Map.Entry<String, List<Long>> entry = iterator.next();
373  String key = entry.getKey();
374  String ruleName;
375  String[] split = key.split("\t");
376  ruleName = split[1];
377 
378  List<Long> fileIds = entry.getValue();
379  for (Long fileId: fileIds) {
380  if (cancelled) {
381  postArtifacts(artifacts);
382  return;
383  }
384  if (lineNumber % REPORT_PROGRESS_INTERVAL == 0) {
385  progressMonitor.setProgressText(Bundle.AddLogicalImageTask_addingInterestingFile(lineNumber, totalFiles));
386  }
387  if (lineNumber % POST_ARTIFACT_INTERVAL == 0) {
388  postArtifacts(artifacts);
389  artifacts.clear();
390  }
391  addInterestingFileToArtifacts(fileId, Bundle.AddLogicalImageTask_logicalImagerResults(), ruleName, artifacts);
392  lineNumber++;
393  }
394  iterator.remove();
395  }
396  postArtifacts(artifacts);
397  }
398 
399  private void addInterestingFileToArtifacts(long fileId, String ruleSetName, String ruleName, List<BlackboardArtifact> artifacts) throws TskCoreException {
400  Collection<BlackboardAttribute> attributes = new ArrayList<>();
401  BlackboardAttribute setNameAttribute = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, ruleSetName);
402  attributes.add(setNameAttribute);
403  BlackboardAttribute ruleNameAttribute = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY, MODULE_NAME, ruleName);
404  attributes.add(ruleNameAttribute);
405  BlackboardArtifact artifact = this.currentCase.getSleuthkitCase().newBlackboardArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT, fileId);
406  artifact.addAttributes(attributes);
407  artifacts.add(artifact);
408  }
409 
410  @Messages({
411  "# {0} - file number", "# {1} - total files", "AddLogicalImageTask.searchingInterestingFile=Searching for interesting files ({0}/{1})"
412  })
413  private Map<String, List<Long>> getInterestingFileMapForVHD(Path resultsPath) throws TskCoreException, IOException {
414  Map<Long, List<String>> objIdToimagePathsMap = currentCase.getSleuthkitCase().getImagePaths();
415  imagePathToObjIdMap = imagePathsToDataSourceObjId(objIdToimagePathsMap);
416  Map<String, List<Long>> interestingFileMap = new HashMap<>();
417 
418  try (BufferedReader br = new BufferedReader(new InputStreamReader(
419  new FileInputStream(resultsPath.toFile()), "UTF8"))) { // NON-NLS
420  String line;
421  br.readLine(); // skip the header line
422  int lineNumber = 2;
423  while ((line = br.readLine()) != null) {
424  if (cancelled) {
425  // Don't delete destination directory once we started adding interesting files.
426  // At this point the database and destination directory are complete.
427  break;
428  }
429  String[] fields = line.split("\t", -1); // NON-NLS
430  if (fields.length != 14) {
431  throw new IOException(Bundle.AddLogicalImageTask_notEnoughFields(lineNumber, fields.length, 14));
432  }
433  String vhdFilename = fields[0];
434 // String fileSystemOffsetStr = fields[1];
435  String fileMetaAddressStr = fields[2];
436 // String extractStatusStr = fields[3];
437  String ruleSetName = fields[4];
438  String ruleName = fields[5];
439 // String description = fields[6];
440  String filename = fields[7];
441  String parentPath = fields[8];
442 
443  if (lineNumber % REPORT_PROGRESS_INTERVAL == 0) {
444  progressMonitor.setProgressText(Bundle.AddLogicalImageTask_searchingInterestingFile(lineNumber, totalFiles));
445  }
446 
447  String query = makeQuery(vhdFilename, fileMetaAddressStr, parentPath, filename);
448  List<AbstractFile> matchedFiles = Case.getCurrentCase().getSleuthkitCase().findAllFilesWhere(query);
449  List<Long> fileIds = new ArrayList<>();
450  for (AbstractFile file : matchedFiles) {
451  fileIds.add(file.getId());
452  }
453  String key = String.format("%s\t%s", ruleSetName, ruleName);
454  if (interestingFileMap.containsKey(key)) {
455  interestingFileMap.get(key).addAll(fileIds);
456  } else {
457  interestingFileMap.put(key, fileIds);
458  }
459  lineNumber++;
460  } // end reading file
461  }
462  return interestingFileMap;
463  }
464 
465  private void postArtifacts(List<BlackboardArtifact> artifacts) {
466  try {
467  // index the artifact for keyword search
468  blackboard.postArtifacts(artifacts, MODULE_NAME);
469  } catch (Blackboard.BlackboardException ex) {
470  LOGGER.log(Level.SEVERE, "Unable to post artifacts to blackboard", ex); //NON-NLS
471  }
472  }
473 
474  @Messages({
475  "# {0} - file number", "# {1} - total files", "AddLogicalImageTask.addingExtractedFile=Adding extracted files ({0}/{1})"
476  })
477  private Map<String, List<Long>> addExtractedFiles(File src, Path resultsPath, List<Content> newDataSources) throws TskCoreException, IOException {
478  SleuthkitCase skCase = Case.getCurrentCase().getSleuthkitCase();
479  SleuthkitCase.CaseDbTransaction trans = null;
480  Map<String, List<Long>> interestingFileMap = new HashMap<>();
481 
482  try {
483  trans = skCase.beginTransaction();
484  LocalFilesDataSource localFilesDataSource = skCase.addLocalFilesDataSource(deviceId, this.src.getName(), timeZone, trans);
485  LocalFileImporter fileImporter = new LocalFileImporter(skCase, trans);
486 
487  try (BufferedReader br = new BufferedReader(new InputStreamReader(
488  new FileInputStream(resultsPath.toFile()), "UTF8"))) { // NON-NLS
489  String line;
490  br.readLine(); // skip the header line
491  int lineNumber = 2;
492  while ((line = br.readLine()) != null) {
493  if (cancelled) {
494  rollbackTransaction(trans);
495  return new HashMap<>();
496  }
497  String[] fields = line.split("\t", -1); // NON-NLS
498  if (fields.length != 14) {
499  rollbackTransaction(trans);
500  throw new IOException(Bundle.AddLogicalImageTask_notEnoughFields(lineNumber, fields.length, 14));
501  }
502  String vhdFilename = fields[0];
503 // String fileSystemOffsetStr = fields[1];
504 // String fileMetaAddressStr = fields[2];
505 // String extractStatusStr = fields[3];
506  String ruleSetName = fields[4];
507  String ruleName = fields[5];
508 // String description = fields[6];
509  String filename = fields[7];
510  String parentPath = fields[8];
511  String extractedFilePath = fields[9];
512  String crtime = fields[10];
513  String mtime = fields[11];
514  String atime = fields[12];
515  String ctime = fields[13];
516  parentPath = ROOT_STR + "/" + vhdFilename + "/" + parentPath;
517 
518  if (lineNumber % REPORT_PROGRESS_INTERVAL == 0) {
519  progressMonitor.setProgressText(Bundle.AddLogicalImageTask_addingExtractedFile(lineNumber, totalFiles));
520  }
521 
522  //addLocalFile here
523  AbstractFile fileAdded = fileImporter.addLocalFile(
524  Paths.get(src.toString(), extractedFilePath).toFile(),
525  filename,
526  parentPath,
527  Long.parseLong(ctime),
528  Long.parseLong(crtime),
529  Long.parseLong(atime),
530  Long.parseLong(mtime),
531  localFilesDataSource);
532  String key = String.format("%s\t%s", ruleSetName, ruleName);
533  List<Long> value = new ArrayList<>();
534  if (interestingFileMap.containsKey(key)) {
535  value = interestingFileMap.get(key);
536  }
537  value.add(fileAdded.getId());
538  interestingFileMap.put(key, value);
539  lineNumber++;
540  } // end reading file
541  }
542  trans.commit();
543  newDataSources.add(localFilesDataSource);
544  return interestingFileMap;
545 
546  } catch (NumberFormatException | TskCoreException ex) {
547  LOGGER.log(Level.SEVERE, "Error adding extracted files", ex); // NON-NLS
548  rollbackTransaction(trans);
549  throw new TskCoreException("Error adding extracted files", ex);
550  }
551  }
552 
553  private void rollbackTransaction(SleuthkitCase.CaseDbTransaction trans) throws TskCoreException {
554  if (null != trans) {
555  try {
556  trans.rollback();
557  } catch (TskCoreException ex) {
558  LOGGER.log(Level.SEVERE, String.format("Failed to rollback transaction: %s", ex.getMessage()), ex); // NON-NLS
559  }
560  }
561  }
562 
563  private boolean deleteDestinationDirectory() {
564  try {
565  FileUtils.deleteDirectory(dest);
566  LOGGER.log(Level.INFO, String.format("Cancellation: Deleted directory %s", dest.toString())); // NON-NLS
567  return true;
568  } catch (IOException ex) {
569  LOGGER.log(Level.WARNING, String.format("Cancellation: Failed to delete directory %s", dest.toString()), ex); // NON-NLS
570  return false;
571  }
572  }
573 
574  String makeQuery(String vhdFilename, String fileMetaAddressStr, String parentPath, String filename) throws TskCoreException {
575  String query;
576  String targetImagePath = Paths.get(dest.toString(), vhdFilename).toString();
577  Long dataSourceObjId = imagePathToObjIdMap.get(targetImagePath);
578  if (dataSourceObjId == null) {
579  throw new TskCoreException(Bundle.AddLogicalImageTask_cannotFindDataSourceObjId(targetImagePath));
580  }
581  query = String.format("data_source_obj_id = '%s' AND meta_addr = '%s' AND name = '%s'", // NON-NLS
582  dataSourceObjId.toString(), fileMetaAddressStr, filename.replace("'", "''"));
583  // TODO - findAllFilesWhere should SQL-escape the query
584  return query;
585  }
586 
587 }
org.sleuthkit.datamodel.Blackboard getArtifactsBlackboard()
Definition: Services.java:86
void addReport(String localPath, String srcModuleName, String reportName)
Definition: Case.java:1630
void done(DataSourceProcessorResult result, List< String > errList, List< Content > newDataSources)
AbstractFile addLocalFile(File fileOnDisk, String name, String parentPath, Long ctime, Long crtime, Long atime, Long mtime, DataSource dataSource)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124

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