Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
ImageDSProcessor.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2013-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 */
19package org.sleuthkit.autopsy.casemodule;
20
21import java.io.File;
22import java.nio.file.Path;
23import javax.swing.JPanel;
24import java.util.ArrayList;
25import java.util.Calendar;
26import java.util.List;
27import java.util.logging.Level;
28import java.util.UUID;
29import java.util.Objects;
30import javax.swing.filechooser.FileFilter;
31import org.openide.util.NbBundle;
32import org.openide.util.lookup.ServiceProvider;
33import org.openide.util.lookup.ServiceProviders;
34import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
35import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
36import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
37import org.sleuthkit.autopsy.coreutils.DataSourceUtils;
38import org.sleuthkit.autopsy.coreutils.Logger;
39import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor;
40import org.sleuthkit.autopsy.ingest.IngestJobSettings;
41import org.sleuthkit.autopsy.ingest.IngestManager;
42import org.sleuthkit.autopsy.ingest.IngestStream;
43import org.sleuthkit.datamodel.Host;
44import org.sleuthkit.datamodel.Image;
45import org.sleuthkit.datamodel.SleuthkitJNI;
46import org.sleuthkit.datamodel.TskCoreException;
47
54@ServiceProviders(value = {
55 @ServiceProvider(service = DataSourceProcessor.class),
56 @ServiceProvider(service = AutoIngestDataSourceProcessor.class)}
57)
59
60 private final static String DATA_SOURCE_TYPE = NbBundle.getMessage(ImageDSProcessor.class, "ImageDSProcessor.dsType.text");
61 private final Logger logger = Logger.getLogger(ImageDSProcessor.class.getName());
62 private static final List<String> allExt = new ArrayList<>();
66 private static final String ALL_DESC = NbBundle.getMessage(ImageDSProcessor.class, "ImageDSProcessor.allDesc.text");
67 private static final GeneralFilter allFilter = new GeneralFilter(allExt, ALL_DESC);
68 private static final List<FileFilter> filtersList = new ArrayList<>();
70 private AddImageTask addImageTask;
71 private IngestStream ingestStream = null;
72 private Image image = null;
73 /*
74 * TODO: Remove the setDataSourceOptionsCalled flag and the settings fields
75 * when the deprecated method setDataSourceOptions is removed.
76 */
77 private String deviceId;
78 private String imagePath;
79 private int sectorSize;
80 private String timeZone;
81 private boolean ignoreFatOrphanFiles;
82 private String md5;
83 private String sha1;
84 private String sha256;
85 private Host host = null;
86 private String password;
87
88 static {
96 }
97
107
113 static List<FileFilter> getFileFiltersList() {
114 return filtersList;
115 }
116
124 public static String getType() {
125 return DATA_SOURCE_TYPE;
126 }
127
135 @Override
136 public String getDataSourceType() {
137 return getType();
138 }
139
148 @Override
149 public JPanel getPanel() {
150 configPanel.reset();
151 configPanel.readSettings();
152 configPanel.select();
153 return configPanel;
154 }
155
163 @Override
164 public boolean isPanelValid() {
165 // before attempting to validate the panel (a potentially long running operation),
166 // check if the validation is loading or on delay.
167 return !configPanel.isValidationLoading() && configPanel.validatePanel();
168 }
169
184 @Override
186 run(null, null, progressMonitor, callback);
187 }
188
204 @Override
205 public void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
206 run(null, host, progressMonitor, callback);
207 }
208
209
210 @Override
211 public void run(String password, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
212 ingestStream = new DefaultIngestStream();
214 this.host = host;
215 this.password = Objects.toString(password, this.password);
216 try {
217 image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
218 new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, this.password, this.host);
219 } catch (TskCoreException ex) {
220 logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
221 final List<String> errors = new ArrayList<>();
222 errors.add(ex.getMessage());
224 return;
225 }
226
227 doAddImageProcess(deviceId, imagePath, sectorSize, timeZone, ignoreFatOrphanFiles, md5, sha1, sha256, this.password, progressMonitor, callback);
228 }
229
230
252 public void run(String deviceId, String imagePath, String timeZone, boolean ignoreFatOrphanFiles, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
253 ingestStream = new DefaultIngestStream();
254 try {
255 image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
256 new String[]{imagePath}, sectorSize, timeZone, "", "", "", deviceId, null, null);
257 } catch (TskCoreException ex) {
258 logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
259 final List<String> errors = new ArrayList<>();
260 errors.add(ex.getMessage());
262 return;
263 }
264
265 doAddImageProcess(deviceId, imagePath, 0, timeZone, ignoreFatOrphanFiles, null, null, null, this.password, progressMonitor, callback);
266 }
267
268
269
287 @Override
290 runWithIngestStream(null, null, settings, progress, callBack);
291 }
292
311 @Override
316
317
318 @Override
319 public void runWithIngestStream(String password, Host host, IngestJobSettings settings,
321
322 // Read the settings from the wizard
324 this.host = host;
325 this.password = Objects.toString(password, this.password);
326
327 // Set up the data source before creating the ingest stream
328 try {
329 image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
330 new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, this.password, this.host);
331 } catch (TskCoreException ex) {
332 logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
333 final List<String> errors = new ArrayList<>();
334 errors.add(ex.getMessage());
336 return;
337 }
338
339 // Now initialize the ingest stream
340 try {
342 } catch (TskCoreException ex) {
343 logger.log(Level.SEVERE, "Error starting ingest modules", ex);
344 // There was an error with ingest, but the data source has already been added
345 // so proceed with the defaultIngestStream. Code in openIngestStream
346 // should have caused a dialog to popup with the errors.
347 ingestStream = new DefaultIngestStream();
348 }
349
351 }
352
353
357 private void readConfigSettings() {
358 configPanel.storeSettings();
359 deviceId = UUID.randomUUID().toString();
360 imagePath = configPanel.getContentPaths();
361 sectorSize = configPanel.getSectorSize();
362 timeZone = configPanel.getTimeZone();
363 ignoreFatOrphanFiles = configPanel.getNoFatOrphans();
364 md5 = configPanel.getMd5();
365 if (md5.isEmpty()) {
366 md5 = null;
367 }
368 sha1 = configPanel.getSha1();
369 if (sha1.isEmpty()) {
370 sha1 = null;
371 }
372 sha256 = configPanel.getSha256();
373 if (sha256.isEmpty()) {
374 sha256 = null;
375 }
376 this.password = configPanel.getPassword();
377 if (this.password.isEmpty()) {
378 password = null;
379 }
380 }
381
387 @Override
388 public boolean supportsIngestStream() {
389 return true;
390 }
391
392
423 private void doAddImageProcess(String deviceId, String imagePath, int sectorSize, String timeZone, boolean ignoreFatOrphanFiles, String md5, String sha1, String sha256, String password, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
424
425 // If the data source or ingest stream haven't been initialized, stop processing
426 if (ingestStream == null) {
427 String message = "Ingest stream was not initialized before running the add image process on " + imagePath;
428 logger.log(Level.SEVERE, message);
429 final List<String> errors = new ArrayList<>();
430 errors.add(message);
432 return;
433 }
434 if (image == null) {
435 String message = "Image was not added to database before running the add image process on " + imagePath;
436 logger.log(Level.SEVERE, message);
437 final List<String> errors = new ArrayList<>();
438 errors.add(message);
440 return;
441 }
442
443 AddImageTask.ImageDetails imageDetails = new AddImageTask.ImageDetails(deviceId, image, sectorSize, timeZone, ignoreFatOrphanFiles, md5, sha1, sha256, null, password);
444 addImageTask = new AddImageTask(imageDetails,
445 progressMonitor,
446 new StreamingAddDataSourceCallbacks(ingestStream),
447 new StreamingAddImageTaskCallback(ingestStream, callback));
448 new Thread(addImageTask).start();
449 }
450
458 @Override
459 public void cancel() {
460 if (null != addImageTask) {
461 addImageTask.cancelTask();
462 }
463 if (ingestStream != null) {
464 ingestStream.stop();
465 }
466 }
467
472 @Override
473 public void reset() {
474 deviceId = null;
475 imagePath = null;
476 timeZone = null;
477 ignoreFatOrphanFiles = false;
478 host = null;
479 password = null;
480 configPanel.reset();
481 }
482
483 private static boolean isAcceptedByFiler(File file, List<FileFilter> filters) {
484 for (FileFilter filter : filters) {
485 if (filter.accept(file)) {
486 return true;
487 }
488 }
489 return false;
490 }
491
492 @Override
493 public int canProcess(Path dataSourcePath) throws AutoIngestDataSourceProcessorException {
494 return canProcess(dataSourcePath, null);
495 }
496
497
498
499 @Override
500 public int canProcess(Path dataSourcePath, String password) throws AutoIngestDataSourceProcessorException {
501
502 // check file extension for supported types
503 if (!isAcceptedByFiler(dataSourcePath.toFile(), filtersList)) {
504 return 0;
505 }
506
507 try {
508 if (password == null) {
509
510 // verify that the image has a file system that TSK can process
511 if (!DataSourceUtils.imageHasFileSystem(dataSourcePath)) {
512 // image does not have a file system that TSK can process
513 return 0;
514 }
515 } else {
516 // verify that the image has a file system that TSK can process
517 if (!DataSourceUtils.imageHasFileSystem(dataSourcePath, password)) {
518 // image does not have a file system that TSK can process
519 return 0;
520 }
521
522 }
523 } catch (Exception ex) {
524 throw new AutoIngestDataSourceProcessorException("Exception inside canProcess() method", ex);
525 }
526
527 // able to process the data source
528 return 100;
529 }
530
531 @Override
532 public void process(String deviceId, Path dataSourcePath, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
533 process(deviceId, dataSourcePath, null, null, progressMonitor, callBack);
534 }
535
536 @Override
537 public void process(String deviceId, Path dataSourcePath, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
538 process(deviceId, dataSourcePath, null, host, progressMonitor, callBack);
539 }
540
541 @Override
542 public void process(String deviceId, Path dataSourcePath, String password, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
543 // this method does not use the config panel
544 this.deviceId = deviceId;
545 this.imagePath = dataSourcePath.toString();
546 this.sectorSize = 0;
547 this.timeZone = Calendar.getInstance().getTimeZone().getID();
548 this.password = Objects.toString(password, this.password);
549 this.host = host;
550 this.ignoreFatOrphanFiles = false;
551
552 ingestStream = new DefaultIngestStream();
553 try {
554 image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
555 new String[]{imagePath}, sectorSize, timeZone, "", "", "", deviceId, this.password, host);
556 } catch (TskCoreException ex) {
557 logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
558 final List<String> errors = new ArrayList<>();
559 errors.add(ex.getMessage());
561 return;
562 }
563
564 doAddImageProcess(deviceId, dataSourcePath.toString(), sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, this.password, progressMonitor, callBack);
565 }
566
567
568
569 @Override
571 return processWithIngestStream(deviceId, dataSourcePath, null, null, settings, progressMonitor, callBack);
572 }
573
574 @Override
575 public IngestStream processWithIngestStream(String deviceId, Path dataSourcePath, Host host, IngestJobSettings settings, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
576 return processWithIngestStream(deviceId, dataSourcePath, null, host, settings, progressMonitor, callBack);
577 }
578
579 @Override
580 public IngestStream processWithIngestStream(String deviceId, Path dataSourcePath, String password, Host host, IngestJobSettings settings, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
581 // this method does not use the config panel
582 this.deviceId = deviceId;
583 this.imagePath = dataSourcePath.toString();
584 this.sectorSize = 0;
585 this.timeZone = Calendar.getInstance().getTimeZone().getID();
586 this.host = host;
587 this.password = Objects.toString(password, this.password);
588 this.ignoreFatOrphanFiles = false;
589
590 // Set up the data source before creating the ingest stream
591 try {
592 image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),
593 new String[]{imagePath}, sectorSize, timeZone, md5, sha1, sha256, deviceId, password, host);
594 } catch (TskCoreException ex) {
595 logger.log(Level.SEVERE, "Error adding data source with path " + imagePath + " to database", ex);
596 final List<String> errors = new ArrayList<>();
597 errors.add(ex.getMessage());
599 return null;
600 }
601
602 // Now initialize the ingest stream
603 try {
605 } catch (TskCoreException ex) {
606 logger.log(Level.SEVERE, "Error starting ingest modules", ex);
607 final List<String> errors = new ArrayList<>();
608 errors.add(ex.getMessage());
610 return null;
611 }
612
613 doAddImageProcess(deviceId, dataSourcePath.toString(), sectorSize, timeZone, ignoreFatOrphanFiles, null, null, null, password, progressMonitor, callBack);
614
615 return ingestStream;
616 }
617
618
619}
static final List< String > VIRTUAL_MACHINE_EXTS
void run(String password, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback)
int canProcess(Path dataSourcePath, String password)
void process(String deviceId, Path dataSourcePath, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack)
void process(String deviceId, Path dataSourcePath, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack)
void runWithIngestStream(IngestJobSettings settings, DataSourceProcessorProgressMonitor progress, DataSourceProcessorCallback callBack)
IngestStream processWithIngestStream(String deviceId, Path dataSourcePath, IngestJobSettings settings, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack)
void doAddImageProcess(String deviceId, String imagePath, int sectorSize, String timeZone, boolean ignoreFatOrphanFiles, String md5, String sha1, String sha256, String password, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback)
void run(String deviceId, String imagePath, String timeZone, boolean ignoreFatOrphanFiles, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback)
void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback)
void runWithIngestStream(String password, Host host, IngestJobSettings settings, DataSourceProcessorProgressMonitor progress, DataSourceProcessorCallback callBack)
void process(String deviceId, Path dataSourcePath, String password, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack)
void runWithIngestStream(Host host, IngestJobSettings settings, DataSourceProcessorProgressMonitor progress, DataSourceProcessorCallback callBack)
IngestStream processWithIngestStream(String deviceId, Path dataSourcePath, Host host, IngestJobSettings settings, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack)
void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback)
static boolean isAcceptedByFiler(File file, List< FileFilter > filters)
IngestStream processWithIngestStream(String deviceId, Path dataSourcePath, String password, Host host, IngestJobSettings settings, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack)
static synchronized ImageFilePanel createInstance(String context, List< FileFilter > fileChooserFilters)
void done(DataSourceProcessorResult result, List< String > errList, List< Content > newDataSources)
static boolean imageHasFileSystem(Path dataSourcePath)
synchronized static Logger getLogger(String name)
Definition Logger.java:124
static synchronized IngestManager getInstance()
IngestStream openIngestStream(DataSource dataSource, IngestJobSettings settings)

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.