/* * * Autopsy Forensic Browser * * Copyright 2012-2014 Basis Technology Corp. * * Copyright 2012 42six Solutions. * Contact: aebadirad <at> 42six <dot> com * Project Contact/Architect: carrier <at> sleuthkit <dot> org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.sleuthkit.autopsy.report; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.util.List; import java.util.logging.Level; import javax.swing.JPanel; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.report.ReportProgressPanel.ReportStatus; import org.sleuthkit.datamodel.*; /** * ReportBodyFile generates a report in the body file format specified on The * Sleuth Kit wiki as * MD5|name|inode|mode_as_string|UID|GID|size|atime|mtime|ctime|crtime. */ class ReportBodyFile implements GeneralReportModule { private static final Logger logger = Logger.getLogger(ReportBodyFile.class.getName()); private static ReportBodyFile instance = null; private Case currentCase; private SleuthkitCase skCase; private String reportPath; // Hidden constructor for the report private ReportBodyFile() { } // Get the default implementation of this report public static synchronized ReportBodyFile getDefault() { if (instance == null) { instance = new ReportBodyFile(); } return instance; } /** * Generates a body file format report for use with the MAC time tool. * * @param baseReportDir path to save the report * @param progressPanel panel to update the report's progress */ @Override @SuppressWarnings("deprecation") public void generateReport(String baseReportDir, ReportProgressPanel progressPanel) { // Start the progress bar and setup the report progressPanel.setIndeterminate(false); progressPanel.start(); progressPanel.updateStatusLabel(NbBundle.getMessage(this.getClass(), "ReportBodyFile.progress.querying")); reportPath = baseReportDir + "BodyFile.txt"; //NON-NLS currentCase = Case.getCurrentCase(); skCase = currentCase.getSleuthkitCase(); // Run query to get all files try { // exclude non-fs files/dirs and . and .. files final String query = "type = " + TskData.TSK_DB_FILES_TYPE_ENUM.FS.getFileType() //NON-NLS + " AND name != '.' AND name != '..'"; //NON-NLS progressPanel.updateStatusLabel(NbBundle.getMessage(this.getClass(), "ReportBodyFile.progress.loading")); List<AbstractFile> fs = skCase.findAllFilesWhere(query); // Check if ingest has finished String ingestwarning = ""; if (IngestManager.getInstance().isIngestRunning()) { ingestwarning = NbBundle.getMessage(this.getClass(), "ReportBodyFile.ingestWarning.text"); } int size = fs.size(); progressPanel.setMaximumProgress(size / 100); BufferedWriter out = null; try { // MD5|name|inode|mode_as_string|UID|GID|size|atime|mtime|ctime|crtime out = new BufferedWriter(new FileWriter(reportPath, true)); out.write(ingestwarning); // Loop files and write info to report int count = 0; for (AbstractFile file : fs) { if (progressPanel.getStatus() == ReportStatus.CANCELED) { break; } if (count++ == 100) { progressPanel.increment(); progressPanel.updateStatusLabel( NbBundle.getMessage(this.getClass(), "ReportBodyFile.progress.processing", file.getName())); count = 0; } if (file.getMd5Hash() != null) { out.write(file.getMd5Hash()); } out.write("|"); if (file.getUniquePath() != null) { out.write(file.getUniquePath()); } out.write("|"); out.write(Long.toString(file.getMetaAddr())); out.write("|"); String modeString = file.getModesAsString(); if (modeString != null) { out.write(modeString); } out.write("|"); out.write(Long.toString(file.getUid())); out.write("|"); out.write(Long.toString(file.getGid())); out.write("|"); out.write(Long.toString(file.getSize())); out.write("|"); out.write(Long.toString(file.getAtime())); out.write("|"); out.write(Long.toString(file.getMtime())); out.write("|"); out.write(Long.toString(file.getCtime())); out.write("|"); out.write(Long.toString(file.getCrtime())); out.write("\n"); } } catch (IOException ex) { logger.log(Level.WARNING, "Could not write the temp body file report.", ex); //NON-NLS } finally { try { if (out != null) { out.flush(); out.close(); Case.getCurrentCase().addReport(reportPath, NbBundle.getMessage(this.getClass(), "ReportBodyFile.generateReport.srcModuleName.text"), ""); } } catch (IOException ex) { logger.log(Level.WARNING, "Could not flush and close the BufferedWriter.", ex); //NON-NLS } catch (TskCoreException ex) { String errorMessage = String.format("Error adding %s to case as a report", reportPath); //NON-NLS logger.log(Level.SEVERE, errorMessage, ex); } } progressPanel.complete(ReportStatus.COMPLETE); } catch (TskCoreException ex) { logger.log(Level.WARNING, "Failed to get the unique path.", ex); //NON-NLS } } @Override public String getName() { String name = NbBundle.getMessage(this.getClass(), "ReportBodyFile.getName.text"); return name; } @Override public String getRelativeFilePath() { return NbBundle.getMessage(this.getClass(), "ReportBodyFile.getFilePath.text"); } @Override public String getDescription() { String desc = NbBundle.getMessage(this.getClass(), "ReportBodyFile.getDesc.text"); return desc; } @Override public JPanel getConfigurationPanel() { return null; // No configuration panel } }