mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 18:17:43 +00:00
Merge pull request #2340 from zhhl/1968-moveBulkExtractor
1968 move bulk extractor
This commit is contained in:
commit
c65672de36
Binary file not shown.
Binary file not shown.
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
|
* Contact: 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.experimental.ingestmodules.bulkextractor;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ingest job settings for the Bulk Extractor ingest module.
|
||||||
|
*/
|
||||||
|
final class BulkExtractorIngestJobSettings implements IngestModuleIngestJobSettings {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private final boolean onlyProcessUnallocatedSpace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs serializable ingest job settings for the Bulk Extractor ingest
|
||||||
|
* module.
|
||||||
|
*
|
||||||
|
* @param onlyProcessUnallocatedSpace Whether or not only unallocated space
|
||||||
|
* should be processed; if not, the
|
||||||
|
* entire disk image is scanned.
|
||||||
|
*/
|
||||||
|
BulkExtractorIngestJobSettings(boolean onlyProcessUnallocatedSpace) {
|
||||||
|
this.onlyProcessUnallocatedSpace = onlyProcessUnallocatedSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long getVersionNumber() {
|
||||||
|
return BulkExtractorIngestJobSettings.serialVersionUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries whether or not to process only unallocated space; if not, the
|
||||||
|
* entire disk image is scanned.
|
||||||
|
*
|
||||||
|
* @return True if only unallocated space is to be processed, false
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
boolean shouldOnlyProcessUnallocatedSpace() {
|
||||||
|
return this.onlyProcessUnallocatedSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="processUnallocatedSpaceCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace pref="83" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="processUnallocatedSpaceCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace pref="151" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JCheckBox" name="processUnallocatedSpaceCheckBox">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/ingestmodules/bulkextractor/Bundle.properties" key="BulkExtractorIngestJobSettingsPanel.processUnallocatedSpaceCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
|
* Contact: 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.experimental.ingestmodules.bulkextractor;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ingest job settings panel for the Bulk Extractor ingest module.
|
||||||
|
*/
|
||||||
|
final class BulkExtractorIngestJobSettingsPanel extends IngestModuleIngestJobSettingsPanel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an ingest job settings panel for the Bulk Extractor ingest
|
||||||
|
* module.
|
||||||
|
*
|
||||||
|
* @param settings The settings to use to initialize the panel.
|
||||||
|
*/
|
||||||
|
BulkExtractorIngestJobSettingsPanel(BulkExtractorIngestJobSettings settings) {
|
||||||
|
initComponents();
|
||||||
|
this.processUnallocatedSpaceCheckBox.setSelected(settings.shouldOnlyProcessUnallocatedSpace());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IngestModuleIngestJobSettings getSettings() {
|
||||||
|
return new BulkExtractorIngestJobSettings(this.processUnallocatedSpaceCheckBox.isSelected());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called from within the constructor to initialize the form.
|
||||||
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
|
* regenerated by the Form Editor.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
|
private void initComponents() {
|
||||||
|
|
||||||
|
processUnallocatedSpaceCheckBox = new javax.swing.JCheckBox();
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(processUnallocatedSpaceCheckBox, org.openide.util.NbBundle.getMessage(BulkExtractorIngestJobSettingsPanel.class, "BulkExtractorIngestJobSettingsPanel.processUnallocatedSpaceCheckBox.text")); // NOI18N
|
||||||
|
|
||||||
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
|
this.setLayout(layout);
|
||||||
|
layout.setHorizontalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addComponent(processUnallocatedSpaceCheckBox)
|
||||||
|
.addContainerGap(83, Short.MAX_VALUE))
|
||||||
|
);
|
||||||
|
layout.setVerticalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addComponent(processUnallocatedSpaceCheckBox)
|
||||||
|
.addContainerGap(151, Short.MAX_VALUE))
|
||||||
|
);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JCheckBox processUnallocatedSpaceCheckBox;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
}
|
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
|
* Contact: 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.experimental.ingestmodules.bulkextractor;
|
||||||
|
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Version;
|
||||||
|
import org.sleuthkit.autopsy.ingest.DataSourceIngestModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.FileIngestModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleFactory;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A factory for creating instances of data source and file ingest modules that
|
||||||
|
* use Bulk Extractor to scan either an entire disk image or unallocated space
|
||||||
|
* files, respectively.
|
||||||
|
*/
|
||||||
|
@ServiceProvider(service = IngestModuleFactory.class)
|
||||||
|
public class BulkExtractorIngestModuleFactory extends IngestModuleFactoryAdapter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getModuleDisplayName() {
|
||||||
|
return Utilities.getModuleName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getModuleDescription() {
|
||||||
|
return NbBundle.getMessage(BulkExtractorIngestModuleFactory.class, "BulkExtractorIngestModuleFactory.moduleDescription");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getModuleVersionNumber() {
|
||||||
|
return Utilities.getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IngestModuleIngestJobSettings getDefaultIngestJobSettings() {
|
||||||
|
// Process the entire image by default.
|
||||||
|
return new BulkExtractorIngestJobSettings(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean hasIngestJobSettingsPanel() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IngestModuleIngestJobSettingsPanel getIngestJobSettingsPanel(IngestModuleIngestJobSettings settings) {
|
||||||
|
if (!(settings instanceof BulkExtractorIngestJobSettings)) {
|
||||||
|
throw new IllegalArgumentException("Settings not instanceof src.org.sleuthkit.autopsy.bulkextractor.BulkExtractorIngestJobSettings"); // NON_NLS
|
||||||
|
}
|
||||||
|
return new BulkExtractorIngestJobSettingsPanel((BulkExtractorIngestJobSettings) settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isDataSourceIngestModuleFactory() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public DataSourceIngestModule createDataSourceIngestModule(IngestModuleIngestJobSettings settings) {
|
||||||
|
if (!(settings instanceof BulkExtractorIngestJobSettings)) {
|
||||||
|
throw new IllegalArgumentException("Settings not instanceof src.org.sleuthkit.autopsy.bulkextractor.BulkExtractorIngestJobSettings"); // NON_NLS
|
||||||
|
}
|
||||||
|
return new DiskImageIngestModule((BulkExtractorIngestJobSettings) settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isFileIngestModuleFactory() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) {
|
||||||
|
if (!(settings instanceof BulkExtractorIngestJobSettings)) {
|
||||||
|
throw new IllegalArgumentException("Settings not instanceof src.org.sleuthkit.autopsy.bulkextractor.BulkExtractorIngestJobSettings"); // NON_NLS
|
||||||
|
}
|
||||||
|
return new UnallocatedSpaceIngestModule((BulkExtractorIngestJobSettings) settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
OpenIDE-Module-Name=Bulk Extractor Ingest Module
|
||||||
|
OpenIDE-Module-Display-Category=Ingest Module
|
||||||
|
OpenIDE-Module-Long-Description=Bulk Extractor ingest module. \n\n Runs the Bulk Extractor executable against an image data source.
|
||||||
|
OpenIDE-Module-Short-Description=Bulk Extractor ingest module.
|
||||||
|
Utilities.moduleName=Bulk Extractor
|
||||||
|
BulkExtractorIngestModuleFactory.moduleDescription=Runs the Bulk Extractor executable against an image data source.
|
||||||
|
BulkExtractorIngestJobSettingsPanel.processUnallocatedSpaceCheckBox.text=Only process unallocated space
|
||||||
|
BulkExtractorIngestModule.processTerminated=Bulk Extractor process was terminated due to exceeding max allowable run time when scanning
|
||||||
|
BulkExtractorIngestModule.moduleError=Bulk Extractor Module Error
|
@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
|
* Contact: 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.experimental.ingestmodules.bulkextractor;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
|
import org.sleuthkit.autopsy.ingest.ProcTerminationCode;
|
||||||
|
import org.sleuthkit.autopsy.ingest.DataSourceIngestModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProcessTerminator;
|
||||||
|
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModule;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
import org.sleuthkit.datamodel.Image;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A data source ingest module that runs the Bulk Extractor executable with an
|
||||||
|
* entire disk image as input.
|
||||||
|
*/
|
||||||
|
public class DiskImageIngestModule implements DataSourceIngestModule {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(DiskImageIngestModule.class.getName());
|
||||||
|
private final BulkExtractorIngestJobSettings settings;
|
||||||
|
private IngestJobContext context;
|
||||||
|
private Path bulkExtractorPath;
|
||||||
|
private Path rootOutputDirPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a Bulk Extractor disk image ingest module.
|
||||||
|
*
|
||||||
|
* @param settings The settings for the ingest module.
|
||||||
|
*/
|
||||||
|
DiskImageIngestModule(BulkExtractorIngestJobSettings settings) {
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void startUp(IngestJobContext context) throws IngestModuleException {
|
||||||
|
this.context = context;
|
||||||
|
|
||||||
|
// Only process data sources that are disk images the user wants scanned
|
||||||
|
// in their entirety. Scans of unallocated space only are performed by
|
||||||
|
// a file ingest module.
|
||||||
|
if (!(context.getDataSource() instanceof Image) || this.settings.shouldOnlyProcessUnallocatedSpace()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bulkExtractorPath = Utilities.locateBulkExtractorExecutable();
|
||||||
|
this.rootOutputDirPath = Utilities.createOutputDirectoryForDataSource(this.context.getDataSource().getName() + "_"
|
||||||
|
+ this.context.getDataSource().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
|
||||||
|
// Only process data sources that are disk images the user wants scanned
|
||||||
|
// in their entirety. Scans of unallocated space only are performed by
|
||||||
|
// a file ingest module.
|
||||||
|
if (!(dataSource instanceof Image) || this.settings.shouldOnlyProcessUnallocatedSpace()) {
|
||||||
|
return ProcessResult.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not sure how long it will take Bulk Extractor to complete.
|
||||||
|
*/
|
||||||
|
progressBar.switchToIndeterminate();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Verify initialization succeeded.
|
||||||
|
if ((null == this.bulkExtractorPath) || (null == this.rootOutputDirPath)) {
|
||||||
|
DiskImageIngestModule.logger.log(Level.SEVERE, "Bulk Extractor disk image ingest module called after failed start up"); // NON-NLS
|
||||||
|
return ProcessResult.ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make an output directory for Bulk Extractor.
|
||||||
|
Path outputDirPath = Utilities.getOutputSubdirectoryPath(this.rootOutputDirPath, dataSource.getId());
|
||||||
|
Files.createDirectories(outputDirPath);
|
||||||
|
|
||||||
|
// Scan the disk image file with Bulk Extractor.
|
||||||
|
Image image = (Image) dataSource;
|
||||||
|
String imageFilePath = image.getPaths()[0];
|
||||||
|
DataSourceIngestModuleProcessTerminator terminator = new DataSourceIngestModuleProcessTerminator(this.context, true);
|
||||||
|
int exitValue = Utilities.runBulkExtractor(this.bulkExtractorPath, outputDirPath, Paths.get(imageFilePath), terminator);
|
||||||
|
|
||||||
|
if (terminator.getTerminationCode() == ProcTerminationCode.TIME_OUT) {
|
||||||
|
String msg = NbBundle.getMessage(this.getClass(), "BulkExtractorIngestModule.processTerminated") + image.getName(); // NON-NLS
|
||||||
|
MessageNotifyUtil.Notify.error(NbBundle.getMessage(this.getClass(), "BulkExtractorIngestModule.moduleError"), msg); // NON-NLS
|
||||||
|
DiskImageIngestModule.logger.log(Level.SEVERE, msg);
|
||||||
|
FileUtil.deleteDir(new File(outputDirPath.toAbsolutePath().toString()));
|
||||||
|
return IngestModule.ProcessResult.ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != exitValue) {
|
||||||
|
FileUtil.deleteDir(new File(outputDirPath.toAbsolutePath().toString()));
|
||||||
|
if (this.context.dataSourceIngestIsCancelled()) {
|
||||||
|
return ProcessResult.OK;
|
||||||
|
} else {
|
||||||
|
DiskImageIngestModule.logger.log(Level.SEVERE, "Bulk Extractor returned error exit value = {0} when scanning {1}", new Object[]{exitValue, image.getName()}); // NON-NLS
|
||||||
|
return ProcessResult.ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Utilities.isDirectoryEmpty(outputDirPath)) {
|
||||||
|
// Add the output directory to the case as an Autopsy report.
|
||||||
|
Case.getCurrentCase().addReport(outputDirPath.toAbsolutePath().toString(), Utilities.getModuleName(), Utilities.getReportName(image.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProcessResult.OK;
|
||||||
|
|
||||||
|
} catch (InterruptedException | IOException | SecurityException | UnsupportedOperationException | TskCoreException ex) {
|
||||||
|
DiskImageIngestModule.logger.log(Level.SEVERE, "Error processing " + dataSource.getName() + " with Bulk Extractor", ex); // NON-NLS
|
||||||
|
return ProcessResult.ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,206 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
|
* Contact: 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.experimental.ingestmodules.bulkextractor;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.ingest.ProcTerminationCode;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
|
import org.sleuthkit.autopsy.ingest.FileIngestModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.FileIngestModuleProcessTerminator;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
|
||||||
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
import org.sleuthkit.datamodel.TskData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A file ingest module that runs the Bulk Extractor executable with unallocated
|
||||||
|
* space files as input.
|
||||||
|
*/
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"SettingsWrong='Process unallocated space only' is checked for this module, but global 'Process Unallocated Space' is not checked. Unallocated space will not be processed.",
|
||||||
|
"Utilities.cannotCreateOutputDir.message=Unable to create output directory."
|
||||||
|
})
|
||||||
|
final class UnallocatedSpaceIngestModule implements FileIngestModule {
|
||||||
|
|
||||||
|
private static final String TEMP_DIR_NAME = "temp"; // NON-NLS
|
||||||
|
private static final Logger logger = Logger.getLogger(UnallocatedSpaceIngestModule.class.getName());
|
||||||
|
private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
|
||||||
|
private static final Map<Long, Path> tempPathsByJob = new ConcurrentHashMap<>();
|
||||||
|
private final BulkExtractorIngestJobSettings settings;
|
||||||
|
private IngestJobContext context;
|
||||||
|
private Path bulkExtractorPath;
|
||||||
|
private Path rootOutputDirPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a file ingest module that runs the Bulk Extractor executable
|
||||||
|
* with unallocated space files as input.
|
||||||
|
*
|
||||||
|
* @param settings The settings for the ingest module.
|
||||||
|
*/
|
||||||
|
UnallocatedSpaceIngestModule(BulkExtractorIngestJobSettings settings) {
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void startUp(IngestJobContext context) throws IngestModuleException {
|
||||||
|
this.context = context;
|
||||||
|
|
||||||
|
// Only process unallocated space files when the user does not want the
|
||||||
|
// data source to be scanned in its entirety. Scans of an entire disk
|
||||||
|
// image are performed by a data source ingest module.
|
||||||
|
if (!this.settings.shouldOnlyProcessUnallocatedSpace()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the global unallocated space processing setting and the module
|
||||||
|
// process unallocated space only setting are not in sych, throw an
|
||||||
|
// exception. Although the result would not be incorrect, it would be
|
||||||
|
// unfortunate for the user to get an accidental no-op for this module.
|
||||||
|
if (!this.context.processingUnallocatedSpace()) {
|
||||||
|
throw new IngestModuleException(Bundle.SettingsWrong());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bulkExtractorPath = Utilities.locateBulkExtractorExecutable();
|
||||||
|
this.rootOutputDirPath = Utilities.createOutputDirectoryForDataSource(this.context.getDataSource().getName() + "_"
|
||||||
|
+ this.context.getDataSource().getId());
|
||||||
|
|
||||||
|
// The first instance of the module for an ingest job creates
|
||||||
|
// a temp subdirectory as a location for writing unallocated
|
||||||
|
// space files to disk.
|
||||||
|
if (UnallocatedSpaceIngestModule.refCounter.incrementAndGet(this.context.getJobId()) == 1) {
|
||||||
|
try {
|
||||||
|
Path tempDirPath = Paths.get(this.rootOutputDirPath.toString(), UnallocatedSpaceIngestModule.TEMP_DIR_NAME + Long.toString(this.context.getJobId()));
|
||||||
|
Files.createDirectory(tempDirPath);
|
||||||
|
UnallocatedSpaceIngestModule.tempPathsByJob.put(this.context.getJobId(), tempDirPath);
|
||||||
|
} catch (SecurityException | IOException | UnsupportedOperationException ex) {
|
||||||
|
throw new IngestModule.IngestModuleException(Bundle.Utilities_cannotCreateOutputDir_message(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ProcessResult process(AbstractFile file) {
|
||||||
|
// Only process unallocated space files when the user does not want the
|
||||||
|
// data source to be scanned in its entirety. Scans of an entire disk
|
||||||
|
// image are performed by a data source ingest module.
|
||||||
|
if (!this.settings.shouldOnlyProcessUnallocatedSpace()) {
|
||||||
|
return ProcessResult.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip everything except unallocated space files.
|
||||||
|
if (file.getType() != TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) {
|
||||||
|
return ProcessResult.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
Path tempFilePath = null;
|
||||||
|
try {
|
||||||
|
// Verify initialization succeeded.
|
||||||
|
if (null == this.bulkExtractorPath) {
|
||||||
|
UnallocatedSpaceIngestModule.logger.log(Level.SEVERE, "Bulk Extractor unallocated space ingest module called after failed start up"); // NON-NLS
|
||||||
|
return ProcessResult.ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the file to disk.
|
||||||
|
Path tempDirPath = UnallocatedSpaceIngestModule.tempPathsByJob.get(this.context.getJobId());
|
||||||
|
tempFilePath = Paths.get(tempDirPath.toString(), file.getName());
|
||||||
|
ContentUtils.writeToFile(file, tempFilePath.toFile());
|
||||||
|
|
||||||
|
// Make an output directory for Bulk Extractor.
|
||||||
|
Path outputDirPath = Utilities.getOutputSubdirectoryPath(this.rootOutputDirPath, file.getId());
|
||||||
|
Files.createDirectories(outputDirPath);
|
||||||
|
|
||||||
|
// Scan the file with Bulk Extractor.
|
||||||
|
FileIngestModuleProcessTerminator terminator = new FileIngestModuleProcessTerminator(this.context, true);
|
||||||
|
int exitValue = Utilities.runBulkExtractor(this.bulkExtractorPath, outputDirPath, tempFilePath, terminator);
|
||||||
|
|
||||||
|
if (terminator.getTerminationCode() == ProcTerminationCode.TIME_OUT) {
|
||||||
|
String msg = NbBundle.getMessage(this.getClass(), "BulkExtractorIngestModule.processTerminated") + file.getName(); // NON-NLS
|
||||||
|
MessageNotifyUtil.Notify.error(NbBundle.getMessage(this.getClass(), "BulkExtractorIngestModule.moduleError"), msg); // NON-NLS
|
||||||
|
UnallocatedSpaceIngestModule.logger.log(Level.SEVERE, msg);
|
||||||
|
FileUtil.deleteDir(new File(outputDirPath.toAbsolutePath().toString()));
|
||||||
|
return IngestModule.ProcessResult.ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != exitValue) {
|
||||||
|
FileUtil.deleteDir(new File(outputDirPath.toAbsolutePath().toString()));
|
||||||
|
if (this.context.dataSourceIngestIsCancelled()) {
|
||||||
|
return ProcessResult.OK;
|
||||||
|
} else {
|
||||||
|
UnallocatedSpaceIngestModule.logger.log(Level.SEVERE, "Bulk Extractor returned error exit value = {0} when scanning unallocated space of {1}", new Object[]{exitValue, file.getName()}); // NON-NLS
|
||||||
|
return ProcessResult.ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Utilities.isDirectoryEmpty(outputDirPath)) {
|
||||||
|
// Add the output directory to the case as an Autopsy report.
|
||||||
|
Case.getCurrentCase().addReport(outputDirPath.toAbsolutePath().toString(), Utilities.getModuleName(), Utilities.getReportName(file.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProcessResult.OK;
|
||||||
|
|
||||||
|
} catch (IOException | InterruptedException | TskCoreException ex) {
|
||||||
|
UnallocatedSpaceIngestModule.logger.log(Level.SEVERE, "Error processing " + file.getName() + " with Bulk Extractor", ex); // NON-NLS
|
||||||
|
return ProcessResult.ERROR;
|
||||||
|
} finally {
|
||||||
|
if (null != tempFilePath && Files.exists(tempFilePath)) {
|
||||||
|
// Get rid of the unallocated space file.
|
||||||
|
tempFilePath.toFile().delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutDown() {
|
||||||
|
if (!this.settings.shouldOnlyProcessUnallocatedSpace()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refCounter.decrementAndGet(this.context.getJobId()) == 0) {
|
||||||
|
try {
|
||||||
|
// The last instance of this module for an ingest job deletes
|
||||||
|
// the temp dir.
|
||||||
|
Path tempDirPath = UnallocatedSpaceIngestModule.tempPathsByJob.remove(this.context.getJobId());
|
||||||
|
FileUtil.deleteDir(new File(tempDirPath.toAbsolutePath().toString()));
|
||||||
|
} catch (SecurityException ex) {
|
||||||
|
UnallocatedSpaceIngestModule.logger.log(Level.SEVERE, "Error shutting down Bulk Extractor unallocated space module", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
|
* Contact: 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.experimental.ingestmodules.bulkextractor;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.DirectoryStream;
|
||||||
|
import java.nio.file.FileAlreadyExistsException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import org.openide.modules.InstalledFileLocator;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.ExecUtil.ProcessTerminator;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility methods for the Bulk Extractor ingest module.
|
||||||
|
*/
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"Utilities.unsupportedOS.message=Bulk Extractor Module is only supported for Windows platforms.",
|
||||||
|
"Utilities.missingBulkExtractor.message=Unable to locate Bulk Extractor executable.",
|
||||||
|
"Utilities.cannotExecuteBulkExtractor.message=Unable to execute Bulk Extractor.",
|
||||||
|
"# {0} - output directory name", "Utilities.cannotCreateOutputDir.message.with.param=Unable to create output directory: {0}."
|
||||||
|
})
|
||||||
|
final class Utilities {
|
||||||
|
|
||||||
|
private static final String OUTPUT_SUB_DIRECTORY = "BulkExtractor"; // NON-NLS
|
||||||
|
private static final String REPORT_NAME_BASE = "Bulk Extractor Scan"; // NON-NLS
|
||||||
|
private static final String BULK_EXTRACTOR_DIR = "bulk_extractor_1_5_3"; // NON-NLS
|
||||||
|
private static final String BULK_EXTRACTOR_VERSION = "1.5.3"; // NON-NLS
|
||||||
|
private static final String BULK_EXTRACTOR_32_BIT_DIR = "32-bit"; // NON-NLS
|
||||||
|
private static final String BULK_EXTRACTOR_64_BIT_DIR = "64-bit"; // NON-NLS
|
||||||
|
private static final String BULK_EXTRACTOR_WINDOWS_EXE = "bulk_extractor.exe"; // NON-NLS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ingest module name.
|
||||||
|
*
|
||||||
|
* @return A name string.
|
||||||
|
*/
|
||||||
|
static String getModuleName() {
|
||||||
|
return NbBundle.getMessage(BulkExtractorIngestModuleFactory.class, "Utilities.moduleName");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the version of the module
|
||||||
|
* @return Version string
|
||||||
|
*/
|
||||||
|
static String getVersion() {
|
||||||
|
return BULK_EXTRACTOR_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a report name based on the name of file presumed to be scanned by
|
||||||
|
* Bulk Extractor.
|
||||||
|
*
|
||||||
|
* @param scannedFileName The name of the file.
|
||||||
|
*
|
||||||
|
* @return The report name string.
|
||||||
|
*/
|
||||||
|
static String getReportName(String scannedFileName) {
|
||||||
|
return scannedFileName + " " + Utilities.REPORT_NAME_BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the output directory for this module for the current case and
|
||||||
|
* data source, if it does not already exist.
|
||||||
|
*
|
||||||
|
* @return The absolute path of the output directory.
|
||||||
|
*
|
||||||
|
* @throws org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException
|
||||||
|
*/
|
||||||
|
synchronized static Path createOutputDirectoryForDataSource(String subDirName) throws IngestModule.IngestModuleException {
|
||||||
|
Path path = Paths.get(Case.getCurrentCase().getModuleDirectory(), Utilities.OUTPUT_SUB_DIRECTORY, subDirName);
|
||||||
|
try {
|
||||||
|
Files.createDirectories(path);
|
||||||
|
} catch (FileAlreadyExistsException ex) {
|
||||||
|
// No worries.
|
||||||
|
} catch (IOException | SecurityException | UnsupportedOperationException ex) {
|
||||||
|
throw new IngestModule.IngestModuleException(Bundle.Utilities_cannotCreateOutputDir_message_with_param(path.toString()), ex);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a path for an output subdirectory to contain the results of
|
||||||
|
* scanning a file with Bulk Extractor.
|
||||||
|
*
|
||||||
|
* @param rootOutputDirPath The root output directory path
|
||||||
|
* @param objectId The object id of the file to be scanned.
|
||||||
|
*
|
||||||
|
* @return The path.
|
||||||
|
*/
|
||||||
|
static Path getOutputSubdirectoryPath(Path rootOutputDirPath, long objectId) {
|
||||||
|
StringBuilder nameBuilder = new StringBuilder(Long.toString(objectId));
|
||||||
|
nameBuilder.append("_"); // NON-NLS
|
||||||
|
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss-SSSS"); // NON-NLS
|
||||||
|
Date date = new Date();
|
||||||
|
nameBuilder.append(dateFormat.format(date));
|
||||||
|
return Paths.get(rootOutputDirPath.toAbsolutePath().toString(), nameBuilder.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locates the Bulk Extractor executable.
|
||||||
|
*
|
||||||
|
* @return The path of the executable.
|
||||||
|
*
|
||||||
|
* @throws org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException
|
||||||
|
*/
|
||||||
|
static Path locateBulkExtractorExecutable() throws IngestModule.IngestModuleException {
|
||||||
|
// Must be running under a Windows operating system.
|
||||||
|
if (!PlatformUtil.isWindowsOS()) {
|
||||||
|
throw new IngestModule.IngestModuleException(Bundle.Utilities_unsupportedOS_message());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the expected path to either the 32-bit or 64-bit version of the
|
||||||
|
// Bulk Extractor executable.
|
||||||
|
final File beRoot = InstalledFileLocator.getDefault().locate(Utilities.BULK_EXTRACTOR_DIR, Utilities.class.getPackage().getName(), false);
|
||||||
|
|
||||||
|
Path executablePath;
|
||||||
|
if (PlatformUtil.is64BitOS()) {
|
||||||
|
executablePath = Paths.get(
|
||||||
|
beRoot.getAbsolutePath(),
|
||||||
|
Utilities.BULK_EXTRACTOR_64_BIT_DIR,
|
||||||
|
Utilities.BULK_EXTRACTOR_WINDOWS_EXE);
|
||||||
|
} else {
|
||||||
|
executablePath = Paths.get(
|
||||||
|
beRoot.getAbsolutePath(),
|
||||||
|
Utilities.BULK_EXTRACTOR_32_BIT_DIR,
|
||||||
|
Utilities.BULK_EXTRACTOR_WINDOWS_EXE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the executable exists at the expected location and that it
|
||||||
|
// can be run.
|
||||||
|
File bulkExtractor = executablePath.toFile();
|
||||||
|
if (null == bulkExtractor || !bulkExtractor.exists()) {
|
||||||
|
throw new IngestModule.IngestModuleException(Bundle.Utilities_missingBulkExtractor_message());
|
||||||
|
}
|
||||||
|
if (!bulkExtractor.canExecute()) {
|
||||||
|
throw new IngestModule.IngestModuleException(Bundle.Utilities_cannotExecuteBulkExtractor_message());
|
||||||
|
}
|
||||||
|
|
||||||
|
return executablePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the Bulk Extractor executable.
|
||||||
|
*
|
||||||
|
* @param bulkExtractorPath The path to the Bulk Extractor executable.
|
||||||
|
* @param outputDirPath The path to the module output directory.
|
||||||
|
* @param inputFilePath The path to the input file.
|
||||||
|
* @param terminator
|
||||||
|
*
|
||||||
|
* @return The exit value of the subprocess used to run Bulk Extractor.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* @throws InterruptedException
|
||||||
|
*/
|
||||||
|
static int runBulkExtractor(Path bulkExtractorPath, Path outputDirPath, Path inputFilePath, ProcessTerminator terminator) throws SecurityException, IOException, InterruptedException {
|
||||||
|
List<String> commandLine = new ArrayList<>();
|
||||||
|
commandLine.add(bulkExtractorPath.toAbsolutePath().toString());
|
||||||
|
commandLine.add("-e");
|
||||||
|
commandLine.add("facebook");
|
||||||
|
commandLine.add("-o");
|
||||||
|
commandLine.add(outputDirPath.toAbsolutePath().toString());
|
||||||
|
commandLine.add(inputFilePath.toAbsolutePath().toString());
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
|
||||||
|
|
||||||
|
// redirect BE stdout and stderr to txt files
|
||||||
|
Path logFileName = Paths.get(outputDirPath.getParent().toString(), outputDirPath.getFileName().toString() + "_out.txt");
|
||||||
|
File logFile = new File(logFileName.toString());
|
||||||
|
Path errFileName = Paths.get(outputDirPath.getParent().toString(), outputDirPath.getFileName().toString() + "_err.txt");
|
||||||
|
File errFile = new File(errFileName.toString());
|
||||||
|
processBuilder.redirectError(ProcessBuilder.Redirect.appendTo(errFile));
|
||||||
|
processBuilder.redirectOutput(ProcessBuilder.Redirect.appendTo(logFile));
|
||||||
|
|
||||||
|
return ExecUtil.execute(processBuilder, terminator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether or not a directory is empty.
|
||||||
|
*
|
||||||
|
* @param directoryPath The path to the directory to inspect.
|
||||||
|
*
|
||||||
|
* @return True if the directory is empty, false otherwise.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
static boolean isDirectoryEmpty(final Path directoryPath) throws IllegalArgumentException, IOException {
|
||||||
|
if (!Files.isDirectory(directoryPath)) {
|
||||||
|
throw new IllegalArgumentException("The directoryPath argument must be a directory path"); // NON-NLS
|
||||||
|
}
|
||||||
|
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(directoryPath)) {
|
||||||
|
return !dirStream.iterator().hasNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user