mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-13 08:26:15 +00:00
Implemented and tested the XRY DSP
This commit is contained in:
parent
875b789abb
commit
aa88bc69b5
@ -0,0 +1,3 @@
|
|||||||
|
XRYDataSourceProcessorConfigPanel.fileBrowserButton.text=Browse
|
||||||
|
XRYDataSourceProcessorConfigPanel.filePathTextField.text=
|
||||||
|
XRYDataSourceProcessorConfigPanel.xrySelectFolderLabel.text=Select an XRY Folder
|
@ -0,0 +1,12 @@
|
|||||||
|
XRYDataSourceProcessor.dataSourceType=Import Tool Report
|
||||||
|
XRYDataSourceProcessor.fileAdded=Added %s to the case database
|
||||||
|
XRYDataSourceProcessor.ioError=I/O error occured trying to test the XRY report folder
|
||||||
|
XRYDataSourceProcessor.notReadable=Could not read from the selected folder
|
||||||
|
XRYDataSourceProcessor.notXRYFolder=Selected folder did not contain any XRY files
|
||||||
|
XRYDataSourceProcessor.preppingFiles=Preparing to add files to the case database
|
||||||
|
XRYDataSourceProcessor.processingFiles=Processing all XRY files...
|
||||||
|
XRYDataSourceProcessor.testingFolder=Testing input folder...
|
||||||
|
XRYDataSourceProcessor.unexpectedError=Internal error occurred while processing XRY report
|
||||||
|
XRYDataSourceProcessorConfigPanel.fileBrowserButton.text=Browse
|
||||||
|
XRYDataSourceProcessorConfigPanel.filePathTextField.text=
|
||||||
|
XRYDataSourceProcessorConfigPanel.xrySelectFolderLabel.text=Select an XRY Folder
|
@ -0,0 +1,242 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 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.datasourceprocessors.xry;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.SwingWorker;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
|
import org.openide.util.lookup.ServiceProviders;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.services.FileManager;
|
||||||
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||||
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.LocalFilesDataSource;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
import org.sleuthkit.datamodel.TskDataException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An XRY Report data source processor.
|
||||||
|
*/
|
||||||
|
@ServiceProviders(value = {
|
||||||
|
@ServiceProvider(service = DataSourceProcessor.class)}
|
||||||
|
)
|
||||||
|
public class XRYDataSourceProcessor implements DataSourceProcessor {
|
||||||
|
|
||||||
|
private final XRYDataSourceProcessorConfigPanel configPanel;
|
||||||
|
|
||||||
|
//Background processor to relieve the EDT from adding files to the case
|
||||||
|
//database and parsing the report files.
|
||||||
|
private XRYReportProcessorSwingWorker swingWorker;
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(XRYDataSourceProcessor.class.getName());
|
||||||
|
|
||||||
|
public XRYDataSourceProcessor() {
|
||||||
|
configPanel = XRYDataSourceProcessorConfigPanel.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"XRYDataSourceProcessor.dataSourceType=Import Tool Report"
|
||||||
|
})
|
||||||
|
public String getDataSourceType() {
|
||||||
|
return Bundle.XRYDataSourceProcessor_dataSourceType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JPanel getPanel() {
|
||||||
|
return configPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPanelValid() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes the XRY folder the examiner selected. The heavy lifting
|
||||||
|
* is handed off to a dedicated thread. This function will
|
||||||
|
* test the minimum requirements needed to successfully process the input.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"XRYDataSourceProcessor.testingFolder=Testing input folder...",
|
||||||
|
"XRYDataSourceProcessor.notReadable=Could not read from the selected folder",
|
||||||
|
"XRYDataSourceProcessor.notXRYFolder=Selected folder did not contain any XRY files",
|
||||||
|
"XRYDataSourceProcessor.ioError=I/O error occured trying to test the XRY report folder"
|
||||||
|
})
|
||||||
|
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
||||||
|
progressMonitor.setProgressText(Bundle.XRYDataSourceProcessor_testingFolder());
|
||||||
|
|
||||||
|
String selectedFilePath = configPanel.getSelectedFilePath();
|
||||||
|
File selectedFile = new File(selectedFilePath);
|
||||||
|
Path selectedPath = selectedFile.toPath();
|
||||||
|
|
||||||
|
//Test permissions
|
||||||
|
if (!Files.isReadable(selectedPath)) {
|
||||||
|
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS,
|
||||||
|
Lists.newArrayList(Bundle.XRYDataSourceProcessor_notReadable()),
|
||||||
|
Lists.newArrayList());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
//Validate the folder.
|
||||||
|
if (!XRYFolder.isXRYFolder(selectedPath)) {
|
||||||
|
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS,
|
||||||
|
Lists.newArrayList(Bundle.XRYDataSourceProcessor_notXRYFolder()),
|
||||||
|
Lists.newArrayList());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "[XRY DSP] I/O exception encountered trying to test the XRY folder.", ex);
|
||||||
|
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS,
|
||||||
|
Lists.newArrayList(Bundle.XRYDataSourceProcessor_ioError(), ex.toString()), Lists.newArrayList());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
XRYFolder xryFolder = new XRYFolder(selectedPath);
|
||||||
|
FileManager fileManager = Case.getCurrentCaseThrows()
|
||||||
|
.getServices().getFileManager();
|
||||||
|
|
||||||
|
//Move heavy lifting to a dedicated thread.
|
||||||
|
swingWorker = new XRYReportProcessorSwingWorker(xryFolder, progressMonitor,
|
||||||
|
callback, fileManager);
|
||||||
|
swingWorker.execute();
|
||||||
|
} catch (NoCurrentCaseException ex) {
|
||||||
|
logger.log(Level.WARNING, "[XRY DSP] No case is currently open.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
if (swingWorker != null) {
|
||||||
|
swingWorker.cancel(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
//Clear the current selected file path.
|
||||||
|
configPanel.clearSelectedFilePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Relieves the EDT from add images to the case database and processing the
|
||||||
|
* XRY report files.
|
||||||
|
*/
|
||||||
|
private class XRYReportProcessorSwingWorker extends SwingWorker<LocalFilesDataSource, Void> {
|
||||||
|
|
||||||
|
private final DataSourceProcessorProgressMonitor progressMonitor;
|
||||||
|
private final DataSourceProcessorCallback callback;
|
||||||
|
private final FileManager fileManager;
|
||||||
|
private final XRYFolder xryFolder;
|
||||||
|
|
||||||
|
public XRYReportProcessorSwingWorker(XRYFolder folder, DataSourceProcessorProgressMonitor progressMonitor,
|
||||||
|
DataSourceProcessorCallback callback, FileManager fileManager) {
|
||||||
|
this.xryFolder = folder;
|
||||||
|
this.progressMonitor = progressMonitor;
|
||||||
|
this.callback = callback;
|
||||||
|
this.fileManager = fileManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"XRYDataSourceProcessor.preppingFiles=Preparing to add files to the case database",
|
||||||
|
"XRYDataSourceProcessor.processingFiles=Processing all XRY files..."
|
||||||
|
})
|
||||||
|
protected LocalFilesDataSource doInBackground() throws TskCoreException,
|
||||||
|
TskDataException, IOException {
|
||||||
|
progressMonitor.setProgressText(Bundle.XRYDataSourceProcessor_preppingFiles());
|
||||||
|
|
||||||
|
List<Path> nonXRYFiles = xryFolder.getNonXRYFiles();
|
||||||
|
List<String> filePaths = nonXRYFiles.stream()
|
||||||
|
//Map paths to string representations.
|
||||||
|
.map(Path::toString)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
String uniqueUUID = UUID.randomUUID().toString();
|
||||||
|
LocalFilesDataSource dataSource = fileManager.addLocalFilesDataSource(
|
||||||
|
uniqueUUID,
|
||||||
|
"XRY Report", //Name
|
||||||
|
"", //Timezone
|
||||||
|
filePaths,
|
||||||
|
new ProgressMonitorAdapter(progressMonitor));
|
||||||
|
|
||||||
|
//Process the report files.
|
||||||
|
progressMonitor.setProgressText(Bundle.XRYDataSourceProcessor_processingFiles());
|
||||||
|
XRYReportProcessor.process(xryFolder, dataSource);
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"XRYDataSourceProcessor.unexpectedError=Internal error occurred while processing XRY report"
|
||||||
|
})
|
||||||
|
public void done() {
|
||||||
|
try {
|
||||||
|
LocalFilesDataSource newDataSource = get();
|
||||||
|
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS,
|
||||||
|
Lists.newArrayList(), Lists.newArrayList(newDataSource));
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
//DSP was cancelled. Not an error.
|
||||||
|
} catch (ExecutionException ex) {
|
||||||
|
logger.log(Level.SEVERE, "[XRY DSP] Unexpected internal error while processing XRY report.", ex);
|
||||||
|
callback.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS,
|
||||||
|
Lists.newArrayList(Bundle.XRYDataSourceProcessor_unexpectedError(),
|
||||||
|
ex.toString()), Lists.newArrayList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the DSP progress monitor compatible with the File Manager
|
||||||
|
* progress updater.
|
||||||
|
*/
|
||||||
|
private class ProgressMonitorAdapter implements FileManager.FileAddProgressUpdater {
|
||||||
|
|
||||||
|
private final DataSourceProcessorProgressMonitor progressMonitor;
|
||||||
|
|
||||||
|
ProgressMonitorAdapter(DataSourceProcessorProgressMonitor progressMonitor) {
|
||||||
|
this.progressMonitor = progressMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"XRYDataSourceProcessor.fileAdded=Added %s to the case database"
|
||||||
|
})
|
||||||
|
public void fileAdded(AbstractFile newFile) {
|
||||||
|
progressMonitor.setProgressText(String.format(Bundle.XRYDataSourceProcessor_fileAdded(), newFile.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" 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"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="xrySelectFolderLabel" pref="380" max="32767" attributes="0"/>
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Component id="filePathTextField" max="32767" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="fileBrowserButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace max="-2" 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="xrySelectFolderLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
|
<Component id="filePathTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="fileBrowserButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace pref="246" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JTextField" name="filePathTextField">
|
||||||
|
<Properties>
|
||||||
|
<Property name="editable" type="boolean" value="false"/>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/datasourceprocessors/xry/Bundle.properties" key="XRYDataSourceProcessorConfigPanel.filePathTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="fileBrowserButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/datasourceprocessors/xry/Bundle.properties" key="XRYDataSourceProcessorConfigPanel.fileBrowserButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="fileBrowserButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="xrySelectFolderLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/datasourceprocessors/xry/Bundle.properties" key="XRYDataSourceProcessorConfigPanel.xrySelectFolderLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 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.datasourceprocessors.xry;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import javax.swing.JFileChooser;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows an examiner to configure the XRY Data source processor.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
||||||
|
class XRYDataSourceProcessorConfigPanel extends JPanel {
|
||||||
|
|
||||||
|
private static final XRYDataSourceProcessorConfigPanel INSTANCE =
|
||||||
|
new XRYDataSourceProcessorConfigPanel();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new form XRYDataSourceConfigPanel.
|
||||||
|
* Prevent direct instantiation.
|
||||||
|
*/
|
||||||
|
private XRYDataSourceProcessorConfigPanel() {
|
||||||
|
initComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the singleton XRYDataSourceProcessorConfigPanel.
|
||||||
|
*/
|
||||||
|
static XRYDataSourceProcessorConfigPanel getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the selected file path.
|
||||||
|
*/
|
||||||
|
void clearSelectedFilePath() {
|
||||||
|
filePathTextField.setText(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the file path selected by the examiner.
|
||||||
|
*/
|
||||||
|
String getSelectedFilePath() {
|
||||||
|
return filePathTextField.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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() {
|
||||||
|
|
||||||
|
filePathTextField = new javax.swing.JTextField();
|
||||||
|
fileBrowserButton = new javax.swing.JButton();
|
||||||
|
xrySelectFolderLabel = new javax.swing.JLabel();
|
||||||
|
|
||||||
|
filePathTextField.setEditable(false);
|
||||||
|
filePathTextField.setText(org.openide.util.NbBundle.getMessage(XRYDataSourceProcessorConfigPanel.class, "XRYDataSourceProcessorConfigPanel.filePathTextField.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(fileBrowserButton, org.openide.util.NbBundle.getMessage(XRYDataSourceProcessorConfigPanel.class, "XRYDataSourceProcessorConfigPanel.fileBrowserButton.text")); // NOI18N
|
||||||
|
fileBrowserButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
fileBrowserButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(xrySelectFolderLabel, org.openide.util.NbBundle.getMessage(XRYDataSourceProcessorConfigPanel.class, "XRYDataSourceProcessorConfigPanel.xrySelectFolderLabel.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()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(xrySelectFolderLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(filePathTextField)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(fileBrowserButton)))
|
||||||
|
.addContainerGap())
|
||||||
|
);
|
||||||
|
layout.setVerticalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addComponent(xrySelectFolderLabel)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
.addComponent(filePathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addComponent(fileBrowserButton))
|
||||||
|
.addContainerGap(246, Short.MAX_VALUE))
|
||||||
|
);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens a JFileChooser instance so that the examiner can select a XRY
|
||||||
|
* report folder.
|
||||||
|
*/
|
||||||
|
private void fileBrowserButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileBrowserButtonActionPerformed
|
||||||
|
JFileChooser fileChooser = new JFileChooser();
|
||||||
|
fileChooser.setMultiSelectionEnabled(false);
|
||||||
|
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||||
|
int returnVal = fileChooser.showOpenDialog(this);
|
||||||
|
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||||
|
File selection = fileChooser.getSelectedFile();
|
||||||
|
filePathTextField.setText(selection.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}//GEN-LAST:event_fileBrowserButtonActionPerformed
|
||||||
|
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JButton fileBrowserButton;
|
||||||
|
private javax.swing.JTextField filePathTextField;
|
||||||
|
private javax.swing.JLabel xrySelectFolderLabel;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
}
|
@ -24,7 +24,9 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.LinkOption;
|
import java.nio.file.LinkOption;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,6 +38,62 @@ final class XRYFolder {
|
|||||||
//children of their parent folder.
|
//children of their parent folder.
|
||||||
private static final int XRY_FILES_DEPTH = 1;
|
private static final int XRY_FILES_DEPTH = 1;
|
||||||
|
|
||||||
|
//Raw path to the XRY folder.
|
||||||
|
private final Path xryFolder;
|
||||||
|
|
||||||
|
public XRYFolder(Path folder) {
|
||||||
|
xryFolder = folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds all paths in the XRY report folder which are not XRY files. Only
|
||||||
|
* the first directory level is searched. As a result, some paths may point
|
||||||
|
* to directories.
|
||||||
|
*
|
||||||
|
* @return A non-null collection of paths
|
||||||
|
* @throws IOException If an I/O error occurs.
|
||||||
|
*/
|
||||||
|
public List<Path> getNonXRYFiles() throws IOException {
|
||||||
|
try (Stream<Path> allFiles = Files.walk(xryFolder, XRY_FILES_DEPTH)) {
|
||||||
|
List<Path> otherFiles = new ArrayList<>();
|
||||||
|
Iterator<Path> allFilesIterator = allFiles.iterator();
|
||||||
|
while (allFilesIterator.hasNext()) {
|
||||||
|
Path currentPath = allFilesIterator.next();
|
||||||
|
if (!currentPath.equals(xryFolder)
|
||||||
|
&& !XRYFileReader.isXRYFile(currentPath)) {
|
||||||
|
otherFiles.add(currentPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return otherFiles;
|
||||||
|
} catch (UncheckedIOException ex) {
|
||||||
|
throw ex.getCause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates XRYFileReader instances for all XRY files found in the top level
|
||||||
|
* of the folder.
|
||||||
|
*
|
||||||
|
* @return A non-null collection of file readers.
|
||||||
|
* @throws IOException If an I/O error occurs.
|
||||||
|
*/
|
||||||
|
public List<XRYFileReader> getXRYFileReaders() throws IOException {
|
||||||
|
try (Stream<Path> allFiles = Files.walk(xryFolder, XRY_FILES_DEPTH)) {
|
||||||
|
List<XRYFileReader> fileReaders = new ArrayList<>();
|
||||||
|
|
||||||
|
Iterator<Path> allFilesIterator = allFiles.iterator();
|
||||||
|
while (allFilesIterator.hasNext()) {
|
||||||
|
Path currentFile = allFilesIterator.next();
|
||||||
|
if (XRYFileReader.isXRYFile(currentFile)) {
|
||||||
|
fileReaders.add(new XRYFileReader(currentFile));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fileReaders;
|
||||||
|
} catch (UncheckedIOException ex) {
|
||||||
|
throw ex.getCause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches for XRY files at the top level of a given folder. If at least
|
* Searches for XRY files at the top level of a given folder. If at least
|
||||||
* one file matches, the entire directory is assumed to be an XRY report.
|
* one file matches, the entire directory is assumed to be an XRY report.
|
||||||
@ -48,7 +106,7 @@ final class XRYFolder {
|
|||||||
* @return Indicates whether the Path is an XRY report.
|
* @return Indicates whether the Path is an XRY report.
|
||||||
*
|
*
|
||||||
* @throws IOException Error occurred during File I/O.
|
* @throws IOException Error occurred during File I/O.
|
||||||
* @throws SecurityException If the security manager denies access any of
|
* @throws SecurityException If the security manager denies access to any of
|
||||||
* the files.
|
* the files.
|
||||||
*/
|
*/
|
||||||
public static boolean isXRYFolder(Path folder) throws IOException {
|
public static boolean isXRYFolder(Path folder) throws IOException {
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 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.datasourceprocessors.xry;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes all XRY files in an XRY folder.
|
||||||
|
*/
|
||||||
|
class XRYReportProcessor {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(XRYReportProcessor.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes all XRY Files and creates artifacts on the given Content
|
||||||
|
* instance.
|
||||||
|
*
|
||||||
|
* @param folder XRY folder to process
|
||||||
|
* @param parent Content instance to hold newly created artifacts.
|
||||||
|
* @throws IOException If an I/O exception occurs.
|
||||||
|
* @throws TskCoreException If an error occurs adding artifacts.
|
||||||
|
*/
|
||||||
|
static void process(XRYFolder folder, Content parent) throws IOException, TskCoreException {
|
||||||
|
//Get all XRY file readers from this folder.
|
||||||
|
List<XRYFileReader> xryFileReaders = folder.getXRYFileReaders();
|
||||||
|
|
||||||
|
for (XRYFileReader xryFileReader : xryFileReaders) {
|
||||||
|
String reportType = xryFileReader.getReportType();
|
||||||
|
if (XRYFileParserFactory.supports(reportType)) {
|
||||||
|
XRYFileParser parser = XRYFileParserFactory.get(reportType);
|
||||||
|
parser.parse(xryFileReader, parent);
|
||||||
|
} else {
|
||||||
|
logger.log(Level.SEVERE, String.format("[XRY DSP] XRY File (in brackets) "
|
||||||
|
+ "[ %s ] was found, but no parser to support its report type exists. "
|
||||||
|
+ "Report type is (in brackets) [ %s ]", xryFileReader.getReportPath().toString(), reportType));
|
||||||
|
}
|
||||||
|
xryFileReader.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user