mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06: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.Path;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
@ -36,6 +38,62 @@ final class XRYFolder {
|
||||
//children of their parent folder.
|
||||
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
|
||||
* 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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
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