Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
LocalFilesDSProcessor.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2011-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.io.IOException;
23import java.nio.file.Path;
24import java.nio.file.Paths;
25import java.util.ArrayList;
26import java.util.Arrays;
27import java.util.List;
28import java.util.UUID;
29import java.util.logging.Level;
30import javax.swing.JPanel;
31import javax.swing.filechooser.FileFilter;
32import org.apache.commons.io.FilenameUtils;
33import org.openide.modules.InstalledFileLocator;
34import org.openide.util.NbBundle;
35import org.openide.util.NbBundle.Messages;
36import org.openide.util.lookup.ServiceProvider;
37import org.openide.util.lookup.ServiceProviders;
38import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
39import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
40import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
41import org.sleuthkit.autopsy.coreutils.ExecUtil;
42import org.sleuthkit.autopsy.coreutils.Logger;
43import org.sleuthkit.autopsy.coreutils.PlatformUtil;
44import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor;
45import org.sleuthkit.datamodel.Host;
46import org.sleuthkit.datamodel.TskCoreException;
47
54@ServiceProviders(value = {
55 @ServiceProvider(service = DataSourceProcessor.class),
56 @ServiceProvider(service = AutoIngestDataSourceProcessor.class)
57})
58@Messages({
59 "LocalFilesDSProcessor.logicalEvidenceFilter.desc=Logical Evidence Files (L01)"
60})
62
63 private static final String DATA_SOURCE_TYPE = NbBundle.getMessage(LocalFilesDSProcessor.class, "LocalFilesDSProcessor.dsType");
64 private static final Logger logger = Logger.getLogger(LocalFilesDSProcessor.class.getName());
65 private final LogicalFilesDspPanel configPanel;
66 private static final String L01_EXTRACTION_DIR = "L01";
67 private static final String UNIQUENESS_CONSTRAINT_SEPERATOR = "_";
68 private static final String EWFEXPORT_DIR = "ewfexport_exec"; // NON-NLS
69 private static final String EWFEXPORT_32_BIT_DIR = "32-bit"; // NON-NLS
70 private static final String EWFEXPORT_64_BIT_DIR = "64-bit"; // NON-NLS
71 private static final String EWFEXPORT_WINDOWS_EXE = "ewfexport.exe"; // NON-NLS
72 private static final String LOG_FILE_EXTENSION = ".txt";
73 private static final List<String> LOGICAL_EVIDENCE_EXTENSIONS = Arrays.asList(".l01");
74 private static final String LOGICAL_EVIDENCE_DESC = Bundle.LocalFilesDSProcessor_logicalEvidenceFilter_desc();
76 /*
77 * TODO: Remove the setDataSourceOptionsCalled flag and the settings fields
78 * when the deprecated method setDataSourceOptions is removed.
79 */
80 private List<String> localFilePaths;
81
89 configPanel = LogicalFilesDspPanel.getDefault();
90 }
91
99 public static String getType() {
100 return DATA_SOURCE_TYPE;
101 }
102
110 @Override
111 public String getDataSourceType() {
112 return DATA_SOURCE_TYPE;
113 }
114
123 @Override
124 public JPanel getPanel() {
125 configPanel.select();
126 return configPanel;
127 }
128
136 @Override
137 public boolean isPanelValid() {
138 return configPanel.validatePanel();
139 }
140
155 @Override
157 run(null, progressMonitor, callback);
158 }
159
175 @Override
176 public void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
177
178 localFilePaths = configPanel.getContentPaths();
179 boolean createTimestamp = configPanel.getCreateTimestamp();
180 boolean modifiedTimestamp = configPanel.getModifiedTimestamp();
181 boolean accessTimestamp = configPanel.getAccessTimestamp();
182 if (configPanel.subTypeIsLogicalEvidencePanel()) {
183 try {
184 //if the L01 option was chosen
186 } catch (L01Exception ex) {
187 //contents of l01 could not be extracted don't add data source or run ingest
188 final List<String> errors = new ArrayList<>();
189 errors.add(ex.getMessage());
191 return;
192 } catch (NoCurrentCaseException ex) {
193 logger.log(Level.WARNING, "Exception while getting open case.", ex);
194 return;
195 }
196 }
197 run(UUID.randomUUID().toString(), configPanel.getFileSetName(), localFilePaths, host, createTimestamp,
198 accessTimestamp, modifiedTimestamp, progressMonitor, callback);
199 }
200
213 private List<String> extractLogicalEvidenceFileContents(final List<String> logicalEvidenceFilePaths) throws L01Exception, NoCurrentCaseException {
214 final List<String> extractedPaths = new ArrayList<>();
215 Path ewfexportPath;
216 ewfexportPath = locateEwfexportExecutable();
217 List<String> command = new ArrayList<>();
218 for (final String l01Path : logicalEvidenceFilePaths) {
219 command.clear();
220 command.add(ewfexportPath.toAbsolutePath().toString());
221 command.add("-f");
222 command.add("files");
223 command.add("-t");
225 if (!l01Dir.exists()) {
226 l01Dir.mkdirs();
227 }
228 Path dirPath = Paths.get(FilenameUtils.getBaseName(l01Path) + UNIQUENESS_CONSTRAINT_SEPERATOR + System.currentTimeMillis());
229
230 command.add(dirPath.toString());
231 command.add(l01Path);
232 ProcessBuilder processBuilder = new ProcessBuilder(command);
233 processBuilder.directory(l01Dir);
234 try {
235 //redirect ewfexport stdout and stderr to txt file
236 Path logFileName = Paths.get(l01Dir.toString(), dirPath.toString() + LOG_FILE_EXTENSION);
237 File logFile = new File(logFileName.toString());
238 Path errFileName = Paths.get(l01Dir.toString(), dirPath.toString() + LOG_FILE_EXTENSION);
239 File errFile = new File(errFileName.toString());
240 processBuilder.redirectError(ProcessBuilder.Redirect.appendTo(errFile));
241 processBuilder.redirectOutput(ProcessBuilder.Redirect.appendTo(logFile));
242 // open the file with ewfexport to extract its contents
243 ExecUtil.execute(processBuilder, new ExecUtil.TimedProcessTerminator());
244 if (l01Dir.toPath().resolve(dirPath).toFile().exists()) {
245 extractedPaths.add(l01Dir.toPath().resolve(dirPath).toString());
246 } else { //if we failed to extract anything let the user know the L01 file was unable to be processed
247 throw new L01Exception("Can not process the selected L01 file, ewfExport was unable to extract any files from it.");
248 }
249
250 } catch (SecurityException ex) {
251 throw new L01Exception("Security exception occcured while trying to extract l01 contents", ex);
252 } catch (IOException ex) {
253 throw new L01Exception("IOException occcured while trying to extract l01 contents", ex);
254 }
255 }
256 return extractedPaths;
257 }
258
264 static FileFilter getLogicalEvidenceFilter() {
265 return LOGICAL_EVIDENCE_FILTER;
266 }
267
277 // Must be running under a Windows operating system.
278 if (!PlatformUtil.isWindowsOS()) {
279 throw new L01Exception("L01 files are only supported on windows currently");
280 }
281
282 // Build the expected path to either the 32-bit or 64-bit version of the
283 // ewfexport executable.
284 final File ewfRoot = InstalledFileLocator.getDefault().locate(EWFEXPORT_DIR, LocalFilesDSProcessor.class.getPackage().getName(), false);
285
286 Path executablePath;
287 if (PlatformUtil.is64BitOS()) {
288 executablePath = Paths.get(
289 ewfRoot.getAbsolutePath(),
292 } else {
293 executablePath = Paths.get(
294 ewfRoot.getAbsolutePath(),
297 }
298
299 // Make sure the executable exists at the expected location and that it
300 // can be run.
301 final File ewfexport = executablePath.toFile();
302 if (null == ewfexport || !ewfexport.exists()) {
303 throw new LocalFilesDSProcessor.L01Exception("EWF export executable was not found");
304 }
305 if (!ewfexport.canExecute()) {
306 throw new LocalFilesDSProcessor.L01Exception("EWF export executable can not be executed");
307 }
308
309 return executablePath;
310 }
311
336 public void run(String deviceId, String rootVirtualDirectoryName, List<String> localFilePaths, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
337 new Thread(new AddLocalFilesTask(deviceId, rootVirtualDirectoryName, localFilePaths, host, false, false, false,progressMonitor, callback)).start();
338 }
339
367 public void run(String deviceId, String rootVirtualDirectoryName, List<String> localFilePaths, Host host, boolean createTimestamp, boolean accessTimestamp,
368 boolean modifiedTimestamp, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
369 new Thread(new AddLocalFilesTask(deviceId, rootVirtualDirectoryName, localFilePaths, host, createTimestamp, accessTimestamp, modifiedTimestamp,
370 progressMonitor, callback)).start();
371 }
372
396 public void run(String deviceId, String rootVirtualDirectoryName, List<String> localFilePaths, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
397 run(deviceId, rootVirtualDirectoryName, localFilePaths, null, progressMonitor, callback);
398 }
399
410 @Override
411 public void cancel() {
412 }
413
418 @Override
419 public void reset() {
420 configPanel.select();
421 localFilePaths = null;
422 }
423
424 @Override
425 public int canProcess(Path dataSourcePath) throws AutoIngestDataSourceProcessorException {
426 // Local files DSP can process any file by simply adding it as a logical file.
427 // It should return lowest possible non-zero confidence level and be treated
428 // as the "option of last resort" for auto ingest purposes
429
430 List<String> filePaths = Arrays.asList(new String[]{dataSourcePath.toString()});
431 //If there is only 1 file check if it is an L01 file and if it is extract the
432 //contents and replace the paths, if the contents can't be extracted return 0
433 if (filePaths.size() == 1) {
434 for (final String path : filePaths) {
435 if (new File(path).isFile() && LOGICAL_EVIDENCE_FILTER.accept(new File(path))) {
436 try {
437 //if the L01 option was chosen
438 filePaths = extractLogicalEvidenceFileContents(filePaths);
439 } catch (L01Exception ex) {
440 logger.log(Level.WARNING, "File extension was .l01 but contents of logical evidence file were unable to be extracted", ex);
441 //contents of l01 could not be extracted don't add data source or run ingest
442 return 0;
443 } catch (NoCurrentCaseException ex) {
444 logger.log(Level.WARNING, "Exception while getting open case.", ex);
445 return 0;
446 }
447 }
448 }
449 }
450 return 1;
451 }
452
453 @Override
454 public void process(String deviceId, Path dataSourcePath, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
455 process(deviceId, dataSourcePath, null, progressMonitor, callBack);
456 }
457
458 @Override
459 public void process(String deviceId, Path dataSourcePath, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
460 List<String> filePaths = Arrays.asList(new String[]{dataSourcePath.toString()});
461 run(deviceId, "", filePaths, host, progressMonitor, callBack);
462 }
463
467 private final class L01Exception extends Exception {
468
469 private static final long serialVersionUID = 1L;
470
471 L01Exception(final String message) {
472 super(message);
473 }
474
475 L01Exception(final String message, final Throwable cause) {
476 super(message, cause);
477 }
478 }
479
480}
void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback)
void run(String deviceId, String rootVirtualDirectoryName, List< String > localFilePaths, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback)
void run(String deviceId, String rootVirtualDirectoryName, List< String > localFilePaths, Host host, boolean createTimestamp, boolean accessTimestamp, boolean modifiedTimestamp, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback)
void process(String deviceId, Path dataSourcePath, Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack)
void run(String deviceId, String rootVirtualDirectoryName, List< String > localFilePaths, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback)
void process(String deviceId, Path dataSourcePath, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack)
List< String > extractLogicalEvidenceFileContents(final List< String > logicalEvidenceFilePaths)
void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback)
void done(DataSourceProcessorResult result, List< String > errList, List< Content > newDataSources)
static int execute(ProcessBuilder processBuilder)
synchronized static Logger getLogger(String name)
Definition Logger.java:124

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