@@ -198,11 +198,11 @@
|
||||
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-filesearch-FileSearchAction.instance"/>
|
||||
<attr name="position" intvalue="200"/>
|
||||
</file>
|
||||
<file name="org-sleuthkit-autopsy-report-ReportAction.shadow">
|
||||
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-report-ReportAction.instance"/>
|
||||
<file name="org-sleuthkit-autopsy-report-ReportWizardAction.shadow">
|
||||
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-report-ReportWizardAction.instance"/>
|
||||
<attr name="position" intvalue="100"/>
|
||||
</file>
|
||||
<file name="org-sleuthkit-autopsy-report-ReportAction-separatorAfter.instance">
|
||||
<file name="org-sleuthkit-autopsy-report-ReportWizardAction-separatorAfter.instance">
|
||||
<attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
|
||||
<attr name="position" intvalue="101"/>
|
||||
</file>
|
||||
@@ -290,24 +290,19 @@
|
||||
<attr name="position" intvalue="50"/>
|
||||
</file>
|
||||
<file name="org-sleuthkit-autopsy-report-ReportHTML.instance">
|
||||
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.ReportModule"/>
|
||||
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.TableReportModule"/>
|
||||
<attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.report.ReportHTML.getDefault"/>
|
||||
<attr name="position" intvalue="900"/>
|
||||
</file>
|
||||
<file name="org-sleuthkit-autopsy-report-ReportXML.instance">
|
||||
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.ReportModule"/>
|
||||
<attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.report.ReportXML.getDefault"/>
|
||||
<file name="org-sleuthkit-autopsy-report-ReportExcel.instance">
|
||||
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.TableReportModule"/>
|
||||
<attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.report.ReportExcel.getDefault"/>
|
||||
<attr name="position" intvalue="901"/>
|
||||
</file>
|
||||
<file name="org-sleuthkit-autopsy-report-ReportXLS.instance">
|
||||
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.ReportModule"/>
|
||||
<attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.report.ReportXLS.getDefault"/>
|
||||
<attr name="position" intvalue="902"/>
|
||||
</file>
|
||||
<file name="org-sleuthkit-autopsy-report-ReportBodyFile.instance">
|
||||
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.ReportModule"/>
|
||||
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.GeneralReportModule"/>
|
||||
<attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.report.ReportBodyFile.getDefault"/>
|
||||
<attr name="position" intvalue="903"/>
|
||||
<attr name="position" intvalue="902"/>
|
||||
</file>
|
||||
<!--<folder name="JavaHelp">
|
||||
<file name="casemodule-helpset.xml" url="casemodule-helpset.xml">
|
||||
@@ -355,9 +350,9 @@
|
||||
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-menuactions-SpacerAction.instance"/>
|
||||
<attr name="position" intvalue="10000"/>
|
||||
</file>
|
||||
<file name="org-sleuthkit-autopsy-report-ReportAction.shadow">
|
||||
<attr name="displayName" bundlevalue="org.sleuthkit.autopsy.report.Bundle#Toolbars/Reports/org-sleuthkit-autopsy-report-ReportAction.shadow"/>
|
||||
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-report-ReportAction.instance"/>
|
||||
<file name="org-sleuthkit-autopsy-report-ReportWizardAction.shadow">
|
||||
<attr name="displayName" bundlevalue="org.sleuthkit.autopsy.report.Bundle#Toolbars/Reports/org-sleuthkit-autopsy-report-ReportWizardAction.shadow"/>
|
||||
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-report-ReportWizardAction.instance"/>
|
||||
<attr name="position" intvalue="102"/>
|
||||
</file>
|
||||
</folder>
|
||||
|
||||
@@ -18,16 +18,17 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
@@ -120,32 +121,35 @@ public class Tags {
|
||||
|
||||
/**
|
||||
* Get a list of all the tag names.
|
||||
* Uses a custom query for speed when dealing with thousands of Tags.
|
||||
* @return a list of all tag names.
|
||||
*/
|
||||
static String[] getTagNames() {
|
||||
Set<String> names = new HashSet<String>();
|
||||
//List<String> names = new ArrayList<String>();
|
||||
public static List<String> getTagNames() {
|
||||
Case currentCase = Case.getCurrentCase();
|
||||
SleuthkitCase skCase = currentCase.getSleuthkitCase();
|
||||
List<String> names = new ArrayList<String>();
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
Case currentCase = Case.getCurrentCase();
|
||||
SleuthkitCase skCase = currentCase.getSleuthkitCase();
|
||||
List<BlackboardArtifact> fileTags = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE);
|
||||
List<BlackboardArtifact> artifactTags = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT);
|
||||
fileTags.addAll(artifactTags);
|
||||
|
||||
for(BlackboardArtifact artifact : fileTags) {
|
||||
List<BlackboardAttribute> attributes = artifact.getAttributes();
|
||||
for(BlackboardAttribute att : attributes) {
|
||||
if(att.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID()) {
|
||||
names.add(att.getValueString());
|
||||
break;
|
||||
}
|
||||
rs = skCase.runQuery("SELECT value_text"
|
||||
+ " FROM blackboard_attributes"
|
||||
+ " WHERE attribute_type_id = " + ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID()
|
||||
+ " GROUP BY value_text"
|
||||
+ " ORDER BY value_text");
|
||||
while(rs.next()) {
|
||||
names.add(rs.getString("value_text"));
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to query the blackboard for tag names.");
|
||||
} finally {
|
||||
if (rs != null) {
|
||||
try {
|
||||
skCase.closeRunQuery(rs);
|
||||
} catch (SQLException ex) {
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to get list of artifacts from the case.");
|
||||
}
|
||||
|
||||
return names.toArray(new String[0]);
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,7 +157,7 @@ public class Tags {
|
||||
* @param name of the requested tags
|
||||
* @return a list of all tag artifacts with the given name
|
||||
*/
|
||||
static List<BlackboardArtifact> getTagsByName(String name) {
|
||||
public static List<BlackboardArtifact> getTagsByName(String name) {
|
||||
try {
|
||||
Case currentCase = Case.getCurrentCase();
|
||||
SleuthkitCase skCase = currentCase.getSleuthkitCase();
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
</SyntheticProperties>
|
||||
<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" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="artifactScrollPane" max="32767" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="deselectAllButton" max="32767" attributes="0"/>
|
||||
<Component id="selectAllButton" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="titleLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="221" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="okButton" 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="titleLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="artifactScrollPane" pref="224" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="selectAllButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="deselectAllButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="11" max="-2" attributes="0"/>
|
||||
<Component id="okButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="artifactScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JList" name="artifactList">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
<Property name="selectionMode" type="int" value="0"/>
|
||||
<Property name="layoutOrientation" type="int" value="2"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="okButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ArtifactSelectionDialog.okButton.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="okButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="titleLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ArtifactSelectionDialog.titleLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="selectAllButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ArtifactSelectionDialog.selectAllButton.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="selectAllButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="deselectAllButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ArtifactSelectionDialog.deselectAllButton.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="deselectAllButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 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.report;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import javax.swing.ListModel;
|
||||
import javax.swing.event.ListDataListener;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||
|
||||
public class ArtifactSelectionDialog extends javax.swing.JDialog {
|
||||
private static final Logger logger = Logger.getLogger(ArtifactSelectionDialog.class.getName());
|
||||
private static ArtifactSelectionDialog instance;
|
||||
private ArtifactModel model;
|
||||
private ArtifactRenderer renderer;
|
||||
|
||||
private Map<BlackboardArtifact.ARTIFACT_TYPE, Boolean> artifactStates;
|
||||
private List<BlackboardArtifact.ARTIFACT_TYPE> artifacts;
|
||||
|
||||
/**
|
||||
* Creates new form ArtifactSelectionDialog
|
||||
*/
|
||||
public ArtifactSelectionDialog(java.awt.Frame parent, boolean modal) {
|
||||
super(parent, modal);
|
||||
initComponents();
|
||||
populateList();
|
||||
customInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the list of artifacts with all important artifacts.
|
||||
*/
|
||||
private void populateList() {
|
||||
artifacts = getImportantArtifactTypes();
|
||||
artifactStates = new EnumMap<BlackboardArtifact.ARTIFACT_TYPE, Boolean>(BlackboardArtifact.ARTIFACT_TYPE.class);
|
||||
for (BlackboardArtifact.ARTIFACT_TYPE type : artifacts) {
|
||||
artifactStates.put(type, Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
private void customInit() {
|
||||
model = new ArtifactModel();
|
||||
renderer = new ArtifactRenderer();
|
||||
artifactList.setModel(model);
|
||||
artifactList.setCellRenderer(renderer);
|
||||
artifactList.setVisibleRowCount(-1);
|
||||
|
||||
artifactList.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent evt) {
|
||||
JList list = (JList) evt.getSource();
|
||||
int index = list.locationToIndex(evt.getPoint());
|
||||
BlackboardArtifact.ARTIFACT_TYPE type = (BlackboardArtifact.ARTIFACT_TYPE) model.getElementAt(index);
|
||||
artifactStates.put(type, !artifactStates.get(type));
|
||||
list.repaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of the artifact types we want to report on.
|
||||
*/
|
||||
static List<ARTIFACT_TYPE> getImportantArtifactTypes() {
|
||||
List<ARTIFACT_TYPE> types = new ArrayList<ARTIFACT_TYPE>();
|
||||
types.add(ARTIFACT_TYPE.TSK_WEB_BOOKMARK);
|
||||
types.add(ARTIFACT_TYPE.TSK_WEB_COOKIE);
|
||||
types.add(ARTIFACT_TYPE.TSK_WEB_HISTORY);
|
||||
types.add(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD);
|
||||
types.add(ARTIFACT_TYPE.TSK_RECENT_OBJECT);
|
||||
types.add(ARTIFACT_TYPE.TSK_INSTALLED_PROG);
|
||||
types.add(ARTIFACT_TYPE.TSK_KEYWORD_HIT);
|
||||
types.add(ARTIFACT_TYPE.TSK_HASHSET_HIT);
|
||||
types.add(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED);
|
||||
types.add(ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY);
|
||||
types.add(ARTIFACT_TYPE.TSK_METADATA_EXIF);
|
||||
types.add(ARTIFACT_TYPE.TSK_TAG_FILE);
|
||||
types.add(ARTIFACT_TYPE.TSK_TAG_ARTIFACT);
|
||||
return types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display this dialog, and return the selected artifacts.
|
||||
*/
|
||||
Map<BlackboardArtifact.ARTIFACT_TYPE, Boolean> display() {
|
||||
this.setTitle("Advanced Artifact Selection");
|
||||
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
// set the popUp window / JFrame
|
||||
int w = this.getSize().width;
|
||||
int h = this.getSize().height;
|
||||
|
||||
// set the location of the popUp Window on the center of the screen
|
||||
setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
|
||||
|
||||
this.setVisible(true);
|
||||
return artifactStates;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
artifactScrollPane = new javax.swing.JScrollPane();
|
||||
artifactList = new javax.swing.JList();
|
||||
okButton = new javax.swing.JButton();
|
||||
titleLabel = new javax.swing.JLabel();
|
||||
selectAllButton = new javax.swing.JButton();
|
||||
deselectAllButton = new javax.swing.JButton();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
|
||||
artifactList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
artifactList.setLayoutOrientation(javax.swing.JList.HORIZONTAL_WRAP);
|
||||
artifactScrollPane.setViewportView(artifactList);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(ArtifactSelectionDialog.class, "ArtifactSelectionDialog.okButton.text")); // NOI18N
|
||||
okButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
okButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(titleLabel, org.openide.util.NbBundle.getMessage(ArtifactSelectionDialog.class, "ArtifactSelectionDialog.titleLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(selectAllButton, org.openide.util.NbBundle.getMessage(ArtifactSelectionDialog.class, "ArtifactSelectionDialog.selectAllButton.text")); // NOI18N
|
||||
selectAllButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
selectAllButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(deselectAllButton, org.openide.util.NbBundle.getMessage(ArtifactSelectionDialog.class, "ArtifactSelectionDialog.deselectAllButton.text")); // NOI18N
|
||||
deselectAllButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
deselectAllButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(artifactScrollPane)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(deselectAllButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(selectAllButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(titleLabel)
|
||||
.addGap(0, 221, Short.MAX_VALUE))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(okButton)))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(titleLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(artifactScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 224, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(selectAllButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(deselectAllButton)
|
||||
.addGap(0, 0, Short.MAX_VALUE)))
|
||||
.addGap(11, 11, 11)
|
||||
.addComponent(okButton)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
|
||||
dispose();
|
||||
}//GEN-LAST:event_okButtonActionPerformed
|
||||
|
||||
private void selectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectAllButtonActionPerformed
|
||||
for (ARTIFACT_TYPE type : artifacts) {
|
||||
artifactStates.put(type, Boolean.TRUE);
|
||||
}
|
||||
artifactList.repaint();
|
||||
}//GEN-LAST:event_selectAllButtonActionPerformed
|
||||
|
||||
private void deselectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deselectAllButtonActionPerformed
|
||||
for (ARTIFACT_TYPE type : artifacts) {
|
||||
artifactStates.put(type, Boolean.FALSE);
|
||||
}
|
||||
artifactList.repaint();
|
||||
}//GEN-LAST:event_deselectAllButtonActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JList artifactList;
|
||||
private javax.swing.JScrollPane artifactScrollPane;
|
||||
private javax.swing.JButton deselectAllButton;
|
||||
private javax.swing.JButton okButton;
|
||||
private javax.swing.JButton selectAllButton;
|
||||
private javax.swing.JLabel titleLabel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
private class ArtifactModel implements ListModel {
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return artifacts.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElementAt(int index) {
|
||||
return artifacts.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListDataListener(ListDataListener l) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListDataListener(ListDataListener l) {
|
||||
}
|
||||
}
|
||||
|
||||
private class ArtifactRenderer extends JCheckBox implements ListCellRenderer {
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
if (value != null) {
|
||||
BlackboardArtifact.ARTIFACT_TYPE type = (BlackboardArtifact.ARTIFACT_TYPE) value;
|
||||
setEnabled(list.isEnabled());
|
||||
setSelected(artifactStates.get(type));
|
||||
setFont(list.getFont());
|
||||
setBackground(list.getBackground());
|
||||
setForeground(list.getForeground());
|
||||
setText(type.getDisplayName());
|
||||
return this;
|
||||
}
|
||||
return new JLabel();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 Basis Technology Corp.
|
||||
*
|
||||
* Copyright 2012 42six Solutions.
|
||||
* Contact: aebadirad <at> 42six <dot> com
|
||||
* Project Contact/Architect: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.report;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class BrowserControl{
|
||||
/**
|
||||
* Method to Open the Browser with Given URL
|
||||
* @param url
|
||||
*/
|
||||
public static void openUrl(String url){
|
||||
String os = System.getProperty("os.name");
|
||||
Runtime runtime=Runtime.getRuntime();
|
||||
try{
|
||||
// Block for Windows Platform
|
||||
if (os.startsWith("Windows")){
|
||||
String cmd = "rundll32 url.dll,FileProtocolHandler "+ url;
|
||||
Process p = runtime.exec(cmd);
|
||||
}
|
||||
//Block for Mac OS
|
||||
else if(os.startsWith("Mac OS")){
|
||||
Class fileMgr = Class.forName("com.apple.eio.FileManager");
|
||||
Method openURL = fileMgr.getDeclaredMethod("openURL", new Class[] {String.class});
|
||||
openURL.invoke(null, new Object[] {url});
|
||||
}
|
||||
//Block for UNIX Platform
|
||||
else {
|
||||
String[] browsers = {"firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape" };
|
||||
String browser = null;
|
||||
for (int count = 0; count < browsers.length && browser == null; count++)
|
||||
if (runtime.exec(new String[] {"which", browsers[count]}).waitFor() == 0)
|
||||
browser = browsers[count];
|
||||
if (browser == null)
|
||||
throw new Exception("Could not find web browser");
|
||||
else
|
||||
runtime.exec(new String[] {browser, url});
|
||||
}
|
||||
}catch(Exception x){
|
||||
System.err.println("Exception occurd while invoking Browser!");
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,32 @@
|
||||
OpenIDE-Module-Name=Report
|
||||
Toolbars/Reports/org-sleuthkit-autopsy-report-ReportAction.shadow=Reports
|
||||
ReportFilter.progBar.string=
|
||||
ReportFilter.cancelButton.actionCommand=
|
||||
ReportFilter.cancelButton.text=Cancel
|
||||
ReportFilter.jButton1.text=Generate Report
|
||||
ReportFilter.jButton2.label=
|
||||
ReportFilter.jButton2.actionCommand=
|
||||
ReportFilter.jButton2.text=
|
||||
ReportPanel.saveReport.actionCommand=
|
||||
ReportPanel.saveReport.text=Export Report...
|
||||
ReportPanel.jButton1.text=Close
|
||||
ReportFilter.updateLabel.toolTipText=
|
||||
ReportFilter.updateLabel.text=
|
||||
ReportPanel.statusLabel.text=Status Label
|
||||
ReportPanel.exportButton.text=Save As...
|
||||
ReportPanel.closeButton.text_1=Close
|
||||
ReportPanel.reportScrollPane.border.title=Report Summary
|
||||
ReportPanel.LABEL_LOC.text=Location
|
||||
ReportPanel.ButtonOpenFolder.text_1=Open Folder
|
||||
GenerateReportPanel.selectAllLabel.text=Select All
|
||||
GenerateReportPanel.deselectAllLabel.text=Deselect All
|
||||
GenerateReportPanel.generateReportButton.text=Generate Report
|
||||
GenerateReportPanel.advancedButton.text=Advanced
|
||||
GenerateReportPanel.reportModulesLabel.text=Report Modules:
|
||||
GenerateReportPanel.dataLabel.text=Select which data to report on:
|
||||
GenerateReportPanel.artifactsRadioButton.text=All Artifacts
|
||||
GenerateReportPanel.tagsRadioButton.text=User Tags
|
||||
ArtifactSelectionDialog.titleLabel.text=Select which artifacts you would like to report on:
|
||||
ArtifactSelectionDialog.okButton.text=OK
|
||||
ReportVisualPanel1.reportModulesLabel.text=Report Modules:
|
||||
DefaultReportConfigurationPanel.infoLabel.text=This report will be configured on the next screen.
|
||||
ReportVisualPanel2.dataLabel.text=Select which data to report on:
|
||||
ReportVisualPanel2.deselectAllButton.text=Deselect All
|
||||
ReportVisualPanel2.selectAllButton.text=Select All
|
||||
ReportVisualPanel2.advancedButton.text=Advanced
|
||||
ArtifactSelectionDialog.deselectAllButton.text=Deselect All
|
||||
ArtifactSelectionDialog.selectAllButton.text=Select All
|
||||
=Browse...
|
||||
ReportGenerationPanel.closeButton.text=Close
|
||||
ReportGenerationPanel.cancelAllButton.text=Cancel All
|
||||
ReportProgressPanel.reportLabel.text=reportLabel
|
||||
ReportProgressPanel.pathLabel.text=pathLabel
|
||||
ReportProgressPanel.separationLabel.text=-
|
||||
ReportProgressPanel.cancelButton.toolTipText=Queuing
|
||||
ReportProgressPanel.cancelButton.text=
|
||||
ReportProgressPanel.processingLabel.text=processingLabel
|
||||
ReportGenerationPanel.titleLabel.text=Report Generation Progress
|
||||
ReportVisualPanel2.taggedResultsRadioButton.text=Tagged Results
|
||||
ReportVisualPanel2.allResultsRadioButton.text=All Results
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.8" 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="infoLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace 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="infoLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="infoLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Tahoma" size="11" style="2"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="DefaultReportConfigurationPanel.infoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 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.report;
|
||||
|
||||
/**
|
||||
* The panel shown for all TableReportModules when configuring report modules.
|
||||
*/
|
||||
public class DefaultReportConfigurationPanel extends javax.swing.JPanel {
|
||||
|
||||
/**
|
||||
* Creates new form DefaultReportConfigurationPanel
|
||||
*/
|
||||
public DefaultReportConfigurationPanel() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
infoLabel = new javax.swing.JLabel();
|
||||
|
||||
infoLabel.setFont(new java.awt.Font("Tahoma", 2, 11)); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(infoLabel, org.openide.util.NbBundle.getMessage(DefaultReportConfigurationPanel.class, "DefaultReportConfigurationPanel.infoLabel.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(infoLabel)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(infoLabel)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JLabel infoLabel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 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.report;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
public interface GeneralReportModule extends ReportModule {
|
||||
|
||||
/**
|
||||
* Generate the report and update the report's ProgressPanel, then save the report
|
||||
* to the reportPath.
|
||||
*
|
||||
* @param reportPath path to save the report
|
||||
* @param progressPanel panel to update the report's progress
|
||||
*/
|
||||
public void generateReport(String reportPath, ReportProgressPanel progressPanel);
|
||||
|
||||
/**
|
||||
* Returns the configuration panel for the report, which is displayed in
|
||||
* the report configuration step of the report wizard.
|
||||
*
|
||||
* @return the report's configuration panel
|
||||
*/
|
||||
public JPanel getConfigurationPanel();
|
||||
|
||||
}
|
||||
@@ -1,305 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 Basis Technology Corp.
|
||||
*
|
||||
* Copyright 2012 42six Solutions.
|
||||
* Contact: aebadirad <at> 42six <dot> com
|
||||
* Project Contact/Architect: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.report;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import java.sql.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
public class Report {
|
||||
private static final Logger logger = Logger.getLogger(Report.class.getName());
|
||||
|
||||
private void Report() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the keywords related artifact/attributes and groups them
|
||||
* based on keyword
|
||||
*
|
||||
* @return boolean true if it completes successfully
|
||||
*
|
||||
*/
|
||||
public boolean getGroupedKeywordHit(Writer out) {
|
||||
HashMap<BlackboardArtifact, ArrayList<BlackboardAttribute>> reportMap = new HashMap<BlackboardArtifact, ArrayList<BlackboardAttribute>>();
|
||||
Case currentCase = Case.getCurrentCase(); // get the most updated case
|
||||
SleuthkitCase tempDb = currentCase.getSleuthkitCase();
|
||||
boolean success = true;
|
||||
try {
|
||||
tempDb.copyCaseDB(currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
|
||||
SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_keyword;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_preview;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_exp;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_list;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_name;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report;");
|
||||
String temp1 = "CREATE TABLE report_keyword AS SELECT value_text as keyword, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID() + ";";
|
||||
String temp2 = "CREATE TABLE report_preview AS SELECT value_text as preview, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID() + ";";
|
||||
String temp3 = "CREATE TABLE report_exp AS SELECT value_text as exp, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID() + ";";
|
||||
String temp4 = "CREATE TABLE report_list AS SELECT value_text as list, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + ";";
|
||||
String temp5 = "CREATE TABLE report_name AS SELECT name, report_keyword.artifact_id, tsk_files.obj_id as obj_id from tsk_files, blackboard_artifacts, report_keyword WHERE blackboard_artifacts.artifact_id = report_keyword.artifact_id AND blackboard_artifacts.obj_id = tsk_files.obj_id;";
|
||||
String temp6 = "CREATE TABLE report AS SELECT keyword, preview, exp, list, name, obj_id from report_keyword "
|
||||
+ "LEFT JOIN report_preview ON report_keyword.artifact_id=report_preview.artifact_id "
|
||||
+ "LEFT JOIN report_exp ON report_keyword.artifact_id=report_exp.artifact_id "
|
||||
+ "LEFT JOIN report_list ON report_keyword.artifact_id=report_list.artifact_id "
|
||||
+ "LEFT JOIN report_name ON report_keyword.artifact_id=report_name.artifact_id;";
|
||||
tempdbconnect.executeStmt(temp1);
|
||||
tempdbconnect.executeStmt(temp2);
|
||||
tempdbconnect.executeStmt(temp3);
|
||||
tempdbconnect.executeStmt(temp4);
|
||||
tempdbconnect.executeStmt(temp5);
|
||||
tempdbconnect.executeStmt(temp6);
|
||||
ResultSet uniqueresults = tempdbconnect.executeQry("SELECT keyword, exp, preview, list, name, obj_id FROM report ORDER BY keyword ASC");
|
||||
String keyword = "";
|
||||
while (uniqueresults.next()) {
|
||||
if (ReportFilter.cancel == true) { break; }
|
||||
Long objId = uniqueresults.getLong("obj_id");
|
||||
AbstractFile file = null;
|
||||
try {
|
||||
file = tempDb.getAbstractFileById(objId);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Could not get AbstractFile from TSK ", ex);
|
||||
}
|
||||
StringBuilder table = new StringBuilder();
|
||||
if (uniqueresults.getString("keyword") == null ? keyword == null : uniqueresults.getString("keyword").equals(keyword)) {
|
||||
} else {
|
||||
table.append("</tbody></table><br /><br />\n");
|
||||
keyword = uniqueresults.getString("keyword");
|
||||
table.append("<strong>").append(keyword).append("</strong>\n");
|
||||
table.append("<table><thead><tr><th>").append("File Name").append("</th><th>Preview</th><th>Keyword List</th><th>Path</th></tr><tbody>\n");
|
||||
}
|
||||
table.append("<tr><td>").append(uniqueresults.getString("name")).append("</td>\n");
|
||||
String previewreplace = StringEscapeUtils.escapeHtml(uniqueresults.getString("preview"));
|
||||
table.append("<td>").append(previewreplace.replaceAll("<!", "")).append("</td>").append("<td>").append(uniqueresults.getString("list")).append("<br />(").append(uniqueresults.getString("exp") == null ? keyword : uniqueresults.getString("exp")).append(")").append("</td>").append("<td>").append(file != null ? file.getUniquePath() : "").append("</td>").append("</tr>\n");
|
||||
out.write(table.toString());
|
||||
}
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_keyword;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_preview;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_exp;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_name;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_list;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report;");
|
||||
tempdbconnect.closeConnection();
|
||||
|
||||
File f1 = new File(currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
|
||||
f1.delete();
|
||||
out.write("</tbody></table><br /><br />");
|
||||
} catch (IOException ex) {
|
||||
success = false;
|
||||
logger.log(Level.SEVERE, "Unable to write to keyword.html file.", ex);
|
||||
} catch (SQLException ex) {
|
||||
success = false;
|
||||
logger.log(Level.SEVERE, "Unable to query databased for keyword hits.", ex);
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, "Failed to connect to database: {0}", ex);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the hash lookups related artifact/attributes and groups them
|
||||
* based on hashset name
|
||||
*
|
||||
* @return String table is a string of an html table
|
||||
*
|
||||
*/
|
||||
public String getGroupedHashsetHit() {
|
||||
StringBuilder table = new StringBuilder();
|
||||
HashMap<BlackboardArtifact, ArrayList<BlackboardAttribute>> reportMap = new HashMap<BlackboardArtifact, ArrayList<BlackboardAttribute>>();
|
||||
Case currentCase = Case.getCurrentCase(); // get the most updated case
|
||||
SleuthkitCase tempDb = currentCase.getSleuthkitCase();
|
||||
try {
|
||||
tempDb.copyCaseDB(currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
|
||||
SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_hashset;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_hashname;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_hash;");
|
||||
String temp1 = "CREATE TABLE report_hashset AS SELECT value_text as hashset,blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = '" + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + "';";
|
||||
String temp5 = "CREATE TABLE report_hashname AS SELECT name, size, report_hashset.artifact_id from tsk_files,blackboard_artifacts, report_hashset WHERE blackboard_artifacts.artifact_id = report_hashset.artifact_id AND blackboard_artifacts.obj_id = tsk_files.obj_id and blackboard_artifacts.artifact_type_id='" + BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() + "';";
|
||||
String temp6 = "CREATE TABLE report_hash AS SELECT hashset,size,name from report_hashset INNER JOIN report_hashname ON report_hashset.artifact_id=report_hashname.artifact_id;";
|
||||
tempdbconnect.executeStmt(temp1);
|
||||
tempdbconnect.executeStmt(temp5);
|
||||
tempdbconnect.executeStmt(temp6);
|
||||
ResultSet uniqueresults = tempdbconnect.executeQry("SELECT name, size, hashset FROM report_hash ORDER BY hashset ASC");
|
||||
String keyword = "";
|
||||
while (uniqueresults.next()) {
|
||||
if (uniqueresults.getString("hashset") == null ? keyword == null : uniqueresults.getString("hashset").equals(keyword)) {
|
||||
} else {
|
||||
table.append("</tbody></table><br /><br />");
|
||||
keyword = uniqueresults.getString("hashset");
|
||||
table.append("<strong>").append(keyword).append("</strong>");
|
||||
table.append("<table><thead><tr><th>").append("File Name").append("</th><th>Size</th></tr><tbody>");
|
||||
}
|
||||
table.append("<tr><td>").append(uniqueresults.getString("name")).append("</td>");
|
||||
table.append("<td>").append(uniqueresults.getString("size")).append("</td>").append("</tr>");
|
||||
|
||||
}
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_hashset;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_hashname;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_hash;");
|
||||
tempdbconnect.closeConnection();
|
||||
|
||||
File f1 = new File(currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
|
||||
table.append("</tbody></table><br /><br />");
|
||||
} catch (SQLException sqle) {
|
||||
logger.log(Level.SEVERE, "Error ocurred while connecting to database", sqle);
|
||||
} catch(IOException ioe){
|
||||
logger.log(Level.SEVERE, "Error ocurred while writing temporary database", ioe);
|
||||
}catch(Exception e){
|
||||
logger.log(Level.SEVERE, "Unknown exception occurred", e);
|
||||
}
|
||||
|
||||
return table.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the hash lookups related artifact/attributes and groups them
|
||||
* based on hashset name
|
||||
*
|
||||
* @return String table is a string of an html table
|
||||
*
|
||||
*/
|
||||
public String getGroupedEmailHit() {
|
||||
StringBuilder table = new StringBuilder();
|
||||
HashMap<BlackboardArtifact, ArrayList<BlackboardAttribute>> reportMap = new HashMap<BlackboardArtifact, ArrayList<BlackboardAttribute>>();
|
||||
Case currentCase = Case.getCurrentCase(); // get the most updated case
|
||||
SleuthkitCase tempDb = currentCase.getSleuthkitCase();
|
||||
try {
|
||||
tempDb.copyCaseDB(currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
|
||||
SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_path;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_from;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_bcc;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_subject;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_to;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_content;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_cc;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_name;");
|
||||
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report;");
|
||||
String temp1 = "CREATE TABLE report_path AS SELECT value_text as path,blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID() + ";";
|
||||
String temp0 = "CREATE TABLE report_date AS SELECT value_int64 as date, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD.getTypeID() + ";";
|
||||
|
||||
String temp2 = "CREATE TABLE report_to AS SELECT value_text as receiver, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO.getTypeID() + ";";
|
||||
String temp3 = "CREATE TABLE report_content AS SELECT value_text as content, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN.getTypeID() + ";";
|
||||
String temp4 = "CREATE TABLE report_cc AS SELECT value_text as cc, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC.getTypeID() + ";";
|
||||
String temp7 = "CREATE TABLE report_bcc AS SELECT value_text as bcc, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_BCC.getTypeID() + ";";
|
||||
String temp8 = "CREATE TABLE report_author AS SELECT value_text as author, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM.getTypeID() + ";";
|
||||
String temp6 = "CREATE TABLE report_subject AS SELECT value_text as subject, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT.getTypeID() + ";";
|
||||
String temp5 = "CREATE TABLE report_name AS SELECT name, report_path.artifact_id from tsk_files,blackboard_artifacts, report_path WHERE blackboard_artifacts.artifact_id = report_path.artifact_id AND blackboard_artifacts.obj_id = tsk_files.obj_id;";
|
||||
String temp9 = "CREATE TABLE report AS SELECT path,receiver,content,cc,bcc,subject,name,author,date from report_path INNER JOIN report_to ON report_path.artifact_id=report_to.artifact_id INNER JOIN report_content ON report_to.artifact_id=report_content.artifact_id INNER JOIN report_cc ON report_content.artifact_id=report_cc.artifact_id INNER JOIN report_name ON report_cc.artifact_id=report_name.artifact_id INNER JOIN report_bcc ON report_name.artifact_id=report_bcc.artifact_id INNER JOIN report_subject ON report_bcc.artifact_id=report_subject.artifact_id INNER JOIN report_author ON report_subject.artifact_id=report_author.artifact_id INNER JOIN report_date ON report_author.artifact_id=report_date.artifact_id";
|
||||
tempdbconnect.executeStmt(temp1);
|
||||
tempdbconnect.executeStmt(temp0);
|
||||
tempdbconnect.executeStmt(temp2);
|
||||
tempdbconnect.executeStmt(temp3);
|
||||
tempdbconnect.executeStmt(temp4);
|
||||
tempdbconnect.executeStmt(temp5);
|
||||
tempdbconnect.executeStmt(temp6);
|
||||
tempdbconnect.executeStmt(temp7);
|
||||
tempdbconnect.executeStmt(temp8);
|
||||
tempdbconnect.executeStmt(temp9);
|
||||
ResultSet uniqueresults = tempdbconnect.executeQry("SELECT path,receiver,content,cc,bcc,subject,name,author,date FROM report ORDER BY path ASC");
|
||||
String keyword = "";
|
||||
while (uniqueresults.next()) {
|
||||
if (uniqueresults.getString("path") == null ? keyword == null : uniqueresults.getString("path").equals(keyword)) {
|
||||
} else {
|
||||
table.append("</tbody></table><br /><br />");
|
||||
keyword = uniqueresults.getString("path");
|
||||
table.append("<strong>").append(keyword).append("</strong>");
|
||||
table.append("<table><thead><tr><th>").append("Folder").append("</th><th>From</th><th>To</th><th>Subject</th><th>Date/Time</th><th>Content</th><th>CC</th><th>BCC</th><th>Path</th></tr><tbody>");
|
||||
}
|
||||
table.append("<tr><td>").append(uniqueresults.getString("name")).append("</td>");
|
||||
table.append("<td>").append(uniqueresults.getString("receiver")).append("</td>").append("<td>").append(uniqueresults.getString("author")).append("</td><td>").append(uniqueresults.getString("subject")).append("</td>");
|
||||
SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
||||
String value = sdf.format(new java.util.Date(uniqueresults.getLong("date") * 1000));
|
||||
table.append("<td>").append(value).append("</td>");
|
||||
table.append("<td>").append(uniqueresults.getString("content")).append("</td>");
|
||||
table.append("<td>").append(uniqueresults.getString("cc")).append("</td>");
|
||||
table.append("<td>").append(uniqueresults.getString("bcc")).append("</td>");
|
||||
table.append("<td>").append(uniqueresults.getString("path")).append("</td>");
|
||||
table.append("</tr>");
|
||||
}
|
||||
tempdbconnect.closeConnection();
|
||||
|
||||
File f1 = new File(currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
|
||||
boolean success = f1.delete();
|
||||
table.append("</tbody></table><br /><br />");
|
||||
|
||||
} catch (SQLException sqle) {
|
||||
logger.log(Level.SEVERE, "Error ocurred while connecting to database", sqle);
|
||||
} catch(IOException ioe){
|
||||
logger.log(Level.SEVERE, "Error ocurred while writing temporary database", ioe);
|
||||
}catch(Exception e){
|
||||
logger.log(Level.SEVERE, "Unknown exception occurred", e);
|
||||
}
|
||||
|
||||
return table.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashmap of associated blackboard artifacts/attributes that were
|
||||
* requested by the config param
|
||||
*
|
||||
* @param config is a ReportConfiguration object that has all the types of
|
||||
* artifacts desired from the blackboard
|
||||
* @return reportMap a hashmap of all the artifacts for artifact types were
|
||||
* input
|
||||
*/
|
||||
public HashMap<BlackboardArtifact, List<BlackboardAttribute>> getAllTypes(ReportConfiguration config) {
|
||||
HashMap<BlackboardArtifact, List<BlackboardAttribute>> reportMap = new HashMap<BlackboardArtifact, List<BlackboardAttribute>>();
|
||||
Case currentCase = Case.getCurrentCase(); // get the most updated case
|
||||
SleuthkitCase tempDb = currentCase.getSleuthkitCase();
|
||||
try {
|
||||
for (Map.Entry<BlackboardArtifact.ARTIFACT_TYPE, Boolean> entry : config.config.entrySet()) {
|
||||
if (entry.getValue()) {
|
||||
List<BlackboardArtifact> bbart = tempDb.getBlackboardArtifacts(entry.getKey());
|
||||
for (BlackboardArtifact artifact : bbart) {
|
||||
List<BlackboardAttribute> attributes = artifact.getAttributes();
|
||||
reportMap.put(artifact, attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException tce) {
|
||||
logger.log(Level.SEVERE, "Error ocurred while connecting to database", tce);
|
||||
}
|
||||
|
||||
return reportMap;
|
||||
}
|
||||
}
|
||||
@@ -1,263 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 Basis Technology Corp.
|
||||
*
|
||||
* Copyright 2012 42six Solutions.
|
||||
* Contact: aebadirad <at> 42six <dot> com
|
||||
* Project Contact/Architect: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.report;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import org.openide.awt.ActionID;
|
||||
import org.openide.awt.ActionReference;
|
||||
import org.openide.awt.ActionReferences;
|
||||
import org.openide.awt.ActionRegistration;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
import org.openide.util.actions.Presenter;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
|
||||
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.report.ReportAction")
|
||||
@ActionRegistration(displayName = "#CTL_ReportAction")
|
||||
@ActionReferences(value = {
|
||||
@ActionReference(path = "Menu/Tools", position = 80)})
|
||||
@Messages(value = "CTL_ReportAction=Run Report")
|
||||
public final class ReportAction extends CallableSystemAction implements Presenter.Toolbar {
|
||||
|
||||
private JButton toolbarButton = new JButton();
|
||||
private static final String ACTION_NAME = "Generate Report";
|
||||
static final Logger logger = Logger.getLogger(ReportAction.class.getName());
|
||||
private JPanel panel;
|
||||
public static ArrayList<JCheckBox> reportList = new ArrayList<JCheckBox>();
|
||||
public static ArrayList<String> preview;
|
||||
public static ReportConfiguration config;
|
||||
|
||||
public ReportAction() {
|
||||
setEnabled(false);
|
||||
Case.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (evt.getPropertyName().equals(Case.CASE_CURRENT_CASE)) {
|
||||
Case newCase = (Case) evt.getNewValue();
|
||||
setEnabled(newCase != null);
|
||||
|
||||
//attempt to create a report folder if a case is active
|
||||
if (newCase != null) {
|
||||
boolean exists = (new File(newCase.getCaseDirectory() + File.separator + "Reports")).exists();
|
||||
if (exists) {
|
||||
// report directory exists -- don't need to do anything
|
||||
} else {
|
||||
// report directory does not exist -- create it
|
||||
boolean reportCreate = (new File(newCase.getCaseDirectory() + File.separator + "Reports")).mkdirs();
|
||||
if (!reportCreate) {
|
||||
logger.log(Level.WARNING, "Could not create Reports directory for case. It does not exist.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// set action of the toolbar button
|
||||
toolbarButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ReportAction.this.actionPerformed(e);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private class configListener implements ItemListener {
|
||||
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
Object source = e.getItem();
|
||||
JCheckBox comp = (JCheckBox) source;
|
||||
String name = comp.getName();
|
||||
BlackboardArtifact.ARTIFACT_TYPE type = BlackboardArtifact.ARTIFACT_TYPE.fromLabel(name);
|
||||
if (e.getStateChange() == ItemEvent.DESELECTED) {
|
||||
try {
|
||||
config.setGenArtifactType(type, Boolean.FALSE);
|
||||
} catch (ReportModuleException ex) {
|
||||
}
|
||||
}
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
try {
|
||||
config.setGenArtifactType(type, Boolean.TRUE);
|
||||
} catch (ReportModuleException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
|
||||
// create the popUp window for it
|
||||
final JFrame frame = new JFrame(ACTION_NAME);
|
||||
final JDialog popUpWindow = new JDialog(frame, ACTION_NAME, true); // to make the popUp Window to be modal
|
||||
popUpWindow.setLayout(new GridLayout(0, 1));
|
||||
// initialize panel with loaded settings
|
||||
final ReportFilter panel = new ReportFilter();
|
||||
panel.setjButton2ActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
popUpWindow.dispose();
|
||||
}
|
||||
});
|
||||
final configListener clistener = new configListener();
|
||||
preview = new ArrayList<String>();
|
||||
reportList.clear();
|
||||
config = new ReportConfiguration();
|
||||
int rows = Lookup.getDefault().lookupAll(ReportModule.class).size(); //One row for each report module
|
||||
final JPanel filterpanel = new JPanel(new GridLayout(rows, 2, 5, 5));
|
||||
final JPanel artpanel = new JPanel(new GridLayout(0, 3, 0, 0));
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
Border border = BorderFactory.createTitledBorder("Reporting Modules");
|
||||
filterpanel.setBorder(border);
|
||||
filterpanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
|
||||
filterpanel.setAlignmentY(Component.TOP_ALIGNMENT);
|
||||
filterpanel.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||
filterpanel.setSize(300, 200);
|
||||
int placement = 1;
|
||||
|
||||
for (ReportModule m : Lookup.getDefault().lookupAll(ReportModule.class)) {
|
||||
String name = m.getName();
|
||||
String desc = m.getReportTypeDescription();
|
||||
JCheckBox ch = new JCheckBox();
|
||||
ch.setAlignmentY(Component.TOP_ALIGNMENT);
|
||||
ch.setText(name);
|
||||
ch.setName(m.getClass().getName());
|
||||
ch.setToolTipText(desc);
|
||||
ch.setSelected(false);
|
||||
if(m.getName().equals(ReportHTML.getDefault().getName())){
|
||||
ch.setSelected(true);
|
||||
reportList.add(0, ch);
|
||||
}
|
||||
else{
|
||||
reportList.add(placement++, ch);
|
||||
}
|
||||
}
|
||||
for(int i = reportList.size()-1; i > -1; i--){
|
||||
filterpanel.add(reportList.get(i), 0);
|
||||
}
|
||||
Border artborder = BorderFactory.createTitledBorder("Report Data");
|
||||
artpanel.setBorder(artborder);
|
||||
artpanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
|
||||
artpanel.setAlignmentY(Component.TOP_ALIGNMENT);
|
||||
artpanel.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||
artpanel.setPreferredSize(new Dimension(300, 150));
|
||||
for (BlackboardArtifact.ARTIFACT_TYPE a : ReportFilter.config.config.keySet()) {
|
||||
JCheckBox ce = new JCheckBox();
|
||||
ce.setText(a.getDisplayName());
|
||||
ce.setToolTipText(a.getDisplayName());
|
||||
ce.setName(a.getLabel());
|
||||
ce.setPreferredSize(new Dimension(60, 30));
|
||||
ce.setSelected(true);
|
||||
ce.addItemListener(clistener);
|
||||
artpanel.add(ce);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
popUpWindow.add(filterpanel, 0);
|
||||
popUpWindow.add(artpanel, 1);
|
||||
// add the panel to the popup window
|
||||
popUpWindow.add(panel, 2);
|
||||
|
||||
popUpWindow.pack();
|
||||
popUpWindow.setResizable(false);
|
||||
// Modules need extra room for text to properly show
|
||||
popUpWindow.setSize(popUpWindow.getWidth(),
|
||||
popUpWindow.getHeight() + 50);
|
||||
|
||||
// set the location of the popUp Window on the center of the screen
|
||||
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
double w = popUpWindow.getSize().getWidth();
|
||||
double h = popUpWindow.getSize().getHeight();
|
||||
popUpWindow.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
|
||||
|
||||
// display the window
|
||||
popUpWindow.setVisible(true);
|
||||
// add the command to close the window to the button on the Case Properties form / panel
|
||||
|
||||
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(ReportFilterAction.class.getName()).log(Level.WARNING, "Error displaying " + ACTION_NAME + " window.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performAction() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return ACTION_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HelpCtx getHelpCtx() {
|
||||
return HelpCtx.DEFAULT_HELP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the toolbar component of this action
|
||||
*
|
||||
* @return component the toolbar button
|
||||
*/
|
||||
@Override
|
||||
public Component getToolbarPresenter() {
|
||||
ImageIcon icon = new ImageIcon(getClass().getResource("btn_icon_generate_report.png"));
|
||||
toolbarButton.setIcon(icon);
|
||||
toolbarButton.setText("Generate Report");
|
||||
return toolbarButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this action to be enabled/disabled
|
||||
*
|
||||
* @param value whether to enable this action or not
|
||||
*/
|
||||
@Override
|
||||
public void setEnabled(boolean value) {
|
||||
super.setEnabled(value);
|
||||
toolbarButton.setEnabled(value);
|
||||
}
|
||||
}
|
||||
@@ -23,43 +23,37 @@
|
||||
package org.sleuthkit.autopsy.report;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import javax.swing.JPanel;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.report.ReportProgressPanel.ReportStatus;
|
||||
import org.sleuthkit.datamodel.*;
|
||||
import org.sleuthkit.datamodel.TskData.TSK_FS_META_MODE_ENUM;
|
||||
|
||||
/**
|
||||
* ReportBodyFile generates a report in the body file format specified on
|
||||
* The Sleuth Kit wiki as MD5|name|inode|mode_as_string|UID|GID|size|atime|mtime|ctime|crtime.
|
||||
*/
|
||||
public class ReportBodyFile implements ReportModule {
|
||||
//Declare our publically accessible formatted Report, this will change everytime they run a Report
|
||||
private static String bodyFilePath = "";
|
||||
private ReportConfiguration config;
|
||||
private static ReportBodyFile instance = null;
|
||||
private Case currentCase = Case.getCurrentCase(); // get the current case
|
||||
private SleuthkitCase skCase = currentCase.getSleuthkitCase();
|
||||
public class ReportBodyFile implements GeneralReportModule {
|
||||
private static final Logger logger = Logger.getLogger(ReportBodyFile.class.getName());
|
||||
private static ReportBodyFile instance = null;
|
||||
|
||||
private Case currentCase;
|
||||
private SleuthkitCase skCase;
|
||||
|
||||
private String reportPath;
|
||||
|
||||
ReportBodyFile() {
|
||||
// Hidden constructor for the report
|
||||
private ReportBodyFile() {
|
||||
}
|
||||
|
||||
// Get the default implementation of this report
|
||||
public static synchronized ReportBodyFile getDefault() {
|
||||
if (instance == null) {
|
||||
instance = new ReportBodyFile();
|
||||
@@ -68,24 +62,19 @@ public class ReportBodyFile implements ReportModule {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a Body File report in the Reports folder of the current case.
|
||||
*
|
||||
* @param reportconfig unused in the body file
|
||||
* @return the path to the generated report
|
||||
* @throws ReportModuleException
|
||||
* Generates a body file format report for use with the MAC time tool.
|
||||
* @param path path to save the report
|
||||
* @param progressPanel panel to update the report's progress
|
||||
*/
|
||||
@Override
|
||||
public String generateReport(ReportConfiguration reportconfig) throws ReportModuleException {
|
||||
config = reportconfig;
|
||||
|
||||
// Setup timestamp
|
||||
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
|
||||
Date date = new Date();
|
||||
String datenotime = dateFormat.format(date);
|
||||
|
||||
// Get report path
|
||||
bodyFilePath = currentCase.getCaseDirectory() + File.separator + "Reports" +
|
||||
File.separator + currentCase.getName() + "-" + datenotime + ".txt";
|
||||
public void generateReport(String path, ReportProgressPanel progressPanel) {
|
||||
// Start the progress bar and setup the report
|
||||
progressPanel.setIndeterminate(false);
|
||||
progressPanel.start();
|
||||
progressPanel.updateStatusLabel("Querying files...");
|
||||
reportPath = path + "BodyFile.txt";
|
||||
currentCase = Case.getCurrentCase();
|
||||
skCase = currentCase.getSleuthkitCase();
|
||||
|
||||
// Run query to get all files
|
||||
ResultSet rs = null;
|
||||
@@ -95,24 +84,36 @@ public class ReportBodyFile implements ReportModule {
|
||||
+ "WHERE type = '" + TskData.TSK_DB_FILES_TYPE_ENUM.FS.getFileType() + "' "
|
||||
+ "AND name != '.' "
|
||||
+ "AND name != '..'");
|
||||
|
||||
progressPanel.updateStatusLabel("Loading files...");
|
||||
List<FsContent> fs = skCase.resultSetToFsContents(rs);
|
||||
// Check if ingest finished
|
||||
|
||||
// Check if ingest has finished
|
||||
String ingestwarning = "";
|
||||
if (IngestManager.getDefault().isIngestRunning()) {
|
||||
ingestwarning = "Warning, this report was run before ingest services completed!\n";
|
||||
}
|
||||
// Loop files and write info to report
|
||||
for (FsContent file : fs) {
|
||||
if (ReportFilter.cancel == true) {
|
||||
break;
|
||||
}
|
||||
|
||||
int size = fs.size();
|
||||
progressPanel.setMaximumProgress(size/100);
|
||||
|
||||
BufferedWriter out = null;
|
||||
try {
|
||||
// MD5|name|inode|mode_as_string|UID|GID|size|atime|mtime|ctime|crtime
|
||||
out = new BufferedWriter(new FileWriter(bodyFilePath, true));
|
||||
out.write(ingestwarning);
|
||||
|
||||
BufferedWriter out = null;
|
||||
try {
|
||||
// MD5|name|inode|mode_as_string|UID|GID|size|atime|mtime|ctime|crtime
|
||||
out = new BufferedWriter(new FileWriter(reportPath, true));
|
||||
out.write(ingestwarning);
|
||||
// Loop files and write info to report
|
||||
int count = 0;
|
||||
for (FsContent file : fs) {
|
||||
if (progressPanel.getStatus() == ReportStatus.CANCELED) {
|
||||
break;
|
||||
}
|
||||
if(count++ == 100) {
|
||||
progressPanel.increment();
|
||||
progressPanel.updateStatusLabel("Now processing " + file.getName() + "...");
|
||||
count = 0;
|
||||
}
|
||||
|
||||
if(file.getMd5Hash()!=null) {
|
||||
out.write(file.getMd5Hash());
|
||||
}
|
||||
@@ -142,94 +143,42 @@ public class ReportBodyFile implements ReportModule {
|
||||
out.write("|");
|
||||
out.write(Long.toString(file.getCrtime()));
|
||||
out.write("\n");
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Could not write the temp body file report.", ex);
|
||||
} finally {
|
||||
try {
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Could not write the temp body file report.", ex);
|
||||
} finally {
|
||||
try {
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Could not flush and close the BufferedWriter.", ex);
|
||||
}
|
||||
logger.log(Level.WARNING, "Could not flush and close the BufferedWriter.", ex);
|
||||
}
|
||||
}
|
||||
progressPanel.complete();
|
||||
} catch(SQLException ex) {
|
||||
logger.log(Level.WARNING, "Failed to get all file information.", ex);
|
||||
} catch(TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Failed to get the unique path.", ex);
|
||||
} finally {
|
||||
try {// Close the query
|
||||
if(rs!=null) { skCase.closeRunQuery(rs); }
|
||||
if(rs!=null) {
|
||||
skCase.closeRunQuery(rs);
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.WARNING, "Failed to close the query.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return bodyFilePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
String name = "Body File (Timeline Report)";
|
||||
String name = "Body File";
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the previously generated report to the given path.
|
||||
* If the report was not generated in generateReport, save will attempt
|
||||
* to regenerate it, then copy the file. If the regeneration fails, the
|
||||
* incident is logged.
|
||||
*/
|
||||
@Override
|
||||
public void save(String path) {
|
||||
File caseFile = new File(bodyFilePath);
|
||||
if(!caseFile.exists()) {
|
||||
logger.log(Level.WARNING, "Body File report does not exist.");
|
||||
try {
|
||||
// Try to generate it again
|
||||
generateReport(config);
|
||||
logger.log(Level.INFO, "Body File report has been regenerated.");
|
||||
} catch (ReportModuleException ex) {
|
||||
logger.log(Level.WARNING, "Failed attempt to regenerate the report.", ex);
|
||||
}
|
||||
}
|
||||
// Check again
|
||||
if(caseFile.exists()) {
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
try {
|
||||
in = new FileInputStream(caseFile);
|
||||
out = new FileOutputStream(path);
|
||||
byte[] b = new byte[Integer.parseInt(Long.toString(caseFile.length()))];
|
||||
int len = b.length;
|
||||
int total = 0;
|
||||
int result = 0;
|
||||
|
||||
while ((result = in.read(b, total, len-total)) > 0) {
|
||||
out.write(b, total, len);
|
||||
total += result;
|
||||
}
|
||||
} catch(FileNotFoundException ex) {
|
||||
logger.log(Level.WARNING, "Could find the file specified.", ex);
|
||||
} catch(IOException ex) {
|
||||
logger.log(Level.WARNING, "Could not read from the FileInputStream.", ex);
|
||||
} finally {
|
||||
try {
|
||||
in.close();
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Could not close and flush the streams.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Otherwise give up
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReportType() {
|
||||
String type = "BodyFile";
|
||||
return type;
|
||||
public String getFilePath() {
|
||||
return "BodyFile.txt";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -239,18 +188,13 @@ public class ReportBodyFile implements ReportModule {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReportConfiguration GetReportConfiguration() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReportTypeDescription() {
|
||||
String desc = "Body file format report with MAC times for every file, that can be used for a timeline view.";
|
||||
public String getDescription() {
|
||||
String desc = "Body file format report with MAC times for every file. This format can be used for a timeline view.";
|
||||
return desc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPreview(String path) {
|
||||
BrowserControl.openUrl(path);
|
||||
public JPanel getConfigurationPanel() {
|
||||
return null; // No configuration panel
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 Basis Technology Corp.
|
||||
*
|
||||
* Copyright 2012 42six Solutions.
|
||||
* Contact: aebadirad <at> 42six <dot> com
|
||||
* Project Contact/Architect: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.report;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
|
||||
/**
|
||||
* Configures which parts of report were requested e.g. based on user input Some
|
||||
* specialized reporting modules may choose not to generate all requested
|
||||
* sections and some modules may generate additional, specialized sections
|
||||
*
|
||||
*/
|
||||
public class ReportConfiguration {
|
||||
|
||||
//base data structure
|
||||
Map<BlackboardArtifact.ARTIFACT_TYPE, Boolean> config = new EnumMap<BlackboardArtifact.ARTIFACT_TYPE, Boolean>(BlackboardArtifact.ARTIFACT_TYPE.class);
|
||||
private final Logger logger = Logger.getLogger(this.getClass().getName());
|
||||
|
||||
ReportConfiguration() {
|
||||
//clear the config just incase before we get the list from the db again
|
||||
config.clear();
|
||||
//now lets get the list from the tsk and current case
|
||||
Case currentCase = Case.getCurrentCase(); // get the most updated case
|
||||
SleuthkitCase skCase = currentCase.getSleuthkitCase();
|
||||
try {
|
||||
ArrayList<BlackboardArtifact.ARTIFACT_TYPE> arttypes = skCase.getBlackboardArtifactTypes();
|
||||
for (BlackboardArtifact.ARTIFACT_TYPE type : arttypes) {
|
||||
config.put(type, Boolean.TRUE);
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "Error while trying to retrieve list of artifact types from the TSK case .", ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
/**regets everything that occurs in the constructor normally
|
||||
*
|
||||
* @throws ReportModuleException
|
||||
*/
|
||||
public void getAllTypes() throws ReportModuleException {
|
||||
config.clear();
|
||||
//now lets get the list from the tsk and current case
|
||||
Case currentCase = Case.getCurrentCase(); // get the most updated case
|
||||
SleuthkitCase skCase = currentCase.getSleuthkitCase();
|
||||
try {
|
||||
ArrayList<BlackboardArtifact.ARTIFACT_TYPE> arttypes = skCase.getBlackboardArtifactTypes();
|
||||
for (BlackboardArtifact.ARTIFACT_TYPE type : arttypes) {
|
||||
config.put(type, Boolean.TRUE);
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "Error while trying to retrieve list of artifact types from the TSK case .", ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
/**setters for generally supported report parts
|
||||
*
|
||||
*/
|
||||
public void setGenArtifactType(BlackboardArtifact.ARTIFACT_TYPE type, Boolean value) throws ReportModuleException {
|
||||
if (config.containsKey(type)) {
|
||||
config.put(type, value);
|
||||
} else {
|
||||
throw new ReportModuleException("The following artifact type is not present:" + type);
|
||||
}
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
/**This allows all that setting to happen in groups
|
||||
*
|
||||
*/
|
||||
public void setGenArtifactType(ArrayList<BlackboardArtifact.ARTIFACT_TYPE> typeList, boolean value) throws ReportModuleException {
|
||||
|
||||
for (BlackboardArtifact.ARTIFACT_TYPE type : typeList) {
|
||||
if (config.containsKey(type)) {
|
||||
config.put(type, value);
|
||||
} else {
|
||||
throw new ReportModuleException("The following artifact type is not present:" + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
|
||||
/** getters for generally supported report parts
|
||||
* @param type is a blackboardartifact type
|
||||
* @return value is the artifact type
|
||||
*/
|
||||
public boolean getGenArtifactType(BlackboardArtifact.ARTIFACT_TYPE type) throws ReportModuleException {
|
||||
boolean value = false;
|
||||
if (config.containsKey(type)) {
|
||||
value = config.get(type);
|
||||
} else {
|
||||
throw new ReportModuleException("The following artifact type is not present:" + type);
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
public void resetGenArtifactTypes() {
|
||||
for (Map.Entry<BlackboardArtifact.ARTIFACT_TYPE, Boolean> entry : config.entrySet()) {
|
||||
config.put(entry.getKey(), Boolean.FALSE);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 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.report;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.logging.Level;
|
||||
import org.apache.poi.hssf.util.HSSFColor;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
public class ReportExcel implements TableReportModule {
|
||||
private static final Logger logger = Logger.getLogger(ReportExcel.class.getName());
|
||||
private static ReportExcel instance;
|
||||
private Case currentCase;
|
||||
|
||||
private Workbook wb;
|
||||
private Sheet sheet;
|
||||
private CellStyle titleStyle;
|
||||
private CellStyle setStyle;
|
||||
private CellStyle elementStyle;
|
||||
private int rowCount = 2;
|
||||
|
||||
private Map<String, Integer> dataTypes;
|
||||
private String currentDataType;
|
||||
private String reportPath;
|
||||
|
||||
// Get the default instance of this report
|
||||
public static synchronized ReportExcel getDefault() {
|
||||
if (instance == null) {
|
||||
instance = new ReportExcel();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
// Hidden constructor
|
||||
private ReportExcel() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the Excel report by creating the Workbook, initializing styles,
|
||||
* and writing the summary.
|
||||
* @param path path to save the report
|
||||
*/
|
||||
@Override
|
||||
public void startReport(String path) {
|
||||
currentCase = Case.getCurrentCase();
|
||||
|
||||
wb = new XSSFWorkbook();
|
||||
|
||||
titleStyle = wb.createCellStyle();
|
||||
titleStyle.setBorderBottom((short) 1);
|
||||
Font titleFont = wb.createFont();
|
||||
titleFont.setFontHeightInPoints((short) 12);
|
||||
titleStyle.setFont(titleFont);
|
||||
|
||||
setStyle = wb.createCellStyle();
|
||||
Font setFont = wb.createFont();
|
||||
setFont.setFontHeightInPoints((short) 14);
|
||||
setFont.setBoldweight((short) 10);
|
||||
setStyle.setFont(setFont);
|
||||
|
||||
elementStyle = wb.createCellStyle();
|
||||
elementStyle.setFillBackgroundColor(HSSFColor.LIGHT_YELLOW.index);
|
||||
Font elementFont = wb.createFont();
|
||||
elementFont.setFontHeightInPoints((short) 14);
|
||||
elementStyle.setFont(elementFont);
|
||||
|
||||
dataTypes = new TreeMap<String, Integer>();
|
||||
this.reportPath = path + getFilePath();
|
||||
|
||||
// Write the summary
|
||||
sheet = wb.createSheet("Summary");
|
||||
sheet.createRow(0).createCell(0).setCellValue("Case Name:");
|
||||
sheet.getRow(0).createCell(1).setCellValue(currentCase.getName());
|
||||
sheet.createRow(1).createCell(0).setCellValue("Case Number:");
|
||||
sheet.getRow(1).createCell(1).setCellValue(currentCase.getNumber());
|
||||
sheet.createRow(2).createCell(0).setCellValue("Examiner:");
|
||||
sheet.getRow(2).createCell(1).setCellValue(currentCase.getExaminer());
|
||||
sheet.createRow(3).createCell(0).setCellValue("# of Images:");
|
||||
sheet.getRow(3).createCell(1).setCellValue(currentCase.getImageIDs().length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the Workbook to a file and end the report.
|
||||
*/
|
||||
@Override
|
||||
public void endReport() {
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
out = new FileOutputStream(reportPath);
|
||||
wb.write(out);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to write Excel report.", ex);
|
||||
} finally {
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a new sheet for the given data type.
|
||||
* @param title data type name
|
||||
*/
|
||||
@Override
|
||||
public void startDataType(String title) {
|
||||
sheet = wb.createSheet(title);
|
||||
sheet.setAutobreaks(true);
|
||||
currentDataType = title;
|
||||
}
|
||||
|
||||
/**
|
||||
* End the current data type and sheet.
|
||||
*/
|
||||
@Override
|
||||
public void endDataType() {
|
||||
Row temp = sheet.createRow(0);
|
||||
temp.createCell(0).setCellValue("Number of " + currentDataType + " artifacts:");
|
||||
temp.createCell(1).setCellValue(rowCount);
|
||||
|
||||
dataTypes.put(currentDataType, rowCount);
|
||||
rowCount = 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a new set for the current data type.
|
||||
* @param setName name of the set
|
||||
*/
|
||||
@Override
|
||||
public void startSet(String setName) {
|
||||
Row temp = sheet.createRow(rowCount);
|
||||
temp.setRowStyle(setStyle);
|
||||
temp.createCell(0).setCellValue(setName);
|
||||
rowCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* End the current set.
|
||||
*/
|
||||
@Override
|
||||
public void endSet() {
|
||||
rowCount++; // Put a space between the sets
|
||||
}
|
||||
|
||||
// Ignored in Excel Report
|
||||
@Override
|
||||
public void addSetIndex(List<String> sets) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an element to the set
|
||||
* @param elementName element name
|
||||
*/
|
||||
@Override
|
||||
public void addSetElement(String elementName) {
|
||||
Row temp = sheet.createRow(rowCount);
|
||||
temp.setRowStyle(elementStyle);
|
||||
temp.createCell(0).setCellValue(elementName);
|
||||
rowCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Label the top of this sheet with the table column names.
|
||||
* @param titles column names
|
||||
*/
|
||||
@Override
|
||||
public void startTable(List<String> titles) {
|
||||
Row temp = sheet.createRow(rowCount);
|
||||
temp.setRowStyle(titleStyle);
|
||||
for (int i=0; i<titles.size(); i++) {
|
||||
temp.createCell(i).setCellValue(titles.get(i));
|
||||
}
|
||||
rowCount++;
|
||||
}
|
||||
|
||||
// Do nothing on end table
|
||||
@Override
|
||||
public void endTable() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a row of information to the report.
|
||||
* @param row cells to add
|
||||
*/
|
||||
@Override
|
||||
public void addRow(List<String> row) {
|
||||
Row temp = sheet.createRow(rowCount);
|
||||
for (int i=0; i<row.size(); i++) {
|
||||
temp.createCell(i).setCellValue(row.get(i));
|
||||
}
|
||||
rowCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the given long date as a String.
|
||||
* @param date as a long
|
||||
* @return String date
|
||||
*/
|
||||
@Override
|
||||
public String dateToString(long date) {
|
||||
SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
||||
return sdf.format(new java.util.Date(date * 1000));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Excel";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "An XLS formatted report which is meant to be viewed in Excel.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtension() {
|
||||
return ".xlsx";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFilePath() {
|
||||
return "Excel.xlsx";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.JButton" name="jButton2">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.jButton2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.jButton2.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="label" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.jButton2.label" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[500, 75]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<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="false"/>
|
||||
<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">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="updateLabel" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="jButton1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="progBar" pref="395" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="24" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
|
||||
<Component id="jButton1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="cancelButton" max="32767" attributes="0"/>
|
||||
<Component id="progBar" min="-2" pref="23" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="updateLabel" min="-2" pref="11" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JProgressBar" name="progBar">
|
||||
<Properties>
|
||||
<Property name="doubleBuffered" type="boolean" value="true"/>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="name" type="java.lang.String" value="" noResource="true"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[146, 15]"/>
|
||||
</Property>
|
||||
<Property name="string" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.progBar.string" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="stringPainted" type="boolean" value="true"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="jButton1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.jButton1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="mouseReleased" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jButton1MouseReleased"/>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton1ActionPerformed"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="reportFilter_jButton1"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="cancelButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.cancelButton.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="updateLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.updateLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.updateLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -1,289 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 Basis Technology Corp.
|
||||
*
|
||||
* Copyright 2012 42six Solutions.
|
||||
* Contact: aebadirad <at> 42six <dot> com
|
||||
* Project Contact/Architect: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.report;
|
||||
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import org.openide.util.Lookup;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alex
|
||||
*/
|
||||
public class ReportFilter extends javax.swing.JPanel {
|
||||
|
||||
public static ArrayList<Integer> filters = new ArrayList<Integer>();
|
||||
public static ReportConfiguration config = new ReportConfiguration();
|
||||
private final Logger logger = Logger.getLogger(this.getClass().getName());
|
||||
public final ReportFilter panel = this;
|
||||
ReportPanelAction rpa = new ReportPanelAction();
|
||||
public static boolean cancel = false;
|
||||
Case currentCase = Case.getCurrentCase(); // get the most updated case
|
||||
SleuthkitCase skCase = currentCase.getSleuthkitCase();
|
||||
|
||||
/**
|
||||
* Creates new form ReportFilter
|
||||
*/
|
||||
public ReportFilter() {
|
||||
this.setLayout(new GridLayout(0, 1));
|
||||
initComponents();
|
||||
cancel = false;
|
||||
try {
|
||||
config.getAllTypes();
|
||||
|
||||
} catch (ReportModuleException ex) {
|
||||
Logger.getLogger(Report.class.getName()).log(Level.WARNING, "Exception occurred", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
jButton2 = new javax.swing.JButton();
|
||||
progBar = new javax.swing.JProgressBar();
|
||||
jButton1 = new javax.swing.JButton();
|
||||
cancelButton = new javax.swing.JButton();
|
||||
updateLabel = new javax.swing.JLabel();
|
||||
|
||||
jButton2.setText(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.jButton2.text")); // NOI18N
|
||||
jButton2.setActionCommand(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.jButton2.actionCommand")); // NOI18N
|
||||
jButton2.setLabel(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.jButton2.label")); // NOI18N
|
||||
|
||||
setPreferredSize(new java.awt.Dimension(500, 75));
|
||||
|
||||
progBar.setDoubleBuffered(true);
|
||||
progBar.setEnabled(false);
|
||||
progBar.setName(""); // NOI18N
|
||||
progBar.setPreferredSize(new java.awt.Dimension(146, 15));
|
||||
progBar.setString(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.progBar.string")); // NOI18N
|
||||
progBar.setStringPainted(true);
|
||||
|
||||
jButton1.setText(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.jButton1.text")); // NOI18N
|
||||
jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
|
||||
public void mouseReleased(java.awt.event.MouseEvent evt) {
|
||||
jButton1MouseReleased(evt);
|
||||
}
|
||||
});
|
||||
jButton1.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButton1ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
cancelButton.setText(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.cancelButton.text")); // NOI18N
|
||||
cancelButton.setActionCommand(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.cancelButton.actionCommand")); // NOI18N
|
||||
cancelButton.setEnabled(false);
|
||||
cancelButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cancelButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
updateLabel.setText(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.updateLabel.text")); // NOI18N
|
||||
updateLabel.setToolTipText(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.updateLabel.toolTipText")); // 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)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(updateLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jButton1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(progBar, javax.swing.GroupLayout.DEFAULT_SIZE, 395, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cancelButton)))
|
||||
.addGap(24, 24, 24))))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(19, 19, 19)
|
||||
.addComponent(jButton1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(cancelButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(progBar, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(updateLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 11, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
public void getfilters(java.awt.event.ActionEvent evt) {
|
||||
jButton1ActionPerformed(evt);
|
||||
}
|
||||
|
||||
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
|
||||
|
||||
jButton1.setEnabled(false);
|
||||
progBar.setEnabled(true);
|
||||
cancelButton.setEnabled(true);
|
||||
progBar.setStringPainted(true);
|
||||
progBar.setValue(0);
|
||||
ReportConfiguration newConfig = ReportAction.config;
|
||||
ArrayList<String> preview = ReportAction.preview;
|
||||
ArrayList<JCheckBox> reportList = ReportAction.reportList;
|
||||
ArrayList<String> classList = new ArrayList<String>();
|
||||
for (JCheckBox box : reportList) {
|
||||
if (box.isSelected()) {
|
||||
classList.add(box.getName());
|
||||
|
||||
}
|
||||
}
|
||||
config.resetGenArtifactTypes();
|
||||
getReports(newConfig, classList, preview);
|
||||
}//GEN-LAST:event_jButton1ActionPerformed
|
||||
|
||||
public void getReports(final ReportConfiguration reportConfig, final ArrayList<String> classList, final ArrayList<String> preview) {
|
||||
new SwingWorker<Void, Void>() {
|
||||
|
||||
@Override
|
||||
protected Void doInBackground() throws Exception {
|
||||
rpa.reportGenerate(reportConfig, classList, preview, panel);
|
||||
return null;
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
// this is called when the SwingWorker's doInBackground finishes
|
||||
@Override
|
||||
protected void done() {
|
||||
progBar.setVisible(false); // hide my progress bar JFrame
|
||||
}
|
||||
;
|
||||
}.execute();
|
||||
progBar.setVisible(true);
|
||||
}
|
||||
|
||||
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
|
||||
cancelButton.setText("Cancelled!");
|
||||
cancel = true;
|
||||
}//GEN-LAST:event_cancelButtonActionPerformed
|
||||
|
||||
private void jButton1MouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton1MouseReleased
|
||||
}//GEN-LAST:event_jButton1MouseReleased
|
||||
|
||||
public void progBarSet(int cc) {
|
||||
final int count = cc;
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
int start = progBar.getValue();
|
||||
int end = start + count;
|
||||
progBar.setValue(end);
|
||||
progBar.setString(null);
|
||||
progBar.setString(progBar.getString());
|
||||
progBar.setStringPainted(true);
|
||||
if (progBar.getPercentComplete() == 1.0) {
|
||||
progBar.setString("Populating Report - Please wait...");
|
||||
progBar.setStringPainted(true);
|
||||
progBar.setIndeterminate(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void progBarDone() {
|
||||
int max = progBar.getMaximum();
|
||||
progBar.setValue(max);
|
||||
jButton2.doClick();
|
||||
}
|
||||
|
||||
public void progBarStartText() {
|
||||
progBar.setIndeterminate(true);
|
||||
progBar.setString("Querying Database for Report Results...");
|
||||
}
|
||||
|
||||
public void setUpdateLabel(final String text) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
updateLabel.setText(text);
|
||||
updateLabel.repaint();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void progBarText() {
|
||||
|
||||
progBar.setString("Populating Report - Please wait...");
|
||||
progBar.setStringPainted(true);
|
||||
progBar.repaint();
|
||||
progBar.setIndeterminate(true);
|
||||
|
||||
}
|
||||
|
||||
public void progBarCount(int count) {
|
||||
progBar.setIndeterminate(false);
|
||||
progBar.setString(null);
|
||||
progBar.setMinimum(0);
|
||||
progBar.setMaximum(count);
|
||||
progBar.setValue(0);
|
||||
//Double bper = progBar.getPercentComplete();
|
||||
progBar.setString(progBar.getString());
|
||||
|
||||
}
|
||||
|
||||
public void setjButton1ActionListener(ActionListener e) {
|
||||
jButton1.addActionListener(e);
|
||||
|
||||
}
|
||||
|
||||
public void setjButton2ActionListener(ActionListener e) {
|
||||
jButton2.addActionListener(e);
|
||||
cancelButton.addActionListener(e);
|
||||
}
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton cancelButton;
|
||||
private javax.swing.JButton jButton1;
|
||||
private javax.swing.JButton jButton2;
|
||||
private javax.swing.JProgressBar progBar;
|
||||
private javax.swing.JLabel updateLabel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 Basis Technology Corp.
|
||||
*
|
||||
* Copyright 2011 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.report;
|
||||
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* The ReportFilterAction opens the reportFilterPanel in a dialog, and saves the
|
||||
* settings of the panel if the Apply button is clicked.
|
||||
*
|
||||
* @author pmartel
|
||||
*/
|
||||
class ReportFilterAction {
|
||||
|
||||
private static final String ACTION_NAME = "Report Window";
|
||||
|
||||
//@Override
|
||||
public void performAction() {
|
||||
Logger.noteAction(this.getClass());
|
||||
|
||||
try {
|
||||
|
||||
// create the popUp window for it
|
||||
Container cpane;
|
||||
final JFrame frame = new JFrame(ACTION_NAME);
|
||||
final JDialog popUpWindow = new JDialog(frame, ACTION_NAME, true); // to make the popUp Window to be modal
|
||||
cpane = frame.getContentPane();
|
||||
// initialize panel with loaded settings
|
||||
final ReportFilter panel = new ReportFilter();
|
||||
|
||||
// add the panel to the popup window
|
||||
popUpWindow.add(panel);
|
||||
popUpWindow.pack();
|
||||
popUpWindow.setResizable(false);
|
||||
|
||||
// set the location of the popUp Window on the center of the screen
|
||||
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
double w = popUpWindow.getSize().getWidth();
|
||||
double h = popUpWindow.getSize().getHeight();
|
||||
popUpWindow.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
|
||||
// display the window
|
||||
popUpWindow.setVisible(true);
|
||||
|
||||
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(ReportFilterAction.class.getName()).log(Level.WARNING, "Error displaying " + ACTION_NAME + " window.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
//@Override
|
||||
public String getName() {
|
||||
return ACTION_NAME;
|
||||
}
|
||||
|
||||
// @Override
|
||||
public HelpCtx getHelpCtx() {
|
||||
return HelpCtx.DEFAULT_HELP;
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 Basis Technology Corp.
|
||||
*
|
||||
* Copyright 2012 42six Solutions.
|
||||
* Contact: aebadirad <at> 42six <dot> com
|
||||
* Project Contact/Architect: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.report;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class is the 'default' way to get artifacts/attributes from the
|
||||
* blackboard using a reportconfiguration object.
|
||||
*/
|
||||
public class ReportGen {
|
||||
|
||||
private HashMap<BlackboardArtifact, List<BlackboardAttribute>> results = new HashMap<BlackboardArtifact, List<BlackboardAttribute>>();
|
||||
|
||||
ReportGen() {
|
||||
}
|
||||
|
||||
HashMap<BlackboardArtifact, List<BlackboardAttribute>> getResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
public void clearReport() {
|
||||
results.clear();
|
||||
}
|
||||
|
||||
public void populateReport(ReportConfiguration config) {
|
||||
clearReport();
|
||||
Report bbreport = new Report();
|
||||
results = bbreport.getAllTypes(config);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[700, 400]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
@@ -16,20 +21,19 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="optionSeparator" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="reportScrollPane" alignment="0" pref="404" max="32767" attributes="0"/>
|
||||
<Component id="statusLabel" alignment="1" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="LABEL_LOC" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="reportScrollPane" max="32767" attributes="0"/>
|
||||
<Component id="titleSeparator" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="titleLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="522" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="exportButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="ButtonOpenFolder" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="380" max="32767" attributes="0"/>
|
||||
<Component id="cancelAllButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="closeButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
@@ -42,93 +46,103 @@
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="reportScrollPane" min="-2" pref="125" max="-2" attributes="0"/>
|
||||
<Component id="titleLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="titleSeparator" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="statusLabel" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="reportScrollPane" pref="290" max="32767" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="optionSeparator" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="LABEL_LOC" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="closeButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="exportButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="ButtonOpenFolder" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cancelAllButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="closeButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportGenerationPanel.closeButton.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="closeButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="cancelAllButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportGenerationPanel.cancelAllButton.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="cancelAllButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="reportScrollPane">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Report Summary">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportPanel.reportScrollPane.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
<Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
|
||||
<LineBorder>
|
||||
<Color PropertyName="color" blue="b4" green="b4" id="Active Caption Border" palette="2" red="b4" type="palette"/>
|
||||
</LineBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="verticalScrollBarPolicy" type="int" value="22"/>
|
||||
</Properties>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="reportSummaryPanel">
|
||||
<Container class="javax.swing.JPanel" name="reportPanel">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[600, 400]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="675" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="661" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="214" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="400" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="closeButton">
|
||||
<Component class="javax.swing.JLabel" name="titleLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Tahoma" size="11" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportPanel.closeButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportGenerationPanel.titleLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="exportButton">
|
||||
<Component class="javax.swing.JSeparator" name="titleSeparator">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportPanel.exportButton.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="exportButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="statusLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportPanel.statusLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="0" green="0" red="0" type="rgb"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="LABEL_LOC">
|
||||
<Component class="javax.swing.JSeparator" name="optionSeparator">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportPanel.LABEL_LOC.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="0" green="0" red="0" type="rgb"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="ButtonOpenFolder">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportPanel.ButtonOpenFolder.text_1" 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="ButtonOpenFolderActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 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.report;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.sleuthkit.autopsy.report.ReportProgressPanel.ReportStatus;
|
||||
|
||||
public class ReportGenerationPanel extends javax.swing.JPanel {
|
||||
private GridBagConstraints c;
|
||||
private List<ReportProgressPanel> progressPanels;
|
||||
private Component glue;
|
||||
private ActionListener actionListener;
|
||||
|
||||
/**
|
||||
* Creates new form ReportGenerationPanel
|
||||
*/
|
||||
public ReportGenerationPanel() {
|
||||
initComponents();
|
||||
customInit();
|
||||
}
|
||||
|
||||
private void customInit() {
|
||||
reportPanel.setLayout(new GridBagLayout());
|
||||
progressPanels = new ArrayList<ReportProgressPanel>();
|
||||
c = new GridBagConstraints();
|
||||
c.fill = GridBagConstraints.BOTH;
|
||||
c.gridx = 0;
|
||||
c.gridy = 0;
|
||||
c.weightx = 1.0;
|
||||
glue = Box.createVerticalGlue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a ReportProgressPanel to this panel with the given report name and path.
|
||||
*
|
||||
* @param reportName report name
|
||||
* @param reportPath report path
|
||||
* @return ReportProgressPanel progress panel to update
|
||||
*/
|
||||
public ReportProgressPanel addReport(String reportName, String reportPath) {
|
||||
// Remove the glue
|
||||
reportPanel.remove(glue);
|
||||
|
||||
// Add the new panel
|
||||
ReportProgressPanel panel = new ReportProgressPanel(reportName, reportPath);
|
||||
progressPanels.add(panel);
|
||||
c.weighty = 0.0;
|
||||
c.anchor = GridBagConstraints.NORTH;
|
||||
reportPanel.add(panel, c);
|
||||
c.gridy++;
|
||||
|
||||
// Add the glue back to the bottom
|
||||
c.weighty = 1.0;
|
||||
c.anchor = GridBagConstraints.PAGE_END;
|
||||
reportPanel.add(glue, c);
|
||||
|
||||
reportPanel.setPreferredSize(new Dimension(600, progressPanels.size() * 80));
|
||||
reportPanel.repaint();
|
||||
return panel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close this panel and it's dialog if all reports are done.
|
||||
*/
|
||||
void close() {
|
||||
boolean closeable = true;
|
||||
for (ReportProgressPanel panel : progressPanels) {
|
||||
if (panel.getStatus() != ReportStatus.CANCELED && panel.getStatus() != ReportStatus.COMPLETE) {
|
||||
closeable = false;
|
||||
}
|
||||
}
|
||||
if (closeable) {
|
||||
actionListener.actionPerformed(null);
|
||||
} else {
|
||||
int result = JOptionPane.showConfirmDialog(null, "Are you sure you'd like to close the dialog?\nAll reports will be canceled.", "Closing", JOptionPane.YES_NO_OPTION);
|
||||
if (result == 0) {
|
||||
cancelAllReports();
|
||||
actionListener.actionPerformed(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel all reports.
|
||||
*/
|
||||
private void cancelAllReports() {
|
||||
for (ReportProgressPanel panel : progressPanels) {
|
||||
panel.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
closeButton = new javax.swing.JButton();
|
||||
cancelAllButton = new javax.swing.JButton();
|
||||
reportScrollPane = new javax.swing.JScrollPane();
|
||||
reportPanel = new javax.swing.JPanel();
|
||||
titleLabel = new javax.swing.JLabel();
|
||||
titleSeparator = new javax.swing.JSeparator();
|
||||
optionSeparator = new javax.swing.JSeparator();
|
||||
|
||||
setPreferredSize(new java.awt.Dimension(700, 400));
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(closeButton, org.openide.util.NbBundle.getMessage(ReportGenerationPanel.class, "ReportGenerationPanel.closeButton.text")); // NOI18N
|
||||
closeButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
closeButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(cancelAllButton, org.openide.util.NbBundle.getMessage(ReportGenerationPanel.class, "ReportGenerationPanel.cancelAllButton.text")); // NOI18N
|
||||
cancelAllButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cancelAllButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
reportScrollPane.setBorder(javax.swing.BorderFactory.createLineBorder(java.awt.SystemColor.activeCaptionBorder));
|
||||
reportScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
|
||||
|
||||
reportPanel.setPreferredSize(new java.awt.Dimension(600, 400));
|
||||
|
||||
javax.swing.GroupLayout reportPanelLayout = new javax.swing.GroupLayout(reportPanel);
|
||||
reportPanel.setLayout(reportPanelLayout);
|
||||
reportPanelLayout.setHorizontalGroup(
|
||||
reportPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 661, Short.MAX_VALUE)
|
||||
);
|
||||
reportPanelLayout.setVerticalGroup(
|
||||
reportPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 400, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
reportScrollPane.setViewportView(reportPanel);
|
||||
|
||||
titleLabel.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(titleLabel, org.openide.util.NbBundle.getMessage(ReportGenerationPanel.class, "ReportGenerationPanel.titleLabel.text")); // NOI18N
|
||||
|
||||
titleSeparator.setForeground(new java.awt.Color(0, 0, 0));
|
||||
|
||||
optionSeparator.setForeground(new java.awt.Color(0, 0, 0));
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(optionSeparator)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(reportScrollPane)
|
||||
.addComponent(titleSeparator, javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
|
||||
.addComponent(titleLabel)
|
||||
.addGap(0, 522, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(0, 380, Short.MAX_VALUE)
|
||||
.addComponent(cancelAllButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(closeButton)))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(titleLabel)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(titleSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(reportScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 290, Short.MAX_VALUE)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(optionSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(closeButton)
|
||||
.addComponent(cancelAllButton))
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
|
||||
close();
|
||||
}//GEN-LAST:event_closeButtonActionPerformed
|
||||
|
||||
private void cancelAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelAllButtonActionPerformed
|
||||
int result = JOptionPane.showConfirmDialog(null, "Are you sure you'd like to cancel all the reports?", "Cancel All", JOptionPane.YES_NO_OPTION);
|
||||
if (result == 0) {
|
||||
cancelAllReports();
|
||||
}
|
||||
}//GEN-LAST:event_cancelAllButtonActionPerformed
|
||||
|
||||
void addCloseAction(ActionListener l) {
|
||||
this.actionListener = l;
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton cancelAllButton;
|
||||
private javax.swing.JButton closeButton;
|
||||
private javax.swing.JSeparator optionSeparator;
|
||||
private javax.swing.JPanel reportPanel;
|
||||
private javax.swing.JScrollPane reportScrollPane;
|
||||
private javax.swing.JLabel titleLabel;
|
||||
private javax.swing.JSeparator titleSeparator;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -0,0 +1,950 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 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.report;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.openide.filesystems.FileUtil;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datamodel.Tags;
|
||||
import org.sleuthkit.autopsy.report.ReportProgressPanel.ReportStatus;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
|
||||
/**
|
||||
* Generates all TableReportModules and GeneralReportModules, given whether each module for both
|
||||
* types is enabled or disabled, and the base report path to save them at.
|
||||
*
|
||||
* After creating an instance of ReportGenerator, one must tell it which reports to run,
|
||||
* TableReportModules on Tags or Artifacts, and the GeneralReportModules.
|
||||
* Then, one calls displayProgressPanels() to display the progress to the user.
|
||||
*/
|
||||
public class ReportGenerator {
|
||||
private static final Logger logger = Logger.getLogger(ReportGenerator.class.getName());
|
||||
|
||||
private Case currentCase = Case.getCurrentCase();
|
||||
private SleuthkitCase skCase = currentCase.getSleuthkitCase();
|
||||
|
||||
private Map<TableReportModule, ReportProgressPanel> tableProgress;
|
||||
private Map<GeneralReportModule, ReportProgressPanel> generalProgress;
|
||||
|
||||
private String reportPath;
|
||||
private ReportGenerationPanel panel = new ReportGenerationPanel();
|
||||
|
||||
ReportGenerator(Map<TableReportModule, Boolean> tableModuleStates, Map<GeneralReportModule, Boolean> generalModuleStates) {
|
||||
// Setup the reporting directory to be [CASE DIRECTORY]/Reports/[Case name] [Timestamp]/
|
||||
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
|
||||
Date date = new Date();
|
||||
String datenotime = dateFormat.format(date);
|
||||
this.reportPath = currentCase.getCaseDirectory() + File.separator + "Reports" + File.separator + currentCase.getName() + " " + datenotime + File.separator;
|
||||
// Create the reporting directory
|
||||
try {
|
||||
FileUtil.createFolder(new File(this.reportPath));
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to make report folder, may be unable to generate reports.", ex);
|
||||
}
|
||||
|
||||
// Initialize the progress panels
|
||||
generalProgress = new HashMap<GeneralReportModule, ReportProgressPanel>();
|
||||
tableProgress = new HashMap<TableReportModule, ReportProgressPanel>();
|
||||
setupProgressPanels(tableModuleStates, generalModuleStates);
|
||||
}
|
||||
|
||||
/**
|
||||
* For every ReportModule which the user enabled, create a ReportProgressPanel for that report.
|
||||
*
|
||||
* @param tableModuleStates the enabled/disabled state of each TableReportModule
|
||||
* @param generalModuleStates the enabled/disabled state of each GeneralReportModule
|
||||
*/
|
||||
private void setupProgressPanels(Map<TableReportModule, Boolean> tableModuleStates, Map<GeneralReportModule, Boolean> generalModuleStates) {
|
||||
for (Entry<TableReportModule, Boolean> entry : tableModuleStates.entrySet()) {
|
||||
if (entry.getValue()) {
|
||||
TableReportModule module = entry.getKey();
|
||||
tableProgress.put(module, panel.addReport(module.getName(), reportPath + module.getFilePath()));
|
||||
}
|
||||
}
|
||||
for (Entry<GeneralReportModule, Boolean> entry : generalModuleStates.entrySet()) {
|
||||
if (entry.getValue()) {
|
||||
GeneralReportModule module = entry.getKey();
|
||||
generalProgress.put(module, panel.addReport(module.getName(), reportPath + module.getFilePath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the progress panels to the user, and add actions to close the parent dialog.
|
||||
*/
|
||||
public void displayProgressPanels() {
|
||||
final JDialog dialog = new JDialog(new JFrame(), true);
|
||||
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
|
||||
dialog.setTitle("Report Generation Progress...");
|
||||
dialog.add(this.panel);
|
||||
dialog.pack();
|
||||
|
||||
panel.addCloseAction(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
dialog.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
dialog.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
panel.close();
|
||||
}
|
||||
});
|
||||
|
||||
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int w = dialog.getSize().width;
|
||||
int h = dialog.getSize().height;
|
||||
|
||||
// set the location of the popUp Window on the center of the screen
|
||||
dialog.setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the GeneralReportModule reports in a new SwingWorker.
|
||||
*/
|
||||
public void generateGeneralReports() {
|
||||
GeneralWorker worker = new GeneralWorker();
|
||||
worker.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the TableReportModule reports on Blackboard Artifacts in a new SwingWorker.
|
||||
*
|
||||
* @param artifactStates the enabled/disabled state of all artifacts
|
||||
*/
|
||||
public void generateTableArtifactReport(Map<ARTIFACT_TYPE, Boolean> artifactStates) {
|
||||
ArtifactWorker worker = new ArtifactWorker(artifactStates);
|
||||
worker.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the TableReportModule reports on Tags in a new SwingWorker.
|
||||
*
|
||||
* @param tagStates the enabled/disabled state of all tags
|
||||
*/
|
||||
public void generateTableTagReport(Map<String, Boolean> tagStates) {
|
||||
TagWorker worker = new TagWorker(tagStates);
|
||||
worker.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* SwingWorker to generate a report on all GeneralReportModules.
|
||||
*/
|
||||
private class GeneralWorker extends SwingWorker<Integer, Integer> {
|
||||
|
||||
@Override
|
||||
protected Integer doInBackground() throws Exception {
|
||||
for (Entry<GeneralReportModule, ReportProgressPanel> entry : generalProgress.entrySet()) {
|
||||
GeneralReportModule module = entry.getKey();
|
||||
if (generalProgress.get(module).getStatus() != ReportStatus.CANCELED) {
|
||||
module.generateReport(reportPath, generalProgress.get(module));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* SwingWorker to generate a report on Tags for all TableReportModules.
|
||||
*/
|
||||
private class TagWorker extends SwingWorker<Integer, Integer> {
|
||||
List<TableReportModule> tableModules;
|
||||
List<String> tags;
|
||||
|
||||
// Create a new TagWorker with the enabled/diabled state of each Tag
|
||||
TagWorker(Map<String, Boolean> tagStates) {
|
||||
tableModules = new ArrayList<TableReportModule>();
|
||||
for (Entry<TableReportModule, ReportProgressPanel> entry : tableProgress.entrySet()) {
|
||||
tableModules.add(entry.getKey());
|
||||
}
|
||||
tags = new ArrayList<String>();
|
||||
for (Entry<String, Boolean> entry : tagStates.entrySet()) {
|
||||
if (entry.getValue()) {
|
||||
tags.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer doInBackground() throws Exception {
|
||||
// For each module, start the report
|
||||
for (TableReportModule module : tableModules) {
|
||||
ReportProgressPanel progress = tableProgress.get(module);
|
||||
if (progress.getStatus() != ReportStatus.CANCELED) {
|
||||
module.startReport(reportPath);
|
||||
progress.start();
|
||||
progress.setIndeterminate(false);
|
||||
progress.setMaximumProgress(tags.size());
|
||||
}
|
||||
}
|
||||
// For every tag in tagStates
|
||||
for (String tag : tags) {
|
||||
// Check to see if all the TableReportModules have been canceled
|
||||
if (tableModules.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
Iterator<TableReportModule> iter = tableModules.iterator();
|
||||
while (iter.hasNext()) {
|
||||
TableReportModule module = iter.next();
|
||||
if (tableProgress.get(module).getStatus() == ReportStatus.CANCELED) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// Start a datatype for this tag
|
||||
for (TableReportModule module : tableModules) {
|
||||
tableProgress.get(module).updateStatusLabel("Now processing " + tag + "...");
|
||||
module.startDataType(tag);
|
||||
module.startTable(new ArrayList<String>(Arrays.asList(new String[] {"Comment", "File Name", "File Path"})));
|
||||
}
|
||||
|
||||
// For every artifact with this tag name, add a row
|
||||
for (BlackboardArtifact artifact : Tags.getTagsByName(tag)) {
|
||||
for (TableReportModule module : tableModules) {
|
||||
try {
|
||||
Map<Integer, String> attributes = getMappedAttributes(skCase.getBlackboardAttributes(artifact), module);
|
||||
List<String> row = new ArrayList<String>();
|
||||
row.add(attributes.get(ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID()));
|
||||
AbstractFile file = getAbstractFile(artifact.getObjectID());
|
||||
if(file != null) {
|
||||
row.add(file.getName());
|
||||
row.add(file.getUniquePath());
|
||||
} else {
|
||||
row.add("");
|
||||
row.add("");
|
||||
}
|
||||
module.addRow(row);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to get Tag information from Blackboard.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finish up this data type
|
||||
for (TableReportModule module : tableModules) {
|
||||
tableProgress.get(module).increment();
|
||||
module.endTable();
|
||||
module.endDataType();
|
||||
}
|
||||
}
|
||||
|
||||
// End the report
|
||||
for (TableReportModule module : tableModules) {
|
||||
tableProgress.get(module).complete();
|
||||
module.endReport();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SwingWorker to generate a report on Blackboard Artifacts for all TableReportModules.
|
||||
*/
|
||||
private class ArtifactWorker extends SwingWorker<Integer, Integer> {
|
||||
List<TableReportModule> tableModules;
|
||||
List<ARTIFACT_TYPE> artifactTypes;
|
||||
|
||||
// Create an ArtifactWorker with the enabled/disabled state of all Artifacts
|
||||
ArtifactWorker(Map<ARTIFACT_TYPE, Boolean> artifactStates) {
|
||||
tableModules = new ArrayList<TableReportModule>();
|
||||
for (Entry<TableReportModule, ReportProgressPanel> entry : tableProgress.entrySet()) {
|
||||
tableModules.add(entry.getKey());
|
||||
}
|
||||
artifactTypes = new ArrayList<ARTIFACT_TYPE>();
|
||||
for (Entry<ARTIFACT_TYPE, Boolean> entry : artifactStates.entrySet()) {
|
||||
if (entry.getValue()) {
|
||||
artifactTypes.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer doInBackground() throws Exception {
|
||||
// Start the report
|
||||
for (TableReportModule module : tableModules) {
|
||||
ReportProgressPanel progress = tableProgress.get(module);
|
||||
if (progress.getStatus() != ReportStatus.CANCELED) {
|
||||
module.startReport(reportPath);
|
||||
progress.start();
|
||||
progress.setIndeterminate(false);
|
||||
progress.setMaximumProgress(ARTIFACT_TYPE.values().length);
|
||||
}
|
||||
}
|
||||
|
||||
// For every enabled artifact type
|
||||
for (ARTIFACT_TYPE type : artifactTypes) {
|
||||
// Check to see if all the TableReportModules have been canceled
|
||||
if (tableModules.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
Iterator<TableReportModule> iter = tableModules.iterator();
|
||||
while (iter.hasNext()) {
|
||||
TableReportModule module = iter.next();
|
||||
if (tableProgress.get(module).getStatus() == ReportStatus.CANCELED) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// If the type is keyword hit or hashset hit, use the helper
|
||||
if (type.equals(ARTIFACT_TYPE.TSK_KEYWORD_HIT)) {
|
||||
writeKeywordHits(tableModules);
|
||||
continue;
|
||||
} else if (type.equals(ARTIFACT_TYPE.TSK_HASHSET_HIT)) {
|
||||
writeHashsetHits(tableModules);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise setup the unsorted list of artifacts, to later be sorted
|
||||
List<String> titles = getArtifactRowTitles(type.getTypeID());
|
||||
ArtifactComparator c = new ArtifactComparator();
|
||||
List<Entry<BlackboardArtifact, List<BlackboardAttribute>>> unsortedArtifacts = new ArrayList<Entry<BlackboardArtifact, List<BlackboardAttribute>>>();
|
||||
try {
|
||||
// For every artifact of the current type, add it and it's attributes to a list
|
||||
for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(type)) {
|
||||
try {
|
||||
unsortedArtifacts.add(new ArtifactEntry<BlackboardArtifact, List<BlackboardAttribute>>(artifact, skCase.getBlackboardAttributes(artifact)));
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to get Blackboard Attributes when generating report.", ex);
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to get Blackboard Artifacts when generating report.", ex);
|
||||
}
|
||||
// The most efficient way to sort all the Artifacts is to add them to a List, and then
|
||||
// sort that List based off a Comparator. Adding to a TreeMap/Set/List sorts the list
|
||||
// each time an element is added, which adds unnecessary overhead if we only need it sorted once.
|
||||
Collections.sort(unsortedArtifacts, c);
|
||||
|
||||
// For every module start a new data type based off this Artifact type
|
||||
for (TableReportModule module : tableModules) {
|
||||
tableProgress.get(module).updateStatusLabel("Now processing " + type.getDisplayName() + "...");
|
||||
module.startDataType(type.getDisplayName());
|
||||
module.startTable(titles);
|
||||
}
|
||||
|
||||
// Add a row for every artifact
|
||||
for (Entry<BlackboardArtifact, List<BlackboardAttribute>> artifactEntry : unsortedArtifacts) {
|
||||
for (TableReportModule module : tableModules) {
|
||||
try {
|
||||
module.addRow(getArtifactRow(artifactEntry, module));
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Failed get Blackboard Artifact information to fill row.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finish up this data type
|
||||
for (TableReportModule module : tableModules) {
|
||||
tableProgress.get(module).increment();
|
||||
module.endTable();
|
||||
module.endDataType();
|
||||
}
|
||||
}
|
||||
|
||||
// End the report
|
||||
for (TableReportModule module : tableModules) {
|
||||
tableProgress.get(module).complete();
|
||||
module.endReport();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the keyword hits to the provided TableReportModules.
|
||||
* @param tableModules modules to report on
|
||||
*/
|
||||
private void writeKeywordHits(List<TableReportModule> tableModules) {
|
||||
ResultSet listsRs = null;
|
||||
try {
|
||||
// Query for keyword lists
|
||||
listsRs = skCase.runQuery("SELECT att.value_text AS list " +
|
||||
"FROM blackboard_attributes AS att, blackboard_artifacts AS art " +
|
||||
"WHERE att.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + " " +
|
||||
"AND art.artifact_type_id = " + ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + " " +
|
||||
"AND att.artifact_id = art.artifact_id " +
|
||||
"GROUP BY list");
|
||||
List<String> lists = new ArrayList<String>();
|
||||
while(listsRs.next()) {
|
||||
String list = listsRs.getString("list");
|
||||
if(list.isEmpty()) {
|
||||
list = "User Searches";
|
||||
}
|
||||
lists.add(list);
|
||||
}
|
||||
|
||||
// Make keyword data type and give them set index
|
||||
for (TableReportModule module : tableModules) {
|
||||
module.startDataType(ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName());
|
||||
module.addSetIndex(lists);
|
||||
tableProgress.get(module).updateStatusLabel("Now processing "
|
||||
+ ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName() + "...");
|
||||
}
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to query keyword lists.", ex);
|
||||
} finally {
|
||||
if (listsRs != null) {
|
||||
try {
|
||||
skCase.closeRunQuery(listsRs);
|
||||
} catch (SQLException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
// Query for keywords
|
||||
rs = skCase.runQuery("SELECT art.obj_id, att1.value_text AS keyword, att2.value_text AS preview, att3.value_text AS list, f.name AS name " +
|
||||
"FROM blackboard_artifacts AS art, blackboard_attributes AS att1, blackboard_attributes AS att2, blackboard_attributes AS att3, tsk_files AS f " +
|
||||
"WHERE (att1.artifact_id = art.artifact_id) " +
|
||||
"AND (att2.artifact_id = art.artifact_id) " +
|
||||
"AND (att3.artifact_id = art.artifact_id) " +
|
||||
"AND (f.obj_id = art.obj_id) " +
|
||||
"AND (att1.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID() + ") " +
|
||||
"AND (att2.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID() + ") " +
|
||||
"AND (att3.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + ") " +
|
||||
"AND (art.artifact_type_id = " + ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + ") " +
|
||||
"ORDER BY list, keyword, name");
|
||||
String currentKeyword = "";
|
||||
String currentList = "";
|
||||
while (rs.next()) {
|
||||
// Check to see if all the TableReportModules have been canceled
|
||||
if (tableModules.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
Iterator<TableReportModule> iter = tableModules.iterator();
|
||||
while (iter.hasNext()) {
|
||||
TableReportModule module = iter.next();
|
||||
if (tableProgress.get(module).getStatus() == ReportStatus.CANCELED) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
Long objId = rs.getLong("obj_id");
|
||||
String keyword = rs.getString("keyword");
|
||||
String preview = rs.getString("preview");
|
||||
String list = rs.getString("list");
|
||||
String name = rs.getString("name");
|
||||
String uniquePath = "";
|
||||
|
||||
try {
|
||||
uniquePath = skCase.getAbstractFileById(objId).getUniquePath();
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Failed to get Abstract File by ID.", ex);
|
||||
}
|
||||
|
||||
// If the lists aren't the same, we've started a new list
|
||||
if((!list.equals(currentList) && !list.isEmpty()) || (list.isEmpty() && !currentList.equals("User Searches"))) {
|
||||
if(!currentList.isEmpty()) {
|
||||
for (TableReportModule module : tableModules) {
|
||||
module.endTable();
|
||||
module.endSet();
|
||||
}
|
||||
}
|
||||
currentList = list.isEmpty() ? "User Searches" : list;
|
||||
currentKeyword = ""; // reset the current keyword because it's a new list
|
||||
for (TableReportModule module : tableModules) {
|
||||
module.startSet(currentList);
|
||||
tableProgress.get(module).updateStatusLabel("Now processing "
|
||||
+ ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName()
|
||||
+ " (" + currentList + ")...");
|
||||
}
|
||||
}
|
||||
if (!keyword.equals(currentKeyword)) {
|
||||
if(!currentKeyword.equals("")) {
|
||||
for (TableReportModule module : tableModules) {
|
||||
module.endTable();
|
||||
}
|
||||
}
|
||||
currentKeyword = keyword;
|
||||
for (TableReportModule module : tableModules) {
|
||||
module.addSetElement(currentKeyword);
|
||||
module.startTable(getArtifactRowTitles(ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()));
|
||||
}
|
||||
}
|
||||
String previewreplace = EscapeUtil.escapeHtml(preview);
|
||||
for (TableReportModule module : tableModules) {
|
||||
module.addRow(Arrays.asList(new String[] {name, previewreplace.replaceAll("<!", ""), uniquePath}));
|
||||
}
|
||||
}
|
||||
|
||||
// Finish the current data type
|
||||
for (TableReportModule module : tableModules) {
|
||||
tableProgress.get(module).increment();
|
||||
module.endDataType();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to query keywords.", ex);
|
||||
} finally {
|
||||
if (rs != null) {
|
||||
try {
|
||||
skCase.closeRunQuery(rs);
|
||||
} catch (SQLException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the hashset hits to the provided TableReportModules.
|
||||
* @param tableModules modules to report on
|
||||
*/
|
||||
private void writeHashsetHits(List<TableReportModule> tableModules) {
|
||||
ResultSet listsRs = null;
|
||||
try {
|
||||
// Query for hashsets
|
||||
listsRs = skCase.runQuery("SELECT att.value_text AS list " +
|
||||
"FROM blackboard_attributes AS att, blackboard_artifacts AS art " +
|
||||
"WHERE att.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + " " +
|
||||
"AND art.artifact_type_id = " + ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() + " " +
|
||||
"AND att.artifact_id = art.artifact_id " +
|
||||
"GROUP BY list");
|
||||
List<String> lists = new ArrayList<String>();
|
||||
while(listsRs.next()) {
|
||||
lists.add(listsRs.getString("list"));
|
||||
}
|
||||
|
||||
// Make hashset data type and give them set index
|
||||
for (TableReportModule module : tableModules) {
|
||||
module.startDataType(ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName());
|
||||
module.addSetIndex(lists);
|
||||
tableProgress.get(module).updateStatusLabel("Now processing "
|
||||
+ ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName() + "...");
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to query hashset lists.", ex);
|
||||
} finally {
|
||||
if (listsRs != null) {
|
||||
try {
|
||||
skCase.closeRunQuery(listsRs);
|
||||
} catch (SQLException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
// Query for hashset hits
|
||||
rs = skCase.runQuery("SELECT art.obj_id, att.value_text AS setname, f.name AS name, f.size AS size " +
|
||||
"FROM blackboard_artifacts AS art, blackboard_attributes AS att, tsk_files AS f " +
|
||||
"WHERE (att.artifact_id = art.artifact_id) " +
|
||||
"AND (f.obj_id = art.obj_id) " +
|
||||
"AND (att.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + ") " +
|
||||
"AND (art.artifact_type_id = " + ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() + ") " +
|
||||
"ORDER BY setname, name, size");
|
||||
String currentSet = "";
|
||||
while (rs.next()) {
|
||||
// Check to see if all the TableReportModules have been canceled
|
||||
if (tableModules.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
Iterator<TableReportModule> iter = tableModules.iterator();
|
||||
while (iter.hasNext()) {
|
||||
TableReportModule module = iter.next();
|
||||
if (tableProgress.get(module).getStatus() == ReportStatus.CANCELED) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
Long objId = rs.getLong("obj_id");
|
||||
String set = rs.getString("setname");
|
||||
String name = rs.getString("name");
|
||||
String size = rs.getString("size");
|
||||
String uniquePath = "";
|
||||
|
||||
try {
|
||||
uniquePath = skCase.getAbstractFileById(objId).getUniquePath();
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Failed to get Abstract File from ID.", ex);
|
||||
}
|
||||
|
||||
// If the sets aren't the same, we've started a new set
|
||||
if(!set.equals(currentSet)) {
|
||||
if(!currentSet.isEmpty()) {
|
||||
for (TableReportModule module : tableModules) {
|
||||
module.endTable();
|
||||
module.endSet();
|
||||
}
|
||||
}
|
||||
currentSet = set;
|
||||
for (TableReportModule module : tableModules) {
|
||||
module.startSet(currentSet);
|
||||
module.startTable(getArtifactRowTitles(ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()));
|
||||
tableProgress.get(module).updateStatusLabel("Now processing "
|
||||
+ ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName()
|
||||
+ " (" + currentSet + ")...");
|
||||
}
|
||||
}
|
||||
|
||||
// Add a row for this hit to every module
|
||||
for (TableReportModule module : tableModules) {
|
||||
module.addRow(Arrays.asList(new String[] {name, size, uniquePath}));
|
||||
}
|
||||
}
|
||||
|
||||
// Finish the current data type
|
||||
for (TableReportModule module : tableModules) {
|
||||
tableProgress.get(module).increment();
|
||||
module.endDataType();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to query hashsets hits.", ex);
|
||||
} finally {
|
||||
if (rs != null) {
|
||||
try {
|
||||
skCase.closeRunQuery(rs);
|
||||
} catch (SQLException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given artifact type ID, return the list of the row titles we're reporting on.
|
||||
*
|
||||
* @param artifactTypeId artifact type ID
|
||||
* @return List<String> row titles
|
||||
*/
|
||||
private List<String> getArtifactRowTitles(int artifactTypeId) {
|
||||
switch (artifactTypeId) {
|
||||
case 2: // TSK_WEB_BOOKMARK
|
||||
return new ArrayList<String>(Arrays.asList(new String[] {"URL", "Title", "Date Accessed", "Program", "Source File"}));
|
||||
case 3: // TSK_WEB_COOKIE
|
||||
return new ArrayList<String>(Arrays.asList(new String[] {"URL", "Date/Time", "Name", "Value", "Program", "Source File"}));
|
||||
case 4: // TSK_WEB_HISTORY
|
||||
return new ArrayList<String>(Arrays.asList(new String[] {"URL", "Date Accessed", "Referrer", "Name", "Program", "Source File"}));
|
||||
case 5: // TSK_WEB_DOWNLOAD
|
||||
return new ArrayList<String>(Arrays.asList(new String[] {"Destination", "Source URL", "Date Accessed", "Program", "Source File"}));
|
||||
case 6: // TSK_RECENT_OBJECT
|
||||
return new ArrayList<String>(Arrays.asList(new String[] {"Path", "Source File"}));
|
||||
case 8: // TSK_INSTALLED_PROG
|
||||
return new ArrayList<String>(Arrays.asList(new String[] {"Program Name", "Install Date/Time", "Source File"}));
|
||||
case 9: // TSK_KEYWORD_HIT
|
||||
return new ArrayList<String>(Arrays.asList(new String[] {"File Name", "Preview", "File Path"}));
|
||||
case 10: // TSK_HASHSET_HIT
|
||||
return new ArrayList<String>(Arrays.asList(new String[] {"File Name", "Size", "File Path"}));
|
||||
case 11: // TSK_DEVICE_ATTACHED
|
||||
return new ArrayList<String>(Arrays.asList(new String[] {"Name", "Device ID", "Date/Time", "Source File"}));
|
||||
case 15: // TSK_WEB_SEARCH_QUERY
|
||||
return new ArrayList<String>(Arrays.asList(new String[] {"Text", "Domain", "Date Accessed", "Program Name", "Source File"}));
|
||||
case 16: // TSK_METADATA_EXIF
|
||||
return new ArrayList<String>(Arrays.asList(new String[] {"File Name", "Date Taken", "Device Manufacturer", "Device Model", "Latitude", "Longitude", "Source File"}));
|
||||
case 17: // TSK_TAG_FILE
|
||||
return new ArrayList<String>(Arrays.asList(new String[] {"Comment", "File Name", "Source File"}));
|
||||
case 18: // TSK_TAG_ARTIFACT
|
||||
return new ArrayList<String>(Arrays.asList(new String[] {"Comment", "File Name", "Source File"}));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map all BlackboardAttributes' values in a list of BlackboardAttributes to each attribute's attribute
|
||||
* type ID, using module's dateToString method for date/time conversions if a module is supplied.
|
||||
*
|
||||
* @param attList list of BlackboardAttributes to be mapped
|
||||
* @param module the TableReportModule the mapping is for
|
||||
* @return Map<Integer, String> of the BlackboardAttributes mapped to their attribute type ID
|
||||
*/
|
||||
public Map<Integer, String> getMappedAttributes(List<BlackboardAttribute> attList, TableReportModule... module) {
|
||||
Map<Integer, String> attributes = new HashMap<Integer, String>();
|
||||
int size = ATTRIBUTE_TYPE.values().length;
|
||||
for (int n = 0; n <= size; n++) {
|
||||
attributes.put(n, "");
|
||||
}
|
||||
for (BlackboardAttribute tempatt : attList) {
|
||||
String value = "";
|
||||
Integer type = tempatt.getAttributeTypeID();
|
||||
if (type.equals(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()) || type.equals(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID())) {
|
||||
if (module.length > 0) {
|
||||
value = module[0].dateToString(tempatt.getValueLong());
|
||||
} else {
|
||||
SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
||||
value = sdf.format(new java.util.Date((tempatt.getValueLong() * 1000)));
|
||||
}
|
||||
} else if(type.equals(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()) ||
|
||||
type.equals(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()) ||
|
||||
type.equals(ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE.getTypeID())) {
|
||||
value = Double.toString(tempatt.getValueDouble());
|
||||
} else {
|
||||
value = tempatt.getValueString();
|
||||
}
|
||||
if (value == null) {
|
||||
value = "";
|
||||
}
|
||||
value = EscapeUtil.escapeHtml(value);
|
||||
attributes.put(type, value);
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of Strings with all the row values for a given BlackboardArtifact and
|
||||
* list of BlackboardAttributes Entry, basing the date/time field on the given TableReportModule.
|
||||
*
|
||||
* @param entry BlackboardArtifact and list of BlackboardAttributes
|
||||
* @param module TableReportModule for which the row is desired
|
||||
* @return List<String> row values
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
private List<String> getArtifactRow(Entry<BlackboardArtifact, List<BlackboardAttribute>> entry, TableReportModule module) throws TskCoreException {
|
||||
Map<Integer, String> attributes = getMappedAttributes(entry.getValue(), module);
|
||||
switch (entry.getKey().getArtifactTypeID()) {
|
||||
case 2: // TSK_WEB_BOOKMARK
|
||||
List<String> bookmark = new ArrayList<String>();
|
||||
bookmark.add(attributes.get(ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
|
||||
bookmark.add(attributes.get(ATTRIBUTE_TYPE.TSK_TITLE.getTypeID()));
|
||||
bookmark.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
|
||||
bookmark.add(attributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
|
||||
bookmark.add(getFileUniquePath(entry.getKey().getObjectID()));
|
||||
return bookmark;
|
||||
case 3: // TSK_WEB_COOKIE
|
||||
List<String> cookie = new ArrayList<String>();
|
||||
cookie.add(attributes.get(ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
|
||||
cookie.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
|
||||
cookie.add(attributes.get(ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
|
||||
cookie.add(attributes.get(ATTRIBUTE_TYPE.TSK_VALUE.getTypeID()));
|
||||
cookie.add(attributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
|
||||
cookie.add(getFileUniquePath(entry.getKey().getObjectID()));
|
||||
return cookie;
|
||||
case 4: // TSK_WEB_HISTORY
|
||||
List<String> history = new ArrayList<String>();
|
||||
history.add(attributes.get(ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
|
||||
history.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
|
||||
history.add(attributes.get(ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID()));
|
||||
history.add(attributes.get(ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
|
||||
history.add(attributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
|
||||
history.add(getFileUniquePath(entry.getKey().getObjectID()));
|
||||
return history;
|
||||
case 5: // TSK_WEB_DOWNLOAD
|
||||
List<String> download = new ArrayList<String>();
|
||||
download.add(attributes.get(ATTRIBUTE_TYPE.TSK_PATH.getTypeID()));
|
||||
download.add(attributes.get(ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
|
||||
download.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
|
||||
download.add(attributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
|
||||
download.add(getFileUniquePath(entry.getKey().getObjectID()));
|
||||
return download;
|
||||
case 6: // TSK_RECENT_OBJECT
|
||||
List<String> recent = new ArrayList<String>();
|
||||
recent.add(attributes.get(ATTRIBUTE_TYPE.TSK_PATH.getTypeID()));
|
||||
recent.add(getFileUniquePath(entry.getKey().getObjectID()));
|
||||
return recent;
|
||||
case 8: // TSK_INSTALLED_PROG
|
||||
List<String> installed = new ArrayList<String>();
|
||||
installed.add(attributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
|
||||
installed.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
|
||||
installed.add(getFileUniquePath(entry.getKey().getObjectID()));
|
||||
return installed;
|
||||
case 11: // TSK_DEVICE_ATTACHED
|
||||
List<String> devices = new ArrayList<String>();
|
||||
devices.add(attributes.get(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID()));
|
||||
devices.add(attributes.get(ATTRIBUTE_TYPE.TSK_DEVICE_ID.getTypeID()));
|
||||
devices.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
|
||||
devices.add(getFileUniquePath(entry.getKey().getObjectID()));
|
||||
return devices;
|
||||
case 15: // TSK_WEB_SEARCH_QUERY
|
||||
List<String> search = new ArrayList<String>();
|
||||
search.add(attributes.get(ATTRIBUTE_TYPE.TSK_TEXT.getTypeID()));
|
||||
search.add(attributes.get(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID()));
|
||||
search.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
|
||||
search.add(attributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
|
||||
search.add(getFileUniquePath(entry.getKey().getObjectID()));
|
||||
return search;
|
||||
case 16: // TSK_METADATA_EXIF
|
||||
List<String> exif = new ArrayList<String>();
|
||||
exif.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
|
||||
exif.add(attributes.get(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE.getTypeID()));
|
||||
exif.add(attributes.get(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID()));
|
||||
exif.add(attributes.get(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()));
|
||||
exif.add(attributes.get(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()));
|
||||
exif.add(getFileUniquePath(entry.getKey().getObjectID()));
|
||||
return exif;
|
||||
case 17: // TSK_TAG_FILE
|
||||
List<String> tagFile = new ArrayList<String>();
|
||||
tagFile.add(attributes.get(ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID()));
|
||||
AbstractFile tFile = getAbstractFile(entry.getKey().getObjectID());
|
||||
if(tFile != null) {
|
||||
tagFile.add(tFile.getName());
|
||||
tagFile.add(tFile.getUniquePath());
|
||||
} else {
|
||||
tagFile.add("");
|
||||
tagFile.add("");
|
||||
}
|
||||
return tagFile;
|
||||
case 18: // TSK_TAG_ARTIFACT
|
||||
List<String> tagArtifact = new ArrayList<String>();
|
||||
tagArtifact.add(attributes.get(ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID()));
|
||||
AbstractFile aFile = getAbstractFile(entry.getKey().getObjectID());
|
||||
if(aFile != null) {
|
||||
tagArtifact.add(aFile.getName());
|
||||
tagArtifact.add(aFile.getUniquePath());
|
||||
} else {
|
||||
tagArtifact.add("");
|
||||
tagArtifact.add("");
|
||||
}
|
||||
return tagArtifact;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a tsk_file's obj_id, return the unique path of that file.
|
||||
*
|
||||
* @param objId tsk_file obj_id
|
||||
* @return String unique path
|
||||
*/
|
||||
private String getFileUniquePath(long objId) {
|
||||
try {
|
||||
return skCase.getAbstractFileById(objId).getUniquePath();
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Failed to get Abstract File by ID.", ex);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a tsk_file's obj_id, return the name of that file.
|
||||
*
|
||||
* @param objId tsk_file obj_id
|
||||
* @return String name
|
||||
*/
|
||||
private String getFileName(long objId) {
|
||||
try {
|
||||
return skCase.getAbstractFileById(objId).getName();
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Failed to get Abstract File by ID.", ex);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
/**
|
||||
* Return the file associated with a tsk_file obj_id.
|
||||
*
|
||||
* @param objId tsk_file obj_id
|
||||
* @return AbstractFile associated with objId
|
||||
*/
|
||||
private AbstractFile getAbstractFile(long objId) {
|
||||
try {
|
||||
return skCase.getAbstractFileById(objId);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Failed to get Abstract File by ID.", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map.Entry for BlackboardArtifacts and lists of BlackboardAttributes.
|
||||
*
|
||||
* @param <K> BlackboardArtifact
|
||||
* @param <V> List<BlackboardAttribute>
|
||||
*/
|
||||
private class ArtifactEntry<K, V> implements Map.Entry<BlackboardArtifact, List<BlackboardAttribute>> {
|
||||
BlackboardArtifact artifact;
|
||||
List<BlackboardAttribute> attributes;
|
||||
|
||||
private ArtifactEntry(BlackboardArtifact artifact, List<BlackboardAttribute> attributes) {
|
||||
this.artifact = artifact;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlackboardArtifact getKey() {
|
||||
return artifact;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlackboardAttribute> getValue() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlackboardAttribute> setValue(List<BlackboardAttribute> value) {
|
||||
List<BlackboardAttribute> old = attributes;
|
||||
attributes = value;
|
||||
return old;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares entries of BlackboardArtifacts and lists of BlackboardAttributes, sorting by
|
||||
* the first attribute both artifacts have in common. If all attributes are the same, they are
|
||||
* assumed duplicates, and they are sorted on artifact ID. Should only be used on artifacts
|
||||
* of similar types.
|
||||
*/
|
||||
private class ArtifactComparator implements Comparator<Entry<BlackboardArtifact, List<BlackboardAttribute>>> {
|
||||
@Override
|
||||
public int compare(Entry<BlackboardArtifact, List<BlackboardAttribute>> art1, Entry<BlackboardArtifact, List<BlackboardAttribute>> art2) {
|
||||
// Get all the attributes for each artifact
|
||||
int size = ATTRIBUTE_TYPE.values().length;
|
||||
Map<Integer, String> att1 = getMappedAttributes(art1.getValue());
|
||||
Map<Integer, String> att2 = getMappedAttributes(art2.getValue());
|
||||
// Compare the attributes one-by-one looking for differences
|
||||
for(int i=0; i < size; i++) {
|
||||
String a1 = att1.get(i);
|
||||
String a2 = att2.get(i);
|
||||
if((!a1.equals("") && !a2.equals("")) && a1.compareTo(a2) != 0) {
|
||||
return a1.compareTo(a2);
|
||||
}
|
||||
}
|
||||
// If all attributes are the same, they're most likely duplicates so sort by artifact ID
|
||||
return ((Long)art1.getKey().getArtifactID()).compareTo((Long)art2.getKey().getArtifactID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,39 +23,11 @@
|
||||
package org.sleuthkit.autopsy.report;
|
||||
|
||||
/**
|
||||
* interface every reporting module should implement
|
||||
* Interface extended by TableReportModule and GeneralReportModule.
|
||||
* Contains vital report information to be used by every report.
|
||||
*/
|
||||
public interface ReportModule {
|
||||
|
||||
/**
|
||||
* Generates a report on the current case Reporting module should traverse
|
||||
* the blackboard, extract needed information as specified in the config and
|
||||
* generate a report file
|
||||
*
|
||||
* @param config specifying parts that should be generated
|
||||
* @return absolute file path to the report generated
|
||||
* @throws ReportModuleException thrown when report generation failed
|
||||
*/
|
||||
public String generateReport(ReportConfiguration config) throws ReportModuleException;
|
||||
|
||||
/**
|
||||
* This saves a copy of the report (current one) to another place specified
|
||||
* by the user. Takes the input of where the path needs to be saved, include
|
||||
* filename and extention.
|
||||
*
|
||||
* @param path file path where to save a copy of the report
|
||||
* @throws ReportModuleException thrown if report saving failed
|
||||
*/
|
||||
public void save(String path) throws ReportModuleException;
|
||||
|
||||
/**
|
||||
* Returns a short description of report type/file format this module
|
||||
* generates for instance, "XML", "Excel"
|
||||
*
|
||||
* @return the report type short description
|
||||
*/
|
||||
public String getReportType();
|
||||
|
||||
/**
|
||||
* Returns a basic string name for the report. What is 'officially' titled.
|
||||
*
|
||||
@@ -63,28 +35,12 @@ public interface ReportModule {
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* Returns the report configuration object that was created
|
||||
*
|
||||
* @return the report configuration for this report
|
||||
*/
|
||||
public ReportConfiguration GetReportConfiguration();
|
||||
|
||||
/**
|
||||
* Returns a one line user friendly description of the type of report this
|
||||
* module generates
|
||||
* @return user-friendly report description
|
||||
*/
|
||||
public String getReportTypeDescription();
|
||||
|
||||
/**
|
||||
* Calls to the report module to execute a method to display the report that
|
||||
* was generated.
|
||||
*
|
||||
* @param path the path to the file
|
||||
*
|
||||
*/
|
||||
public void getPreview(String path);
|
||||
public String getDescription();
|
||||
|
||||
/**
|
||||
* Calls to the report module to execute a method to get the extension that
|
||||
@@ -94,4 +50,11 @@ public interface ReportModule {
|
||||
*
|
||||
*/
|
||||
public String getExtension();
|
||||
|
||||
/**
|
||||
* Returns the path to the main (or only) file for the report.
|
||||
*
|
||||
* @return String path to the report file
|
||||
*/
|
||||
public String getFilePath();
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 Basis Technology Corp.
|
||||
*
|
||||
* Copyright 2012 42six Solutions.
|
||||
* Contact: aebadirad <at> 42six <dot> com
|
||||
* Project Contact/Architect: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.report;
|
||||
|
||||
//exception thrown by a reporting module when report generation failed
|
||||
class ReportModuleException extends Exception {
|
||||
|
||||
public ReportModuleException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public ReportModuleException(String msg, Exception ex) {
|
||||
super(msg, ex);
|
||||
}
|
||||
}
|
||||
@@ -1,282 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 Basis Technology Corp.
|
||||
*
|
||||
* Copyright 2012 42six Solutions.
|
||||
* Contact: aebadirad <at> 42six <dot> com
|
||||
* Project Contact/Architect: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.report;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
public class ReportPanel extends javax.swing.JPanel {
|
||||
|
||||
private ReportPanelAction rpa;
|
||||
private static final Logger logger = Logger.getLogger(ReportPanel.class.getName());
|
||||
|
||||
/**
|
||||
* Creates new form ReportPanel
|
||||
*/
|
||||
public ReportPanel(ReportPanelAction reportPanelAction) {
|
||||
initComponents();
|
||||
rpa = reportPanelAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
reportScrollPane = new javax.swing.JScrollPane();
|
||||
reportSummaryPanel = new javax.swing.JPanel();
|
||||
closeButton = new javax.swing.JButton();
|
||||
exportButton = new javax.swing.JButton();
|
||||
statusLabel = new javax.swing.JLabel();
|
||||
LABEL_LOC = new javax.swing.JLabel();
|
||||
ButtonOpenFolder = new javax.swing.JButton();
|
||||
|
||||
reportScrollPane.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ReportPanel.class, "ReportPanel.reportScrollPane.border.title"))); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout reportSummaryPanelLayout = new javax.swing.GroupLayout(reportSummaryPanel);
|
||||
reportSummaryPanel.setLayout(reportSummaryPanelLayout);
|
||||
reportSummaryPanelLayout.setHorizontalGroup(
|
||||
reportSummaryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 675, Short.MAX_VALUE)
|
||||
);
|
||||
reportSummaryPanelLayout.setVerticalGroup(
|
||||
reportSummaryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 214, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
reportScrollPane.setViewportView(reportSummaryPanel);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(closeButton, org.openide.util.NbBundle.getMessage(ReportPanel.class, "ReportPanel.closeButton.text_1")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(exportButton, org.openide.util.NbBundle.getMessage(ReportPanel.class, "ReportPanel.exportButton.text")); // NOI18N
|
||||
exportButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
exportButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(statusLabel, org.openide.util.NbBundle.getMessage(ReportPanel.class, "ReportPanel.statusLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(LABEL_LOC, org.openide.util.NbBundle.getMessage(ReportPanel.class, "ReportPanel.LABEL_LOC.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(ButtonOpenFolder, org.openide.util.NbBundle.getMessage(ReportPanel.class, "ReportPanel.ButtonOpenFolder.text_1")); // NOI18N
|
||||
ButtonOpenFolder.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
ButtonOpenFolderActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
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(reportScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 404, Short.MAX_VALUE)
|
||||
.addComponent(statusLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(LABEL_LOC)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(exportButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(ButtonOpenFolder)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(closeButton)))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(reportScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(statusLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(LABEL_LOC)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(closeButton)
|
||||
.addComponent(exportButton)
|
||||
.addComponent(ButtonOpenFolder))
|
||||
.addGap(8, 8, 8))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void exportButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportButtonActionPerformed
|
||||
HashMap<ReportModule, String> reports = rpa.getReports();
|
||||
exportReportAction(reports);
|
||||
}//GEN-LAST:event_exportButtonActionPerformed
|
||||
|
||||
private void ButtonOpenFolderActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonOpenFolderActionPerformed
|
||||
String path = Case.getCurrentCase().getCaseDirectory() + File.separator + "Reports";
|
||||
File dir = new File(path);
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
try {
|
||||
Desktop.getDesktop().open(dir);
|
||||
} catch (IOException ioe) {
|
||||
logger.log(Level.WARNING, "Could not open folder [" + path + "]", ioe);
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_ButtonOpenFolderActionPerformed
|
||||
|
||||
public void setCloseButtonActionListener(ActionListener e) {
|
||||
closeButton.addActionListener(e);
|
||||
}
|
||||
|
||||
public void setFinishedReportText() {
|
||||
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
||||
String reportText = "These reports were generated on " + dateFormat.format(new Date()) + ".";
|
||||
String loc = "Reports extracted to: " + Case.getCurrentCase().getCaseDirectory() + File.separator + "Reports";
|
||||
statusLabel.setText(reportText);
|
||||
LABEL_LOC.setText(loc);
|
||||
|
||||
final JPanel tempPanel = new JPanel(new GridBagLayout());
|
||||
//tempPanel.setMinimumSize(new Dimension(540,240));
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
HashMap<ReportModule, String> reports = rpa.getReports();
|
||||
int cc = 0;
|
||||
for (Map.Entry<ReportModule, String> entry : reports.entrySet()) {
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
c.weightx = 1;
|
||||
c.gridwidth = 1;
|
||||
c.gridx = 0;
|
||||
c.gridy = cc;
|
||||
c.insets = new Insets(0, 0, 0, 0); // remove padding
|
||||
String info = entry.getKey().getName() + " report";
|
||||
JLabel infoLabel = new JLabel(info);
|
||||
tempPanel.add(infoLabel, c);
|
||||
|
||||
c.fill = GridBagConstraints.BASELINE_TRAILING;
|
||||
c.weightx = 0.0;
|
||||
c.gridwidth = 1;
|
||||
c.gridheight = 1;
|
||||
c.gridx = 1;
|
||||
c.gridy = cc;
|
||||
JButton viewButton = new JButton("View Report");
|
||||
final ReportModule rep = entry.getKey();
|
||||
final String path = entry.getValue();
|
||||
viewButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
rep.getPreview(path);
|
||||
}
|
||||
});
|
||||
tempPanel.add(viewButton, c);
|
||||
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
c.weightx = 1;
|
||||
c.gridwidth = 3;
|
||||
c.gridheight = 1;
|
||||
c.gridx = 0;
|
||||
c.gridy = ++cc;
|
||||
c.insets = new Insets(0, 0, 15, 0); // row padding
|
||||
tempPanel.revalidate();
|
||||
tempPanel.repaint();
|
||||
cc++;
|
||||
}
|
||||
}
|
||||
});
|
||||
reportSummaryPanel.setLayout(new GridLayout(0, 1));
|
||||
reportSummaryPanel.add(tempPanel, 0);
|
||||
//reportScrollPane.revalidate();
|
||||
//reportScrollPane.repaint();
|
||||
|
||||
}
|
||||
|
||||
private void exportReportAction(HashMap<ReportModule, String> reports) {
|
||||
JFileChooser exportChooser = new JFileChooser();
|
||||
int option = exportChooser.showSaveDialog(this);
|
||||
if (option == JFileChooser.APPROVE_OPTION) {
|
||||
if (exportChooser.getSelectedFile() != null) {
|
||||
File file = exportChooser.getSelectedFile();
|
||||
String path = file.getParent();
|
||||
String name = file.getName();
|
||||
for (Map.Entry<ReportModule, String> entry : reports.entrySet()) {
|
||||
exportReport(path, name, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void exportReport(String path, String name, Map.Entry<ReportModule, String> entry) {
|
||||
ReportModule report = entry.getKey();
|
||||
String ext = report.getExtension();
|
||||
String original = entry.getValue();
|
||||
try {
|
||||
if(report.getName().equals("HTML")) {
|
||||
String newpath = FileUtil.copyFolder(original.substring(0, original.lastIndexOf("\\")), path, name);
|
||||
JOptionPane.showMessageDialog(this, "\n" + report.getName() + " report has been successfully saved to: \n" + newpath);
|
||||
} else {
|
||||
String newpath = FileUtil.copyFile(original, path, name + "-" + report.getName(), ext, true);
|
||||
JOptionPane.showMessageDialog(this, "\n" + report.getName() + " report has been successfully saved to: \n" + newpath);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
JOptionPane.showMessageDialog(this, "\n" + report.getName() + " report has failed to save! \n Reason: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton ButtonOpenFolder;
|
||||
private javax.swing.JLabel LABEL_LOC;
|
||||
private javax.swing.JButton closeButton;
|
||||
private javax.swing.JButton exportButton;
|
||||
private javax.swing.JScrollPane reportScrollPane;
|
||||
private javax.swing.JPanel reportSummaryPanel;
|
||||
private javax.swing.JLabel statusLabel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 Basis Technology Corp.
|
||||
*
|
||||
* Copyright 2012 42six Solutions.
|
||||
* Contact: aebadirad <at> 42six <dot> com
|
||||
* Project Contact/Architect: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.report;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
|
||||
public class ReportPanelAction {
|
||||
|
||||
private static final String ACTION_NAME = "Report Preview";
|
||||
private StringBuilder viewReport = new StringBuilder();
|
||||
private int cc = 1;
|
||||
private HashMap<ReportModule,String> reports = new HashMap<ReportModule,String>();
|
||||
public ReportPanelAction() {
|
||||
}
|
||||
|
||||
public void reportGenerate(final ReportConfiguration reportconfig, final ArrayList<String> classList, final ArrayList<String> preview, final ReportFilter rr) {
|
||||
try {
|
||||
//Clear any old reports in the string
|
||||
viewReport.setLength(0);
|
||||
|
||||
|
||||
// Generate the reports and create the hashmap
|
||||
final ReportGen report = new ReportGen();
|
||||
//see what reports we need to run and run them
|
||||
//Set progress bar to move while doing this
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
rr.progBarStartText();
|
||||
}
|
||||
});
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
rr.progBarCount(((classList.size())*2)+1);
|
||||
}
|
||||
});
|
||||
// Advance the bar a bit so the user knows something is happening
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
rr.progBarSet(1);
|
||||
}
|
||||
});
|
||||
//Turn our results into the appropriate xml/html reports
|
||||
//TODO: add a way for users to select what they will run when
|
||||
Thread reportThread = new Thread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
reports.clear();
|
||||
for (String s : classList) {
|
||||
try {
|
||||
rr.progBarSet(cc);
|
||||
final Class reportclass = Class.forName(s);
|
||||
rr.setUpdateLabel("Running " + reportclass.getSimpleName() + " report...");
|
||||
Object reportObject = reportclass.newInstance();
|
||||
Class[] argTypes = new Class[]{ReportConfiguration.class};
|
||||
Method generatereport = reportclass.getDeclaredMethod("generateReport", argTypes);
|
||||
Object invoke = generatereport.invoke(reportObject, reportconfig);
|
||||
rr.progBarSet(cc);
|
||||
String path = invoke.toString();
|
||||
reports.put((ReportModule) reportObject, path);
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(ReportFilterAction.class.getName()).log(Level.WARNING, "Error generating " + s + "! Reason: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// start our threads
|
||||
reportThread.start();
|
||||
|
||||
// display the window
|
||||
|
||||
// create the popUp window for it
|
||||
if (ReportFilter.cancel == false) {
|
||||
|
||||
final JFrame frame = new JFrame(ACTION_NAME);
|
||||
final JDialog popUpWindow = new JDialog(frame, ACTION_NAME, true); // to make the popUp Window to be modal
|
||||
|
||||
|
||||
// initialize panel with loaded settings
|
||||
|
||||
//Set the temporary label to let the user know its done and is waiting on the report
|
||||
|
||||
final ReportPanel panel = new ReportPanel(this);
|
||||
|
||||
|
||||
panel.setCloseButtonActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
popUpWindow.dispose();
|
||||
}
|
||||
});
|
||||
// add the panel to the popup window
|
||||
popUpWindow.add(panel);
|
||||
|
||||
popUpWindow.setResizable(true);
|
||||
popUpWindow.pack();
|
||||
// set the location of the popUp Window on the center of the screen
|
||||
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
double w = popUpWindow.getSize().getWidth();
|
||||
double h = popUpWindow.getSize().getHeight();
|
||||
popUpWindow.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
|
||||
|
||||
reportThread.join();
|
||||
rr.progBarText();
|
||||
rr.progBarDone();
|
||||
panel.setFinishedReportText();
|
||||
popUpWindow.setVisible(true);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(ReportFilterAction.class.getName()).log(Level.WARNING, "Error displaying " + ACTION_NAME + " window.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public HashMap<ReportModule,String> getReports(){
|
||||
return reports;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[486, 68]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<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="processingLabel" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="reportProgressBar" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="reportLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="separationLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pathLabel" pref="548" max="32767" 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"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="cancelButton" max="32767" attributes="0"/>
|
||||
<Component id="reportProgressBar" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="reportLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="pathLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="separationLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="processingLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="20" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JProgressBar" name="reportProgressBar">
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="cancelButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/report/images/report_loading.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.cancelButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="null"/>
|
||||
</Property>
|
||||
<Property name="borderPainted" type="boolean" value="false"/>
|
||||
<Property name="contentAreaFilled" type="boolean" value="false"/>
|
||||
<Property name="focusPainted" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="mouseEntered" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="cancelButtonMouseEntered"/>
|
||||
<EventHandler event="mouseExited" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="cancelButtonMouseExited"/>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="reportLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Tahoma" size="11" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.reportLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="pathLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.pathLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="processingLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Tahoma" size="10" style="2"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.processingLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="separationLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.separationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,396 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 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.report;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ReportProgressPanel extends javax.swing.JPanel {
|
||||
private ReportStatus STATUS;
|
||||
|
||||
// Enum to represent if a report is waiting,
|
||||
// running, done, or has been canceled
|
||||
public enum ReportStatus {
|
||||
QUEUING,
|
||||
RUNNING,
|
||||
COMPLETE,
|
||||
CANCELED
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new form ReportProgressPanel
|
||||
*/
|
||||
public ReportProgressPanel(String reportName, String reportPath) {
|
||||
initComponents();
|
||||
customInit(reportName, reportPath);
|
||||
}
|
||||
|
||||
private void customInit(String reportName, String reportPath) {
|
||||
reportLabel.setText(reportName);
|
||||
pathLabel.setText("<html><u>" + shortenPath(reportPath) + "</u></html>");
|
||||
pathLabel.setToolTipText(reportPath);
|
||||
|
||||
reportProgressBar.setIndeterminate(true);
|
||||
reportProgressBar.setMaximum(100);
|
||||
|
||||
processingLabel.setText("Queuing...");
|
||||
STATUS = ReportStatus.QUEUING;
|
||||
|
||||
// Add the "link" effect to the pathLabel
|
||||
final String linkPath = reportPath;
|
||||
pathLabel.addMouseListener(new MouseListener() {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
File file = new File(linkPath);
|
||||
try {
|
||||
Desktop.getDesktop().open(file);
|
||||
} catch (IOException ex) {
|
||||
} catch (IllegalArgumentException ex) {
|
||||
try {
|
||||
// try to open the parent path if the file doens't exist
|
||||
Desktop.getDesktop().open(file.getParentFile());
|
||||
} catch (IOException ex1) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
pathLabel.setForeground(Color.DARK_GRAY);
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
pathLabel.setForeground(Color.BLACK);
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a shortened version of the given path.
|
||||
*/
|
||||
private String shortenPath(String path) {
|
||||
if (path.length() > 100) {
|
||||
path = path.substring(0, 10 + path.substring(10).indexOf(File.separator) + 1) + "..."
|
||||
+ path.substring((path.length() - 70) + path.substring(path.length() - 70).indexOf(File.separator));
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current ReportStatus of this report.
|
||||
*
|
||||
* @return ReportStatus status of this report
|
||||
*/
|
||||
public ReportStatus getStatus() {
|
||||
return STATUS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the JProgressBar for this report.
|
||||
*
|
||||
* Enables the cancelButton, updates the processingLabel, and changes this
|
||||
* report's ReportStatus.
|
||||
*/
|
||||
public void start() {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
cancelButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/report/images/report_cancel.png")));
|
||||
cancelButton.setToolTipText("Cancel");
|
||||
processingLabel.setText("Starting report...");
|
||||
STATUS = ReportStatus.RUNNING;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum progress for this report's JProgressBar.
|
||||
*
|
||||
* @param max maximum progress for JProgressBar
|
||||
*/
|
||||
public void setMaximumProgress(final int max) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (STATUS != ReportStatus.CANCELED) {
|
||||
reportProgressBar.setMaximum(max);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the JProgressBar for this report by one unit.
|
||||
*/
|
||||
public void increment() {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (STATUS != ReportStatus.CANCELED) {
|
||||
reportProgressBar.setValue(reportProgressBar.getValue() + 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of the JProgressBar for this report.
|
||||
*
|
||||
* @param value value to be set at
|
||||
*/
|
||||
public void setProgress(final int value) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (STATUS != ReportStatus.CANCELED) {
|
||||
reportProgressBar.setValue(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the status of the JProgressBar to be determinate or indeterminate.
|
||||
*
|
||||
* @param indeterminate sets the JProgressBar to be indeterminate if true, determinate otherwise
|
||||
*/
|
||||
public void setIndeterminate(final boolean indeterminate) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (STATUS != ReportStatus.CANCELED) {
|
||||
reportProgressBar.setIndeterminate(indeterminate);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the text of this report's status label. The text given will
|
||||
* be the full text used.
|
||||
* e.g. updateStatusLabel("Now processing files...")
|
||||
* sets the label to "Now processing files..."
|
||||
*
|
||||
* @param status String to use as status
|
||||
*/
|
||||
public void updateStatusLabel(final String status) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (STATUS != ReportStatus.CANCELED) {
|
||||
processingLabel.setText(status);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare the report completed.
|
||||
* This will fill the JProgressBar, update the cancelButton to completed,
|
||||
* and disallow any cancellation of this report.
|
||||
*/
|
||||
public void complete() {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (STATUS != ReportStatus.CANCELED) {
|
||||
STATUS = ReportStatus.COMPLETE;
|
||||
processingLabel.setText("Complete");
|
||||
reportProgressBar.setValue(reportProgressBar.getMaximum());
|
||||
cancelButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/report/images/report_complete.png")));
|
||||
cancelButton.setToolTipText("Complete");
|
||||
}
|
||||
}
|
||||
});
|
||||
// Do something with the button to change the icon and make not clickable
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
reportProgressBar = new javax.swing.JProgressBar();
|
||||
cancelButton = new javax.swing.JButton();
|
||||
reportLabel = new javax.swing.JLabel();
|
||||
pathLabel = new javax.swing.JLabel();
|
||||
processingLabel = new javax.swing.JLabel();
|
||||
separationLabel = new javax.swing.JLabel();
|
||||
|
||||
setMinimumSize(new java.awt.Dimension(486, 68));
|
||||
|
||||
cancelButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/report/images/report_loading.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.cancelButton.text")); // NOI18N
|
||||
cancelButton.setToolTipText(org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.cancelButton.toolTipText")); // NOI18N
|
||||
cancelButton.setBorder(null);
|
||||
cancelButton.setBorderPainted(false);
|
||||
cancelButton.setContentAreaFilled(false);
|
||||
cancelButton.setFocusPainted(false);
|
||||
cancelButton.addMouseListener(new java.awt.event.MouseAdapter() {
|
||||
public void mouseEntered(java.awt.event.MouseEvent evt) {
|
||||
cancelButtonMouseEntered(evt);
|
||||
}
|
||||
public void mouseExited(java.awt.event.MouseEvent evt) {
|
||||
cancelButtonMouseExited(evt);
|
||||
}
|
||||
});
|
||||
cancelButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cancelButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
reportLabel.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(reportLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.reportLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(pathLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.pathLabel.text")); // NOI18N
|
||||
|
||||
processingLabel.setFont(new java.awt.Font("Tahoma", 2, 10)); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(processingLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.processingLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(separationLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.separationLabel.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(processingLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(reportProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cancelButton))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(reportLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(separationLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pathLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 548, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(cancelButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(reportProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(reportLabel)
|
||||
.addComponent(pathLabel)
|
||||
.addComponent(separationLabel))
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(processingLabel)
|
||||
.addContainerGap(20, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
|
||||
cancel();
|
||||
}//GEN-LAST:event_cancelButtonActionPerformed
|
||||
|
||||
/**
|
||||
* Cancels the current report, based on it's status. If the report is
|
||||
* complete or has already been completed, nothing happens.
|
||||
*/
|
||||
void cancel() {
|
||||
switch(STATUS) {
|
||||
case COMPLETE:
|
||||
break;
|
||||
case CANCELED:
|
||||
break;
|
||||
default:
|
||||
STATUS = ReportStatus.CANCELED;
|
||||
cancelButton.setEnabled(false);
|
||||
cancelButton.setToolTipText("Canceled");
|
||||
reportProgressBar.setIndeterminate(false);
|
||||
reportProgressBar.setValue(0);
|
||||
reportProgressBar.setForeground(Color.RED);
|
||||
reportProgressBar.setBackground(Color.RED);
|
||||
processingLabel.setForeground(Color.RED);
|
||||
processingLabel.setText("Canceled");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelButtonMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_cancelButtonMouseEntered
|
||||
switch(STATUS) {
|
||||
case COMPLETE:
|
||||
break;
|
||||
case CANCELED:
|
||||
break;
|
||||
default:
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
cancelButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/report/images/report_cancel_hover.png")));
|
||||
break;
|
||||
}
|
||||
}//GEN-LAST:event_cancelButtonMouseEntered
|
||||
|
||||
private void cancelButtonMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_cancelButtonMouseExited
|
||||
switch(STATUS) {
|
||||
case COMPLETE:
|
||||
break;
|
||||
case CANCELED:
|
||||
break;
|
||||
case QUEUING:
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
cancelButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/report/images/report_loading.png")));
|
||||
break;
|
||||
case RUNNING:
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
cancelButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/report/images/report_cancel.png")));
|
||||
break;
|
||||
}
|
||||
}//GEN-LAST:event_cancelButtonMouseExited
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton cancelButton;
|
||||
private javax.swing.JLabel pathLabel;
|
||||
private javax.swing.JLabel processingLabel;
|
||||
private javax.swing.JLabel reportLabel;
|
||||
private javax.swing.JProgressBar reportProgressBar;
|
||||
private javax.swing.JLabel separationLabel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 Basis Technology Corp.
|
||||
*
|
||||
* Copyright 2012 42six Solutions.
|
||||
* Contact: aebadirad <at> 42six <dot> com
|
||||
* Project Contact/Architect: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.report;
|
||||
|
||||
public class ReportUtils {
|
||||
|
||||
static String changeExtension(String originalName, String newExtension) {
|
||||
int lastDot = originalName.lastIndexOf(".");
|
||||
if (lastDot != -1) {
|
||||
return originalName.substring(0, lastDot) + newExtension;
|
||||
} else {
|
||||
return originalName + newExtension;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a string into a string every n number of characters
|
||||
*
|
||||
* @param text the base string/text that you want to have manipulated
|
||||
* @param insert the string you want to insert
|
||||
* @param period how many characters it should input insert at
|
||||
* @return string with the string inserts inserted
|
||||
*/
|
||||
public static String insertPeriodically(String text, String insert, int period) {
|
||||
StringBuilder builder = new StringBuilder(
|
||||
text.length() + insert.length() * (text.length() / period) + 1);
|
||||
|
||||
int index = 0;
|
||||
String prefix = "";
|
||||
while (index < text.length()) {
|
||||
// Don't put the insert in the very first iteration.
|
||||
// This is easier than appending it *after* each substring
|
||||
builder.append(prefix);
|
||||
prefix = insert;
|
||||
builder.append(text.substring(index,
|
||||
Math.min(index + period, text.length())));
|
||||
index += period;
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[650, 250]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<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" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="reportModulesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="modulesScrollPane" alignment="0" min="-2" pref="186" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="configurationPanel" max="32767" attributes="0"/>
|
||||
<Component id="descriptionScrollPane" max="32767" attributes="0"/>
|
||||
</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="reportModulesLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="modulesScrollPane" pref="208" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="configurationPanel" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="descriptionScrollPane" min="-2" pref="32" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="modulesScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="modulesTable">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="f0" green="f0" red="f0" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
|
||||
<Table columnCount="0" rowCount="0"/>
|
||||
</Property>
|
||||
<Property name="showHorizontalLines" type="boolean" value="false"/>
|
||||
<Property name="showVerticalLines" type="boolean" value="false"/>
|
||||
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
|
||||
<TableHeader reorderingAllowed="true" resizingAllowed="true"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="reportModulesLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportVisualPanel1.reportModulesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="configurationPanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
|
||||
<LineBorder>
|
||||
<Color PropertyName="color" blue="7d" green="7d" red="7d" type="rgb"/>
|
||||
</LineBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="432" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
</Container>
|
||||
<Container class="javax.swing.JScrollPane" name="descriptionScrollPane">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="null"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextPane" name="descriptionTextPane">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="f0" green="f0" red="f0" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="null"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 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.report;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.TableColumn;
|
||||
import org.openide.util.Lookup;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
public final class ReportVisualPanel1 extends JPanel {
|
||||
private static final Logger logger = Logger.getLogger(ReportVisualPanel1.class.getName());
|
||||
private ReportWizardPanel1 wizPanel;
|
||||
|
||||
private Map<TableReportModule, Boolean> tableModuleStates = new LinkedHashMap<TableReportModule, Boolean>();
|
||||
private Map<GeneralReportModule, Boolean> generalModuleStates = new LinkedHashMap<GeneralReportModule, Boolean>();
|
||||
private List<TableReportModule> tableModules = new ArrayList<TableReportModule>();
|
||||
private List<GeneralReportModule> generalModules = new ArrayList<GeneralReportModule>();
|
||||
|
||||
private ModulesTableModel modulesModel;
|
||||
private ModuleSelectionListener modulesListener;
|
||||
|
||||
/**
|
||||
* Creates new form ReportVisualPanel1
|
||||
*/
|
||||
public ReportVisualPanel1(ReportWizardPanel1 wizPanel) {
|
||||
initComponents();
|
||||
initModules();
|
||||
this.wizPanel = wizPanel;
|
||||
configurationPanel.setLayout(new BorderLayout());
|
||||
descriptionTextPane.setEditable(false);
|
||||
modulesTable.setRowSelectionInterval(0, 0);
|
||||
}
|
||||
|
||||
// Initialize the list of ReportModules
|
||||
private void initModules() {
|
||||
for(TableReportModule module : Lookup.getDefault().lookupAll(TableReportModule.class)) {
|
||||
if(module.getName().equals("HTML")) {
|
||||
tableModuleStates.put(module, Boolean.TRUE);
|
||||
} else {
|
||||
tableModuleStates.put(module, Boolean.FALSE);
|
||||
}
|
||||
tableModules.add(module);
|
||||
}
|
||||
for(GeneralReportModule module : Lookup.getDefault().lookupAll(GeneralReportModule.class)) {
|
||||
generalModuleStates.put(module, Boolean.FALSE);
|
||||
generalModules.add(module);
|
||||
}
|
||||
|
||||
modulesModel = new ModulesTableModel();
|
||||
modulesListener = new ModuleSelectionListener();
|
||||
modulesTable.setModel(modulesModel);
|
||||
modulesTable.getSelectionModel().addListSelectionListener(modulesListener);
|
||||
modulesTable.setTableHeader(null);
|
||||
modulesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
modulesTable.setRowHeight(modulesTable.getRowHeight() + 5);
|
||||
|
||||
int width = modulesScrollPane.getPreferredSize().width;
|
||||
for (int i = 0; i < modulesTable.getColumnCount(); i++) {
|
||||
TableColumn column = modulesTable.getColumnModel().getColumn(i);
|
||||
if (i == 0) {
|
||||
column.setPreferredWidth(((int) (width * 0.15)));
|
||||
} else {
|
||||
column.setPreferredWidth(((int) (width * 0.84)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Select and Configure Report Modules";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the enabled/disabled states of all TableReportModules
|
||||
*/
|
||||
Map<TableReportModule, Boolean> getTableModuleStates() {
|
||||
return tableModuleStates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the enabled/disabled states of all GeneralReportModules
|
||||
*/
|
||||
Map<GeneralReportModule, Boolean> getGeneralModuleStates() {
|
||||
return generalModuleStates;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
modulesScrollPane = new javax.swing.JScrollPane();
|
||||
modulesTable = new javax.swing.JTable();
|
||||
reportModulesLabel = new javax.swing.JLabel();
|
||||
configurationPanel = new javax.swing.JPanel();
|
||||
descriptionScrollPane = new javax.swing.JScrollPane();
|
||||
descriptionTextPane = new javax.swing.JTextPane();
|
||||
|
||||
setPreferredSize(new java.awt.Dimension(650, 250));
|
||||
|
||||
modulesTable.setBackground(new java.awt.Color(240, 240, 240));
|
||||
modulesTable.setModel(new javax.swing.table.DefaultTableModel(
|
||||
new Object [][] {
|
||||
|
||||
},
|
||||
new String [] {
|
||||
|
||||
}
|
||||
));
|
||||
modulesTable.setShowHorizontalLines(false);
|
||||
modulesTable.setShowVerticalLines(false);
|
||||
modulesScrollPane.setViewportView(modulesTable);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(reportModulesLabel, org.openide.util.NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.reportModulesLabel.text")); // NOI18N
|
||||
|
||||
configurationPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(125, 125, 125)));
|
||||
|
||||
javax.swing.GroupLayout configurationPanelLayout = new javax.swing.GroupLayout(configurationPanel);
|
||||
configurationPanel.setLayout(configurationPanelLayout);
|
||||
configurationPanelLayout.setHorizontalGroup(
|
||||
configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 432, Short.MAX_VALUE)
|
||||
);
|
||||
configurationPanelLayout.setVerticalGroup(
|
||||
configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
descriptionScrollPane.setBorder(null);
|
||||
|
||||
descriptionTextPane.setBackground(new java.awt.Color(240, 240, 240));
|
||||
descriptionTextPane.setBorder(null);
|
||||
descriptionScrollPane.setViewportView(descriptionTextPane);
|
||||
|
||||
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(reportModulesLabel)
|
||||
.addComponent(modulesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 186, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(10, 10, 10)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(descriptionScrollPane))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(reportModulesLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(modulesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 208, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(descriptionScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JPanel configurationPanel;
|
||||
private javax.swing.JScrollPane descriptionScrollPane;
|
||||
private javax.swing.JTextPane descriptionTextPane;
|
||||
private javax.swing.JScrollPane modulesScrollPane;
|
||||
private javax.swing.JTable modulesTable;
|
||||
private javax.swing.JLabel reportModulesLabel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
private class ModulesTableModel extends AbstractTableModel {
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return tableModules.size() + generalModules.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
ReportModule module;
|
||||
if (rowIndex < tableModules.size()) {
|
||||
module = tableModules.get(rowIndex);
|
||||
} else {
|
||||
module = generalModules.get(rowIndex - tableModules.size());
|
||||
}
|
||||
if (columnIndex == 0 && rowIndex < tableModules.size()) {
|
||||
return tableModuleStates.get(tableModules.get(rowIndex));
|
||||
} else if (columnIndex == 0 && rowIndex >= tableModules.size()) {
|
||||
return generalModuleStates.get(generalModules.get(rowIndex - tableModules.size()));
|
||||
} else {
|
||||
return module.getName();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return columnIndex == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
if (columnIndex == 0 && rowIndex < tableModules.size()) {
|
||||
tableModuleStates.put(tableModules.get(rowIndex), (Boolean) aValue);
|
||||
} else if (columnIndex == 0 && rowIndex >= tableModules.size()) {
|
||||
generalModuleStates.put(generalModules.get(rowIndex - tableModules.size()), (Boolean) aValue);
|
||||
}
|
||||
// Check if there are any TableReportModules enabled
|
||||
boolean tableModuleEnabled = false;
|
||||
for (Entry<TableReportModule, Boolean> module : tableModuleStates.entrySet()) {
|
||||
if (module.getValue()) {
|
||||
tableModuleEnabled = true;
|
||||
}
|
||||
}
|
||||
boolean generalModuleEnabled = false;
|
||||
for (Entry<GeneralReportModule, Boolean> module : generalModuleStates.entrySet()) {
|
||||
if (module.getValue()) {
|
||||
generalModuleEnabled = true;
|
||||
}
|
||||
}
|
||||
if(tableModuleEnabled) {
|
||||
wizPanel.setNext(true);
|
||||
wizPanel.setFinish(false);
|
||||
} else if(generalModuleEnabled) {
|
||||
wizPanel.setFinish(true);
|
||||
wizPanel.setNext(false);
|
||||
} else {
|
||||
wizPanel.setFinish(false);
|
||||
wizPanel.setNext(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getColumnClass(int c) {
|
||||
return getValueAt(0, c).getClass();
|
||||
}
|
||||
}
|
||||
|
||||
private class ModuleSelectionListener implements ListSelectionListener {
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
configurationPanel.removeAll();
|
||||
int rowIndex = modulesTable.getSelectedRow();
|
||||
if (rowIndex < tableModules.size()) {
|
||||
configurationPanel.add(new DefaultReportConfigurationPanel(), BorderLayout.CENTER);
|
||||
descriptionTextPane.setText(tableModules.get(rowIndex).getDescription());
|
||||
} else {
|
||||
GeneralReportModule module = generalModules.get(rowIndex - tableModules.size());
|
||||
JPanel panel = module.getConfigurationPanel();
|
||||
descriptionTextPane.setText(module.getDescription());
|
||||
if (panel != null) {
|
||||
configurationPanel.add(panel, BorderLayout.CENTER);
|
||||
}
|
||||
}
|
||||
configurationPanel.revalidate();
|
||||
configurationPanel.repaint();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.ButtonGroup" name="optionsButtonGroup">
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[650, 250]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<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" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="taggedResultsRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="allResultsRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="dataLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="481" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="-2" pref="21" max="-2" attributes="0"/>
|
||||
<Component id="tagsScrollPane" max="32767" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="advancedButton" alignment="1" max="32767" attributes="0"/>
|
||||
<Component id="deselectAllButton" max="32767" attributes="0"/>
|
||||
<Component id="selectAllButton" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</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="dataLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="allResultsRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="taggedResultsRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="7" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="selectAllButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="deselectAllButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="70" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="tagsScrollPane" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="advancedButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JRadioButton" name="taggedResultsRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="optionsButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportVisualPanel2.taggedResultsRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="taggedResultsRadioButtonStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="allResultsRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="optionsButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportVisualPanel2.allResultsRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="dataLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportVisualPanel2.dataLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="selectAllButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportVisualPanel2.selectAllButton.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="selectAllButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="deselectAllButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportVisualPanel2.deselectAllButton.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="deselectAllButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="tagsScrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JList" name="tagsList">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
<Property name="selectionMode" type="int" value="0"/>
|
||||
<Property name="layoutOrientation" type="int" value="1"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="advancedButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportVisualPanel2.advancedButton.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="advancedButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 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.report;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import javax.swing.ListModel;
|
||||
import javax.swing.event.ListDataListener;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datamodel.Tags;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||
|
||||
public final class ReportVisualPanel2 extends JPanel {
|
||||
private static final Logger logger = Logger.getLogger(ReportVisualPanel2.class.getName());
|
||||
private ReportWizardPanel2 wizPanel;
|
||||
|
||||
private Map<String, Boolean> tagStates = new LinkedHashMap<String, Boolean>();
|
||||
private List<String> tags = new ArrayList<String>();
|
||||
|
||||
ArtifactSelectionDialog dialog = new ArtifactSelectionDialog(new JFrame(), true);
|
||||
private Map<ARTIFACT_TYPE, Boolean> artifactStates = new EnumMap<ARTIFACT_TYPE, Boolean>(ARTIFACT_TYPE.class);
|
||||
private List<ARTIFACT_TYPE> artifacts = new ArrayList<ARTIFACT_TYPE>();
|
||||
|
||||
private TagsListModel tagsModel;
|
||||
private TagsListRenderer tagsRenderer;
|
||||
|
||||
/**
|
||||
* Creates new form ReportVisualPanel2
|
||||
*/
|
||||
public ReportVisualPanel2(ReportWizardPanel2 wizPanel) {
|
||||
initComponents();
|
||||
initTags();
|
||||
initArtifactTypes();
|
||||
tagsList.setEnabled(false);
|
||||
selectAllButton.setEnabled(false);
|
||||
deselectAllButton.setEnabled(false);
|
||||
allResultsRadioButton.setSelected(true);
|
||||
this.wizPanel = wizPanel;
|
||||
}
|
||||
|
||||
// Initialize the list of Tags
|
||||
private void initTags() {
|
||||
for(String tag : Tags.getTagNames()) {
|
||||
tagStates.put(tag, Boolean.FALSE);
|
||||
}
|
||||
tags.addAll(tagStates.keySet());
|
||||
|
||||
tagsModel = new TagsListModel();
|
||||
tagsRenderer = new TagsListRenderer();
|
||||
tagsList.setModel(tagsModel);
|
||||
tagsList.setCellRenderer(tagsRenderer);
|
||||
tagsList.setVisibleRowCount(-1);
|
||||
|
||||
// Add the ability to enable and disable Tag checkboxes to the list
|
||||
tagsList.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent evt) {
|
||||
JList list = (JList) evt.getSource();
|
||||
int index = list.locationToIndex(evt.getPoint());
|
||||
String value = (String) tagsModel.getElementAt(index);
|
||||
tagStates.put(value, !tagStates.get(value));
|
||||
list.repaint();
|
||||
updateFinishButton();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Initialize the list of Artifacts
|
||||
private void initArtifactTypes() {
|
||||
artifacts = ArtifactSelectionDialog.getImportantArtifactTypes();
|
||||
artifactStates = new EnumMap<ARTIFACT_TYPE, Boolean>(ARTIFACT_TYPE.class);
|
||||
for (ARTIFACT_TYPE type : artifacts) {
|
||||
artifactStates.put(type, Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Configure HTML and Excel reports";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the enabled/disabled state of all Artifacts
|
||||
*/
|
||||
Map<ARTIFACT_TYPE, Boolean> getArtifactStates() {
|
||||
return artifactStates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the enabled/disabled state of all Tags
|
||||
*/
|
||||
Map<String, Boolean> getTagStates() {
|
||||
return tagStates;
|
||||
}
|
||||
|
||||
private boolean areTagsSelected() {
|
||||
boolean result = false;
|
||||
for (Entry<String, Boolean> entry: tagStates.entrySet()) {
|
||||
if (entry.getValue()) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean areArtifactsSelected() {
|
||||
boolean result = false;
|
||||
for (Entry<ARTIFACT_TYPE, Boolean> entry: artifactStates.entrySet()) {
|
||||
if (entry.getValue()) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void updateFinishButton() {
|
||||
if (taggedResultsRadioButton.isSelected()) {
|
||||
wizPanel.setFinish(areTagsSelected());
|
||||
} else {
|
||||
wizPanel.setFinish(areArtifactsSelected());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the Tags radio button is selected, false otherwise
|
||||
*/
|
||||
boolean isTaggedResultsRadioButtonSelected() {
|
||||
return taggedResultsRadioButton.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.
|
||||
*/
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
optionsButtonGroup = new javax.swing.ButtonGroup();
|
||||
taggedResultsRadioButton = new javax.swing.JRadioButton();
|
||||
allResultsRadioButton = new javax.swing.JRadioButton();
|
||||
dataLabel = new javax.swing.JLabel();
|
||||
selectAllButton = new javax.swing.JButton();
|
||||
deselectAllButton = new javax.swing.JButton();
|
||||
tagsScrollPane = new javax.swing.JScrollPane();
|
||||
tagsList = new javax.swing.JList();
|
||||
advancedButton = new javax.swing.JButton();
|
||||
|
||||
setPreferredSize(new java.awt.Dimension(650, 250));
|
||||
|
||||
optionsButtonGroup.add(taggedResultsRadioButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(taggedResultsRadioButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.taggedResultsRadioButton.text")); // NOI18N
|
||||
taggedResultsRadioButton.addChangeListener(new javax.swing.event.ChangeListener() {
|
||||
public void stateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
taggedResultsRadioButtonStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
optionsButtonGroup.add(allResultsRadioButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(allResultsRadioButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.allResultsRadioButton.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(dataLabel, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.dataLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(selectAllButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.selectAllButton.text")); // NOI18N
|
||||
selectAllButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
selectAllButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(deselectAllButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.deselectAllButton.text")); // NOI18N
|
||||
deselectAllButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
deselectAllButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
tagsList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
tagsList.setLayoutOrientation(javax.swing.JList.VERTICAL_WRAP);
|
||||
tagsScrollPane.setViewportView(tagsList);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(advancedButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.advancedButton.text")); // NOI18N
|
||||
advancedButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
advancedButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
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)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(taggedResultsRadioButton)
|
||||
.addComponent(allResultsRadioButton)
|
||||
.addComponent(dataLabel))
|
||||
.addGap(0, 481, Short.MAX_VALUE))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGap(21, 21, 21)
|
||||
.addComponent(tagsScrollPane)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(advancedButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(deselectAllButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(selectAllButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(dataLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(allResultsRadioButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(taggedResultsRadioButton)
|
||||
.addGap(7, 7, 7)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(selectAllButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(deselectAllButton)
|
||||
.addGap(0, 70, Short.MAX_VALUE))
|
||||
.addComponent(tagsScrollPane))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(advancedButton)
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void taggedResultsRadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_taggedResultsRadioButtonStateChanged
|
||||
tagsList.setEnabled(taggedResultsRadioButton.isSelected());
|
||||
selectAllButton.setEnabled(taggedResultsRadioButton.isSelected());
|
||||
deselectAllButton.setEnabled(taggedResultsRadioButton.isSelected());
|
||||
advancedButton.setEnabled(!taggedResultsRadioButton.isSelected());
|
||||
updateFinishButton();
|
||||
}//GEN-LAST:event_taggedResultsRadioButtonStateChanged
|
||||
|
||||
private void selectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectAllButtonActionPerformed
|
||||
for (String tag : tags) {
|
||||
tagStates.put(tag, Boolean.TRUE);
|
||||
}
|
||||
tagsList.repaint();
|
||||
wizPanel.setFinish(true);
|
||||
}//GEN-LAST:event_selectAllButtonActionPerformed
|
||||
|
||||
private void deselectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deselectAllButtonActionPerformed
|
||||
for (String tag : tags) {
|
||||
tagStates.put(tag, Boolean.FALSE);
|
||||
}
|
||||
tagsList.repaint();
|
||||
wizPanel.setFinish(false);
|
||||
}//GEN-LAST:event_deselectAllButtonActionPerformed
|
||||
|
||||
private void advancedButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_advancedButtonActionPerformed
|
||||
artifactStates = dialog.display();
|
||||
wizPanel.setFinish(areArtifactsSelected());
|
||||
}//GEN-LAST:event_advancedButtonActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton advancedButton;
|
||||
private javax.swing.JRadioButton allResultsRadioButton;
|
||||
private javax.swing.JLabel dataLabel;
|
||||
private javax.swing.JButton deselectAllButton;
|
||||
private javax.swing.ButtonGroup optionsButtonGroup;
|
||||
private javax.swing.JButton selectAllButton;
|
||||
private javax.swing.JRadioButton taggedResultsRadioButton;
|
||||
private javax.swing.JList tagsList;
|
||||
private javax.swing.JScrollPane tagsScrollPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
private class TagsListModel implements ListModel {
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return tags.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElementAt(int index) {
|
||||
return tags.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListDataListener(ListDataListener l) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListDataListener(ListDataListener l) {
|
||||
}
|
||||
}
|
||||
|
||||
// Render the Tags as JCheckboxes
|
||||
private class TagsListRenderer extends JCheckBox implements ListCellRenderer {
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
if (value != null) {
|
||||
setEnabled(list.isEnabled());
|
||||
setSelected(tagStates.get(value.toString()));
|
||||
setFont(list.getFont());
|
||||
setBackground(list.getBackground());
|
||||
setForeground(list.getForeground());
|
||||
setText(value.toString());
|
||||
return this;
|
||||
}
|
||||
return new JLabel();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 Basis Technology Corp.
|
||||
*
|
||||
* Copyright 2012 42six Solutions.
|
||||
* Contact: aebadirad <at> 42six <dot> com
|
||||
* Project Contact/Architect: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.report;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import org.openide.DialogDisplayer;
|
||||
import org.openide.WizardDescriptor;
|
||||
import org.openide.awt.ActionID;
|
||||
import org.openide.awt.ActionReference;
|
||||
import org.openide.awt.ActionReferences;
|
||||
import org.openide.awt.ActionRegistration;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
import org.openide.util.actions.Presenter;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||
|
||||
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.report.ReportWizardAction")
|
||||
@ActionRegistration(displayName = "#CTL_ReportWizardAction", lazy = false)
|
||||
@ActionReferences(value = {
|
||||
@ActionReference(path = "Menu/Tools", position = 80)})
|
||||
@NbBundle.Messages(value = "CTL_ReportWizardAction=Run Report")
|
||||
public final class ReportWizardAction extends CallableSystemAction implements Presenter.Toolbar, ActionListener {
|
||||
private static final Logger logger = Logger.getLogger(ReportWizardAction.class.getName());
|
||||
|
||||
private JButton toolbarButton = new JButton();
|
||||
private static final String ACTION_NAME = "Generate Report";
|
||||
|
||||
public ReportWizardAction() {
|
||||
setEnabled(false);
|
||||
Case.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (evt.getPropertyName().equals(Case.CASE_CURRENT_CASE)) {
|
||||
Case newCase = (Case) evt.getNewValue();
|
||||
setEnabled(newCase != null);
|
||||
|
||||
// Make the cases' Reoports folder, if it doesn't exist
|
||||
if (newCase != null) {
|
||||
boolean exists = (new File(newCase.getCaseDirectory() + File.separator + "Reports")).exists();
|
||||
if (!exists) {
|
||||
boolean reportCreate = (new File(newCase.getCaseDirectory() + File.separator + "Reports")).mkdirs();
|
||||
if (!reportCreate) {
|
||||
logger.log(Level.WARNING, "Could not create Reports directory for case. It does not exist.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize the Generate Report button
|
||||
toolbarButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ReportWizardAction.this.actionPerformed(e);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* When the Generate Report button or menu item is selected, open the reporting wizard.
|
||||
* When the wizard is finished, create a ReportGenerator with the wizard information,
|
||||
* and start all necessary reports.
|
||||
*/
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// Create the wizard
|
||||
WizardDescriptor wiz = new WizardDescriptor(new ReportWizardIterator());
|
||||
wiz.setTitleFormat(new MessageFormat("{0} {1}"));
|
||||
wiz.setTitle("Generate Report");
|
||||
|
||||
// When the user presses the finish button
|
||||
if (DialogDisplayer.getDefault().notify(wiz) == WizardDescriptor.FINISH_OPTION) {
|
||||
// Get the wizard information
|
||||
Map<TableReportModule, Boolean> tableModuleStates = (Map<TableReportModule, Boolean>) wiz.getProperty("tableModuleStates");
|
||||
Map<GeneralReportModule, Boolean> generalModuleStates = (Map<GeneralReportModule, Boolean>) wiz.getProperty("generalModuleStates");
|
||||
// Create the generator and generate reports
|
||||
ReportGenerator generator = new ReportGenerator(tableModuleStates, generalModuleStates);
|
||||
if (wiz.getProperty("isTagsSelected") != null) {
|
||||
if ((Boolean) wiz.getProperty("isTagsSelected")) {
|
||||
generator.generateTableTagReport((Map<String, Boolean>) wiz.getProperty("tagStates"));
|
||||
} else {
|
||||
generator.generateTableArtifactReport((Map<ARTIFACT_TYPE, Boolean>) wiz.getProperty("artifactStates"));
|
||||
}
|
||||
}
|
||||
generator.generateGeneralReports();
|
||||
// Open the progress window for the user
|
||||
generator.displayProgressPanels();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performAction() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return ACTION_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HelpCtx getHelpCtx() {
|
||||
return HelpCtx.DEFAULT_HELP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the toolbar component of this action
|
||||
*
|
||||
* @return component the toolbar button
|
||||
*/
|
||||
@Override
|
||||
public Component getToolbarPresenter() {
|
||||
ImageIcon icon = new ImageIcon(getClass().getResource("images/btn_icon_generate_report.png"));
|
||||
toolbarButton.setIcon(icon);
|
||||
toolbarButton.setText("Generate Report");
|
||||
return toolbarButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this action to be enabled/disabled
|
||||
*
|
||||
* @param value whether to enable this action or not
|
||||
*/
|
||||
@Override
|
||||
public void setEnabled(boolean value) {
|
||||
super.setEnabled(value);
|
||||
toolbarButton.setEnabled(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 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.report;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import org.openide.WizardDescriptor;
|
||||
|
||||
public final class ReportWizardIterator implements WizardDescriptor.Iterator<WizardDescriptor> {
|
||||
private int index;
|
||||
private List<WizardDescriptor.Panel<WizardDescriptor>> panels;
|
||||
|
||||
private List<WizardDescriptor.Panel<WizardDescriptor>> getPanels() {
|
||||
if (panels == null) {
|
||||
panels = new ArrayList<WizardDescriptor.Panel<WizardDescriptor>>();
|
||||
panels.add(new ReportWizardPanel1());
|
||||
panels.add(new ReportWizardPanel2());
|
||||
String[] steps = new String[panels.size()];
|
||||
for (int i = 0; i < panels.size(); i++) {
|
||||
Component c = panels.get(i).getComponent();
|
||||
// Default step name to component name of panel.
|
||||
steps[i] = c.getName();
|
||||
if (c instanceof JComponent) { // assume Swing components
|
||||
JComponent jc = (JComponent) c;
|
||||
jc.putClientProperty(WizardDescriptor.PROP_CONTENT_SELECTED_INDEX, i);
|
||||
jc.putClientProperty(WizardDescriptor.PROP_CONTENT_DATA, steps);
|
||||
jc.putClientProperty(WizardDescriptor.PROP_AUTO_WIZARD_STYLE, true);
|
||||
jc.putClientProperty(WizardDescriptor.PROP_CONTENT_DISPLAYED, false);
|
||||
jc.putClientProperty(WizardDescriptor.PROP_CONTENT_NUMBERED, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return panels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WizardDescriptor.Panel<WizardDescriptor> current() {
|
||||
return getPanels().get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return index < getPanels().size() - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return index > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextPanel() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void previousPanel() {
|
||||
if (!hasPrevious()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
index--;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChangeListener(ChangeListener l) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeChangeListener(ChangeListener l) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 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.report;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import org.openide.WizardDescriptor;
|
||||
import org.openide.util.HelpCtx;
|
||||
|
||||
public class ReportWizardPanel1 implements WizardDescriptor.FinishablePanel<WizardDescriptor> {
|
||||
private WizardDescriptor wiz;
|
||||
private ReportVisualPanel1 component;
|
||||
private JButton nextButton;
|
||||
private JButton finishButton;
|
||||
|
||||
ReportWizardPanel1() {
|
||||
nextButton = new JButton("Next >");
|
||||
finishButton = new JButton("Finish");
|
||||
finishButton.setEnabled(false);
|
||||
|
||||
// Initialize our custom next and finish buttons
|
||||
nextButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
wiz.doNextClick();
|
||||
}
|
||||
});
|
||||
|
||||
finishButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
wiz.doFinishClick();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReportVisualPanel1 getComponent() {
|
||||
if (component == null) {
|
||||
component = new ReportVisualPanel1(this);
|
||||
}
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HelpCtx getHelp() {
|
||||
return HelpCtx.DEFAULT_HELP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
// Always valid, but we control the enabled state
|
||||
// of our custom buttons
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinishPanel() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setNext(boolean enabled) {
|
||||
nextButton.setEnabled(enabled);
|
||||
}
|
||||
|
||||
public void setFinish(boolean enabled) {
|
||||
finishButton.setEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChangeListener(ChangeListener l) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeChangeListener(ChangeListener l) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSettings(WizardDescriptor wiz) {
|
||||
// Add out custom buttons in place of the regular ones
|
||||
this.wiz = wiz;
|
||||
wiz.setOptions(new Object[] {WizardDescriptor.PREVIOUS_OPTION, nextButton, finishButton, WizardDescriptor.CANCEL_OPTION});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeSettings(WizardDescriptor wiz) {
|
||||
wiz.putProperty("tableModuleStates", getComponent().getTableModuleStates());
|
||||
wiz.putProperty("generalModuleStates", getComponent().getGeneralModuleStates());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 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.report;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import org.openide.WizardDescriptor;
|
||||
import org.openide.util.HelpCtx;
|
||||
|
||||
public class ReportWizardPanel2 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
private ReportVisualPanel2 component;
|
||||
private JButton finishButton;
|
||||
private WizardDescriptor wiz;
|
||||
|
||||
ReportWizardPanel2() {
|
||||
finishButton = new JButton("Finish");
|
||||
finishButton.setEnabled(true);
|
||||
|
||||
finishButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
wiz.doFinishClick();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReportVisualPanel2 getComponent() {
|
||||
if (component == null) {
|
||||
component = new ReportVisualPanel2(this);
|
||||
}
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HelpCtx getHelp() {
|
||||
return HelpCtx.DEFAULT_HELP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChangeListener(ChangeListener l) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeChangeListener(ChangeListener l) {
|
||||
}
|
||||
|
||||
public void setFinish(boolean enabled) {
|
||||
finishButton.setEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSettings(WizardDescriptor wiz) {
|
||||
// Re-enable the normal wizard buttons
|
||||
this.wiz = wiz;
|
||||
wiz.setOptions(new Object[] {WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, finishButton, WizardDescriptor.CANCEL_OPTION});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeSettings(WizardDescriptor wiz) {
|
||||
wiz.putProperty("tagStates", getComponent().getTagStates());
|
||||
wiz.putProperty("artifactStates", getComponent().getArtifactStates());
|
||||
wiz.putProperty("isTagsSelected", getComponent().isTaggedResultsRadioButtonSelected());
|
||||
}
|
||||
}
|
||||
@@ -1,592 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 Basis Technology Corp.
|
||||
*
|
||||
* Copyright 2012 42six Solutions.
|
||||
* Contact: aebadirad <at> 42six <dot> com
|
||||
* Project Contact/Architect: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.report;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.TreeMap;
|
||||
import java.util.logging.Level;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.*;
|
||||
|
||||
/**
|
||||
* Generates an XLS report for all the Blackboard Artifacts found in the current case.
|
||||
*/
|
||||
public class ReportXLS implements ReportModule {
|
||||
|
||||
public static Workbook wb = new XSSFWorkbook();
|
||||
private static String xlsPath = "";
|
||||
private ReportConfiguration config;
|
||||
private static ReportXLS instance = null;
|
||||
private static final Logger logger = Logger.getLogger(ReportXLS.class.getName());
|
||||
|
||||
public ReportXLS() {
|
||||
//Empty the workbook first
|
||||
}
|
||||
|
||||
public static synchronized ReportXLS getDefault() {
|
||||
if (instance == null) {
|
||||
instance = new ReportXLS();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateReport(ReportConfiguration reportconfig) throws ReportModuleException {
|
||||
config = reportconfig;
|
||||
ReportGen reportobj = new ReportGen();
|
||||
reportobj.populateReport(reportconfig);
|
||||
HashMap<BlackboardArtifact, List<BlackboardAttribute>> report = reportobj.getResults();
|
||||
Workbook wbtemp = new XSSFWorkbook();
|
||||
int countGen = 0;
|
||||
int countBookmark = 0;
|
||||
int countCookie = 0;
|
||||
int countHistory = 0;
|
||||
int countDownload = 0;
|
||||
int countRecentObjects = 0;
|
||||
int countTrackPoint = 0;
|
||||
int countInstalled = 0;
|
||||
int countKeyword = 0;
|
||||
int countHash = 0;
|
||||
int countDevice = 0;
|
||||
int countEmail = 0;
|
||||
int countWebSearch = 0;
|
||||
int countExif = 0;
|
||||
int countTagFile = 0;
|
||||
for (Entry<BlackboardArtifact, List<BlackboardAttribute>> entry : report.entrySet()) {
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID()) {
|
||||
countGen++;
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()) {
|
||||
countBookmark++;
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()) {
|
||||
|
||||
countCookie++;
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) {
|
||||
|
||||
countHistory++;
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()) {
|
||||
countDownload++;
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID()) {
|
||||
countRecentObjects++;
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TRACKPOINT.getTypeID()) {
|
||||
countTrackPoint++;
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) {
|
||||
countInstalled++;
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
|
||||
countKeyword++;
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) {
|
||||
countHash++;
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) {
|
||||
countDevice++;
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
|
||||
countEmail++;
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
|
||||
countWebSearch++;
|
||||
}
|
||||
if(entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID()){
|
||||
countExif++;
|
||||
}
|
||||
if(entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()){
|
||||
countTagFile++;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Case currentCase = Case.getCurrentCase(); // get the most updated case
|
||||
SleuthkitCase skCase = currentCase.getSleuthkitCase();
|
||||
String caseName = currentCase.getName();
|
||||
String examiner = currentCase.getExaminer();
|
||||
String number = currentCase.getNumber();
|
||||
Integer imagecount = currentCase.getImageIDs().length;
|
||||
Integer filesystemcount = currentCase.getRootObjectsCount();
|
||||
Integer totalfiles = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG);
|
||||
Integer totaldirs = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR);
|
||||
DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
||||
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
|
||||
Date date = new Date();
|
||||
String datetime = datetimeFormat.format(date);
|
||||
String datenotime = dateFormat.format(date);
|
||||
|
||||
//The first summary report page
|
||||
Sheet sheetSummary = wbtemp.createSheet("Summary");
|
||||
|
||||
//Generate a sheet per artifact type
|
||||
// Sheet sheetGen = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getDisplayName());
|
||||
Sheet sheetHash = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName());
|
||||
Sheet sheetDevice = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getDisplayName());
|
||||
Sheet sheetInstalled = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getDisplayName());
|
||||
Sheet sheetKeyword = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName());
|
||||
// Sheet sheetTrackpoint = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_TRACKPOINT.getDisplayName());
|
||||
Sheet sheetRecent = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getDisplayName());
|
||||
Sheet sheetCookie = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getDisplayName());
|
||||
Sheet sheetBookmark = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getDisplayName());
|
||||
Sheet sheetDownload = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getDisplayName());
|
||||
Sheet sheetHistory = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getDisplayName());
|
||||
Sheet sheetEmail = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getDisplayName());
|
||||
Sheet sheetWebSearch = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getDisplayName());
|
||||
Sheet sheetExif = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getDisplayName());
|
||||
Sheet sheetTagFile = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getDisplayName());
|
||||
//Bold/underline cell style for the top header rows
|
||||
CellStyle style = wbtemp.createCellStyle();
|
||||
style.setBorderBottom((short) 2);
|
||||
Font font = wbtemp.createFont();
|
||||
font.setFontHeightInPoints((short) 14);
|
||||
font.setFontName("Arial");
|
||||
font.setBoldweight((short) 2);
|
||||
style.setFont(font);
|
||||
|
||||
//create 'default' style
|
||||
CellStyle defaultstyle = wbtemp.createCellStyle();
|
||||
defaultstyle.setBorderBottom((short) 2);
|
||||
Font defaultfont = wbtemp.createFont();
|
||||
defaultfont.setFontHeightInPoints((short) 14);
|
||||
defaultfont.setFontName("Arial");
|
||||
defaultfont.setBoldweight((short) 2);
|
||||
defaultstyle.setFont(defaultfont);
|
||||
//create the rows in the worksheet for our records
|
||||
//Create first row and header
|
||||
// sheetGen.createRow(0);
|
||||
// sheetGen.getRow(0).createCell(0).setCellValue("Name");
|
||||
// sheetGen.getRow(0).createCell(1).setCellValue("Value");
|
||||
// sheetGen.getRow(0).createCell(2).setCellValue("Date/Time");
|
||||
sheetSummary.setDefaultColumnStyle(1, defaultstyle);
|
||||
|
||||
sheetSummary.createRow(0).setRowStyle(style);
|
||||
sheetSummary.getRow(0).createCell(0).setCellValue("Summary Information");
|
||||
sheetSummary.getRow(0).createCell(1).setCellValue(caseName);
|
||||
|
||||
//add some basic information
|
||||
sheetSummary.createRow(1);
|
||||
sheetSummary.getRow(1).createCell(0).setCellValue("Examiner");
|
||||
sheetSummary.getRow(1).createCell(1).setCellValue(examiner);
|
||||
|
||||
sheetSummary.createRow(2);
|
||||
sheetSummary.getRow(2).createCell(0).setCellValue("Number");
|
||||
sheetSummary.getRow(2).createCell(1).setCellValue(number);
|
||||
|
||||
sheetSummary.createRow(3);
|
||||
sheetSummary.getRow(3).createCell(0).setCellValue("# of Images");
|
||||
sheetSummary.getRow(3).createCell(1).setCellValue(imagecount);
|
||||
|
||||
sheetSummary.createRow(4);
|
||||
sheetSummary.getRow(4).createCell(0).setCellValue("Filesystems found");
|
||||
sheetSummary.getRow(4).createCell(1).setCellValue(filesystemcount);
|
||||
|
||||
sheetSummary.createRow(5);
|
||||
sheetSummary.getRow(5).createCell(0).setCellValue("# of Files");
|
||||
sheetSummary.getRow(5).createCell(1).setCellValue(totalfiles);
|
||||
|
||||
sheetSummary.createRow(6);
|
||||
sheetSummary.getRow(6).createCell(0).setCellValue("# of Directories");
|
||||
sheetSummary.getRow(6).createCell(1).setCellValue(totaldirs);
|
||||
|
||||
sheetSummary.createRow(7);
|
||||
sheetSummary.getRow(7).createCell(0).setCellValue("Date/Time");
|
||||
sheetSummary.getRow(7).createCell(1).setCellValue(datetime);
|
||||
|
||||
|
||||
sheetHash.setDefaultColumnStyle(1, defaultstyle);
|
||||
sheetHash.createRow(0).setRowStyle(style);
|
||||
sheetHash.getRow(0).createCell(0).setCellValue("Name");
|
||||
sheetHash.getRow(0).createCell(1).setCellValue("Size");
|
||||
sheetHash.getRow(0).createCell(2).setCellValue("Hashset Name");
|
||||
sheetHash.getRow(0).createCell(3).setCellValue("Path");
|
||||
|
||||
sheetDevice.setDefaultColumnStyle(1, defaultstyle);
|
||||
sheetDevice.createRow(0).setRowStyle(style);
|
||||
sheetDevice.getRow(0).createCell(0).setCellValue("Name");
|
||||
sheetDevice.getRow(0).createCell(1).setCellValue("Serial #");
|
||||
sheetDevice.getRow(0).createCell(2).setCellValue("Time");
|
||||
sheetDevice.getRow(0).createCell(3).setCellValue("Path");
|
||||
|
||||
sheetInstalled.setDefaultColumnStyle(1, defaultstyle);
|
||||
sheetInstalled.createRow(0).setRowStyle(style);
|
||||
sheetInstalled.getRow(0).createCell(0).setCellValue("Program Name");
|
||||
sheetInstalled.getRow(0).createCell(1).setCellValue("Install Date/Time");
|
||||
sheetInstalled.getRow(0).createCell(2).setCellValue("Path");
|
||||
|
||||
sheetKeyword.setDefaultColumnStyle(1, defaultstyle);
|
||||
sheetKeyword.createRow(0).setRowStyle(style);
|
||||
sheetKeyword.getRow(0).createCell(0).setCellValue("Keyword");
|
||||
sheetKeyword.getRow(0).createCell(1).setCellValue("File Name");
|
||||
sheetKeyword.getRow(0).createCell(2).setCellValue("Preview");
|
||||
sheetKeyword.getRow(0).createCell(3).setCellValue("Keyword List");
|
||||
sheetKeyword.getRow(0).createCell(4).setCellValue("Path");
|
||||
|
||||
sheetRecent.setDefaultColumnStyle(1, defaultstyle);
|
||||
sheetRecent.createRow(0).setRowStyle(style);
|
||||
sheetRecent.getRow(0).createCell(0).setCellValue("Name");
|
||||
sheetRecent.getRow(0).createCell(1).setCellValue("Path");
|
||||
sheetRecent.getRow(0).createCell(2).setCellValue("Related Shortcut");
|
||||
sheetRecent.getRow(0).createCell(4).setCellValue("Path");
|
||||
|
||||
sheetCookie.setDefaultColumnStyle(1, defaultstyle);
|
||||
sheetCookie.createRow(0).setRowStyle(style);
|
||||
sheetCookie.getRow(0).createCell(0).setCellValue("URL");
|
||||
sheetCookie.getRow(0).createCell(1).setCellValue("Date");
|
||||
sheetCookie.getRow(0).createCell(2).setCellValue("Name");
|
||||
sheetCookie.getRow(0).createCell(3).setCellValue("Value");
|
||||
sheetCookie.getRow(0).createCell(4).setCellValue("Program");
|
||||
sheetCookie.getRow(0).createCell(5).setCellValue("Path");
|
||||
|
||||
sheetBookmark.setDefaultColumnStyle(1, defaultstyle);
|
||||
sheetBookmark.createRow(0).setRowStyle(style);
|
||||
sheetBookmark.getRow(0).createCell(0).setCellValue("URL");
|
||||
sheetBookmark.getRow(0).createCell(1).setCellValue("Title");
|
||||
sheetBookmark.getRow(0).createCell(2).setCellValue("Program");
|
||||
sheetBookmark.getRow(0).createCell(4).setCellValue("Path");
|
||||
|
||||
sheetDownload.setDefaultColumnStyle(1, defaultstyle);
|
||||
sheetDownload.createRow(0).setRowStyle(style);
|
||||
sheetDownload.getRow(0).createCell(0).setCellValue("File");
|
||||
sheetDownload.getRow(0).createCell(1).setCellValue("Source");
|
||||
sheetDownload.getRow(0).createCell(2).setCellValue("Time");
|
||||
sheetDownload.getRow(0).createCell(3).setCellValue("Program");
|
||||
sheetDownload.getRow(0).createCell(4).setCellValue("Path");
|
||||
|
||||
sheetHistory.setDefaultColumnStyle(1, defaultstyle);
|
||||
sheetHistory.createRow(0).setRowStyle(style);
|
||||
sheetHistory.getRow(0).createCell(0).setCellValue("URL");
|
||||
sheetHistory.getRow(0).createCell(1).setCellValue("Date");
|
||||
sheetHistory.getRow(0).createCell(2).setCellValue("Referrer");
|
||||
sheetHistory.getRow(0).createCell(3).setCellValue("Title");
|
||||
sheetHistory.getRow(0).createCell(4).setCellValue("Program");
|
||||
sheetHistory.getRow(0).createCell(5).setCellValue("Path");
|
||||
|
||||
sheetEmail.setDefaultColumnStyle(1, defaultstyle);
|
||||
sheetEmail.createRow(0).setRowStyle(style);
|
||||
sheetEmail.getRow(0).createCell(0).setCellValue("From");
|
||||
sheetEmail.getRow(0).createCell(1).setCellValue("To");
|
||||
sheetEmail.getRow(0).createCell(2).setCellValue("Subject");
|
||||
sheetEmail.getRow(0).createCell(3).setCellValue("Date/Time");
|
||||
sheetEmail.getRow(0).createCell(4).setCellValue("Content");
|
||||
sheetEmail.getRow(0).createCell(5).setCellValue("CC");
|
||||
sheetEmail.getRow(0).createCell(6).setCellValue("BCC");
|
||||
sheetEmail.getRow(0).createCell(7).setCellValue("Path");
|
||||
|
||||
sheetWebSearch.setDefaultColumnStyle(1, defaultstyle);
|
||||
sheetWebSearch.createRow(0).setRowStyle(style);
|
||||
sheetWebSearch.getRow(0).createCell(0).setCellValue("Program");
|
||||
sheetWebSearch.getRow(0).createCell(1).setCellValue("Domain");
|
||||
sheetWebSearch.getRow(0).createCell(2).setCellValue("Text");
|
||||
sheetWebSearch.getRow(0).createCell(3).setCellValue("Last Accesed");
|
||||
sheetWebSearch.getRow(0).createCell(4).setCellValue("Path");
|
||||
|
||||
sheetExif.setDefaultColumnStyle(1, defaultstyle);
|
||||
sheetExif.createRow(0).setRowStyle(style);
|
||||
sheetExif.getRow(0).createCell(0).setCellValue("File Name");
|
||||
sheetExif.getRow(0).createCell(1).setCellValue("Date Taken");
|
||||
sheetExif.getRow(0).createCell(2).setCellValue("Device Manufacturer");
|
||||
sheetExif.getRow(0).createCell(3).setCellValue("Device Model");
|
||||
sheetExif.getRow(0).createCell(4).setCellValue("Latitude");
|
||||
sheetExif.getRow(0).createCell(5).setCellValue("Longitude");
|
||||
sheetExif.getRow(0).createCell(6).setCellValue("Altitude");
|
||||
sheetExif.getRow(0).createCell(7).setCellValue("Path");
|
||||
|
||||
sheetTagFile.setDefaultColumnStyle(1, defaultstyle);
|
||||
sheetTagFile.createRow(0).setRowStyle(style);
|
||||
sheetTagFile.getRow(0).createCell(0).setCellValue("Comment");
|
||||
sheetTagFile.getRow(0).createCell(1).setCellValue("File Name");
|
||||
sheetTagFile.getRow(0).createCell(2).setCellValue("Path");
|
||||
|
||||
for (int i = 0; i < wbtemp.getNumberOfSheets(); i++) {
|
||||
Sheet tempsheet = wbtemp.getSheetAt(i);
|
||||
tempsheet.setAutobreaks(true);
|
||||
|
||||
for (Row temprow : tempsheet) {
|
||||
for (Cell cell : temprow) {
|
||||
cell.setCellStyle(style);
|
||||
tempsheet.autoSizeColumn(cell.getColumnIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int countedGen = 0;
|
||||
int countedBookmark = 0;
|
||||
int countedCookie = 0;
|
||||
int countedHistory = 0;
|
||||
int countedDownload = 0;
|
||||
int countedRecentObjects = 0;
|
||||
int countedTrackPoint = 0;
|
||||
int countedInstalled = 0;
|
||||
int countedKeyword = 0;
|
||||
int countedHash = 0;
|
||||
int countedDevice = 0;
|
||||
int countedEmail = 0;
|
||||
int countedWebSearch = 0;
|
||||
int countedExif = 0;
|
||||
int countedTagFile = 0;
|
||||
|
||||
//start populating the sheets in the workbook
|
||||
for (Entry<BlackboardArtifact, List<BlackboardAttribute>> entry : report.entrySet()) {
|
||||
if (ReportFilter.cancel == true) {
|
||||
break;
|
||||
}
|
||||
int cc = 0;
|
||||
Long objId = entry.getKey().getObjectID();
|
||||
AbstractFile file = skCase.getAbstractFileById(objId);
|
||||
String filename = file.getName();
|
||||
Long filesize = file.getSize();
|
||||
TreeMap<Integer, String> attributes = new TreeMap<Integer, String>();
|
||||
// Get all the attributes, line them up to be added. Place empty string placeholders for each attribute type
|
||||
int n;
|
||||
for (n = 1; n <= 36; n++) {
|
||||
attributes.put(n, "");
|
||||
|
||||
}
|
||||
for (BlackboardAttribute tempatt : entry.getValue()) {
|
||||
if (ReportFilter.cancel == true) {
|
||||
break;
|
||||
}
|
||||
String value = "";
|
||||
int type = tempatt.getAttributeTypeID();
|
||||
if (tempatt.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD.getTypeID() || tempatt.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID() || tempatt.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()) {
|
||||
value = new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new java.util.Date((tempatt.getValueLong()) * 1000)).toString();
|
||||
} else {
|
||||
value = tempatt.getValueString();
|
||||
}
|
||||
|
||||
// attributes.put(type, StringEscapeUtils.escapeCsv(value));
|
||||
attributes.put(type, value);
|
||||
cc++;
|
||||
}
|
||||
|
||||
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID()) {
|
||||
countedGen++;
|
||||
// Row temp = sheetGen.getRow(countedGen);
|
||||
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()) {
|
||||
countedBookmark++;
|
||||
Row temp = sheetBookmark.createRow(countedBookmark);
|
||||
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
|
||||
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
|
||||
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
|
||||
temp.createCell(3).setCellValue(file.getUniquePath());
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()) {
|
||||
countedCookie++;
|
||||
Row temp = sheetCookie.createRow(countedCookie);
|
||||
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
|
||||
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
|
||||
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
|
||||
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE.getTypeID()));
|
||||
temp.createCell(4).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
|
||||
temp.createCell(5).setCellValue(file.getUniquePath());
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) {
|
||||
countedHistory++;
|
||||
Row temp = sheetHistory.createRow(countedHistory);
|
||||
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
|
||||
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
|
||||
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID()));
|
||||
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
|
||||
temp.createCell(4).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
|
||||
temp.createCell(5).setCellValue(file.getUniquePath());
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()) {
|
||||
countedDownload++;
|
||||
Row temp = sheetDownload.createRow(countedDownload);
|
||||
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID()));
|
||||
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
|
||||
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
|
||||
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
|
||||
temp.createCell(4).setCellValue(file.getUniquePath());
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID()) {
|
||||
countedRecentObjects++;
|
||||
Row temp = sheetRecent.createRow(countedRecentObjects);
|
||||
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
|
||||
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID()));
|
||||
temp.createCell(2).setCellValue(file.getName());
|
||||
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
|
||||
temp.createCell(4).setCellValue(file.getUniquePath());
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TRACKPOINT.getTypeID()) {
|
||||
// sheetTrackpoint.addContent(artifact);
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) {
|
||||
countedInstalled++;
|
||||
Row temp = sheetInstalled.createRow(countedInstalled);
|
||||
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
|
||||
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
|
||||
temp.createCell(2).setCellValue(file.getUniquePath());
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
|
||||
countedKeyword++;
|
||||
Row temp = sheetKeyword.createRow(countedKeyword);
|
||||
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()));
|
||||
temp.createCell(1).setCellValue(filename);
|
||||
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID()));
|
||||
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()));
|
||||
temp.createCell(4).setCellValue(file.getUniquePath());
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) {
|
||||
countedHash++;
|
||||
Row temp = sheetHash.createRow(countedHash);
|
||||
temp.createCell(0).setCellValue(file.getName().toString());
|
||||
temp.createCell(1).setCellValue(filesize.toString());
|
||||
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()));
|
||||
temp.createCell(3).setCellValue(file.getUniquePath());
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) {
|
||||
countedDevice++;
|
||||
Row temp = sheetDevice.createRow(countedDevice);
|
||||
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID()));
|
||||
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID.getTypeID()));
|
||||
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
|
||||
temp.createCell(3).setCellValue(file.getUniquePath());
|
||||
}
|
||||
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
|
||||
countedEmail++;
|
||||
Row temp = sheetEmail.createRow(countedEmail);
|
||||
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM.getTypeID()));
|
||||
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO.getTypeID()));
|
||||
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT.getTypeID()));
|
||||
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD.getTypeID()));
|
||||
temp.createCell(4).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN.getTypeID()));
|
||||
temp.createCell(5).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC.getTypeID()));
|
||||
temp.createCell(6).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_BCC.getTypeID()));
|
||||
temp.createCell(7).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID()));
|
||||
temp.createCell(8).setCellValue(file.getUniquePath());
|
||||
}
|
||||
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
|
||||
countedWebSearch++;
|
||||
Row temp = sheetWebSearch.createRow(countedWebSearch);
|
||||
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
|
||||
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID()));
|
||||
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT.getTypeID()));
|
||||
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
|
||||
temp.createCell(4).setCellValue(file.getUniquePath());
|
||||
}
|
||||
if(entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID()){
|
||||
countedExif++;
|
||||
Row temp = sheetExif.createRow(countedExif);
|
||||
temp.createCell(0).setCellValue(file.getName());
|
||||
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
|
||||
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE.getTypeID()));
|
||||
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID()));
|
||||
temp.createCell(4).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()));
|
||||
temp.createCell(5).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()));
|
||||
temp.createCell(6).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE.getTypeID()));
|
||||
temp.createCell(7).setCellValue(file.getUniquePath());
|
||||
}
|
||||
if(entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()){
|
||||
countedTagFile++;
|
||||
Row temp = sheetTagFile.createRow(countedTagFile);
|
||||
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID()));
|
||||
temp.createCell(1).setCellValue(file.getName());
|
||||
temp.createCell(2).setCellValue(file.getUniquePath());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//write out the report to the reports folder, set the wbtemp to the primary wb object
|
||||
wb = wbtemp;
|
||||
xlsPath = currentCase.getCaseDirectory() + File.separator + "Reports" + File.separator + caseName + "-" + datenotime + ".xlsx";
|
||||
this.save(xlsPath);
|
||||
|
||||
} catch (TskCoreException tce) {
|
||||
logger.log(Level.WARNING, "Could not create XLS report", tce);
|
||||
}
|
||||
|
||||
return xlsPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(String path) {
|
||||
try {
|
||||
FileOutputStream fos = new FileOutputStream(path);
|
||||
wb.write(fos);
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.WARNING, "Could not write out XLS report!", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
String name = "Excel";
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReportType() {
|
||||
String type = "XLS";
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtension() {
|
||||
String ext = ".xlsx";
|
||||
return ext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReportConfiguration GetReportConfiguration() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReportTypeDescription() {
|
||||
String desc = "This is an xls formatted report that is meant to be viewed in Excel.";
|
||||
return desc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPreview(String path) {
|
||||
File file = new File(path);
|
||||
try {
|
||||
Desktop.getDesktop().open(file);
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.WARNING, "Could not open XLS report! ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,314 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 Basis Technology Corp.
|
||||
*
|
||||
* Copyright 2012 42six Solutions.
|
||||
* Contact: aebadirad <at> 42six <dot> com
|
||||
* Project Contact/Architect: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.report;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.XMLUtil;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.datamodel.*;
|
||||
import org.w3c.dom.Comment;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Generates an XML report for all the Blackboard Artifacts found in the current case.
|
||||
*/
|
||||
public class ReportXML implements ReportModule {
|
||||
|
||||
public static Document xmldoc;
|
||||
private ReportConfiguration reportconfig;
|
||||
private String xmlPath;
|
||||
private static ReportXML instance = null;
|
||||
private static final Logger logger = Logger.getLogger(ReportXML.class.getName());
|
||||
|
||||
|
||||
public ReportXML() {
|
||||
}
|
||||
|
||||
public static synchronized ReportXML getDefault() {
|
||||
if (instance == null) {
|
||||
instance = new ReportXML();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateReport(ReportConfiguration reportconfig) throws ReportModuleException {
|
||||
ReportGen reportobj = new ReportGen();
|
||||
reportobj.populateReport(reportconfig);
|
||||
HashMap<BlackboardArtifact, List<BlackboardAttribute>> report = reportobj.getResults();
|
||||
try {
|
||||
Case currentCase = Case.getCurrentCase(); // get the most updated case
|
||||
SleuthkitCase skCase = currentCase.getSleuthkitCase();
|
||||
String caseName = currentCase.getName();
|
||||
String examiner = currentCase.getExaminer();
|
||||
String number = currentCase.getNumber();
|
||||
Integer imagecount = currentCase.getImageIDs().length;
|
||||
Integer filesystemcount = currentCase.getRootObjectsCount();
|
||||
Integer totalfiles = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG);
|
||||
Integer totaldirs = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR);
|
||||
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
Document ret = builder.newDocument();
|
||||
Element root = ret.createElement("Case");
|
||||
DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
||||
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
|
||||
Date date = new Date();
|
||||
String datetime = datetimeFormat.format(date);
|
||||
String datenotime = dateFormat.format(date);
|
||||
Comment comment = ret.createComment("XML Report Generated by Autopsy 3 on " + datetime);
|
||||
root.appendChild(comment);
|
||||
//Create summary node involving how many of each type
|
||||
Element summary = ret.createElement("Summary");
|
||||
if (IngestManager.getDefault().isIngestRunning()) {
|
||||
Element warning = ret.createElement("Warning");
|
||||
warning.setTextContent("Report was run before ingest services completed!");
|
||||
summary.appendChild(warning);
|
||||
}
|
||||
Element name = ret.createElement("Name");
|
||||
name.setTextContent(caseName);
|
||||
summary.appendChild(name);
|
||||
|
||||
Element texaminer = ret.createElement("Examiner");
|
||||
texaminer.setTextContent(examiner);
|
||||
summary.appendChild(texaminer);
|
||||
|
||||
Element tnumber = ret.createElement("Number");
|
||||
tnumber.setTextContent(number);
|
||||
summary.appendChild(tnumber);
|
||||
|
||||
Element timages = ret.createElement("Total-Images");
|
||||
timages.setTextContent(imagecount.toString());
|
||||
summary.appendChild(timages);
|
||||
|
||||
Element tfilesys = ret.createElement("Total-FileSystems");
|
||||
tfilesys.setTextContent(filesystemcount.toString());
|
||||
summary.appendChild(tfilesys);
|
||||
|
||||
Element tfiles = ret.createElement("Total-Files");
|
||||
tfiles.setTextContent(totalfiles.toString());
|
||||
summary.appendChild(tfiles);
|
||||
|
||||
Element tdir = ret.createElement("Total-Directories");
|
||||
tdir.setTextContent(totaldirs.toString());
|
||||
summary.appendChild(tdir);
|
||||
|
||||
root.appendChild(summary);
|
||||
//generate the nodes for each of the types so we can use them later
|
||||
|
||||
Element nodeGen = ret.createElement("General-Information");
|
||||
Element nodeWebBookmark = ret.createElement("Web-Bookmarks");
|
||||
Element nodeWebCookie = ret.createElement("Web-Cookies");
|
||||
Element nodeWebHistory = ret.createElement("Web-History");
|
||||
Element nodeWebDownload = ret.createElement("Web-Downloads");
|
||||
Element nodeRecentObjects =ret.createElement("Recent-Documents");
|
||||
Element nodeTrackPoint = ret.createElement("Track-Points");
|
||||
Element nodeInstalled = ret.createElement("Installed-Programfiles");
|
||||
Element nodeKeyword = ret.createElement("Keyword-Search-Hits");
|
||||
Element nodeHash = ret.createElement("Hashset-Hits");
|
||||
Element nodeDevice = ret.createElement("Attached-Devices");
|
||||
Element nodeEmail = ret.createElement("Email-Messages");
|
||||
Element nodeWebSearch = ret.createElement("Web-Search-Queries");
|
||||
Element nodeExif = ret.createElement("Exif-Metadata");
|
||||
Element nodeTagFile = ret.createElement("File-Tags");
|
||||
|
||||
//remove bytes
|
||||
Pattern INVALID_XML_CHARS = Pattern.compile("[^\\u0009\\u000A\\u000D\\u0020-\\uD7FF\\uE000-\\uFFFD\uD800\uDC00-\uDBFF\uDFFF]");
|
||||
for (Entry<BlackboardArtifact, List<BlackboardAttribute>> entry : report.entrySet()) {
|
||||
if (ReportFilter.cancel == true) {
|
||||
break;
|
||||
}
|
||||
int cc = 0;
|
||||
Element artifact = ret.createElement("Artifact");
|
||||
Long objId = entry.getKey().getObjectID();
|
||||
Content cont = skCase.getContentById(objId);
|
||||
Long filesize = cont.getSize();
|
||||
try {
|
||||
artifact.setAttribute("ID", objId.toString());
|
||||
artifact.setAttribute("Name", cont.getName());
|
||||
artifact.setAttribute("Size", filesize.toString());
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Visitor content exception occurred:", e);
|
||||
}
|
||||
// Get all the attributes for this guy
|
||||
for (BlackboardAttribute tempatt : entry.getValue()) {
|
||||
if (ReportFilter.cancel == true) {
|
||||
break;
|
||||
}
|
||||
Element attribute = ret.createElement("Attribute");
|
||||
attribute.setAttribute("Type", tempatt.getAttributeTypeDisplayName());
|
||||
String tempvalue = tempatt.getValueString();
|
||||
//INVALID_XML_CHARS.matcher(tempvalue).replaceAll("");
|
||||
Element value = ret.createElement("Value");
|
||||
value.setTextContent(tempvalue);
|
||||
Element context = ret.createElement("Context");
|
||||
context.setTextContent(tempatt.getContext());
|
||||
Element path = ret.createElement("Path");
|
||||
String pathStr = skCase.getAbstractFileById(entry.getKey().getObjectID()).getUniquePath();
|
||||
path.setTextContent(pathStr);
|
||||
attribute.appendChild(value);
|
||||
attribute.appendChild(context);
|
||||
artifact.appendChild(attribute);
|
||||
artifact.appendChild(path);
|
||||
cc++;
|
||||
}
|
||||
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID()) {
|
||||
nodeGen.appendChild(artifact);
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()) {
|
||||
nodeWebBookmark.appendChild(artifact);
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()) {
|
||||
nodeWebCookie.appendChild(artifact);
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) {
|
||||
|
||||
nodeWebHistory.appendChild(artifact);
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()) {
|
||||
nodeWebDownload.appendChild(artifact);
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID()) {
|
||||
nodeRecentObjects.appendChild(artifact);
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TRACKPOINT.getTypeID()) {
|
||||
nodeTrackPoint.appendChild(artifact);
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) {
|
||||
nodeInstalled.appendChild(artifact);
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
|
||||
nodeKeyword.appendChild(artifact);
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) {
|
||||
nodeHash.appendChild(artifact);
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) {
|
||||
nodeDevice.appendChild(artifact);
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
|
||||
nodeEmail.appendChild(artifact);
|
||||
}
|
||||
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
|
||||
nodeWebSearch.appendChild(artifact);
|
||||
}
|
||||
if(entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID()){
|
||||
nodeExif.appendChild(artifact);
|
||||
}
|
||||
if(entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()){
|
||||
nodeTagFile.appendChild(artifact);
|
||||
}
|
||||
|
||||
|
||||
//end of master loop
|
||||
}
|
||||
|
||||
//add them in the order we want them to the document
|
||||
root.appendChild(nodeGen);
|
||||
root.appendChild(nodeWebBookmark);
|
||||
root.appendChild(nodeWebCookie);
|
||||
root.appendChild(nodeWebHistory);
|
||||
root.appendChild(nodeWebDownload);
|
||||
root.appendChild(nodeRecentObjects);
|
||||
root.appendChild(nodeTrackPoint);
|
||||
root.appendChild(nodeInstalled);
|
||||
root.appendChild(nodeKeyword);
|
||||
root.appendChild(nodeHash);
|
||||
root.appendChild(nodeDevice);
|
||||
root.appendChild(nodeEmail);
|
||||
root.appendChild(nodeWebSearch);
|
||||
root.appendChild(nodeExif);
|
||||
root.appendChild(nodeTagFile);
|
||||
|
||||
ret.appendChild(root);
|
||||
xmldoc = ret;
|
||||
|
||||
//Export it the first time
|
||||
xmlPath = currentCase.getCaseDirectory() + File.separator + "Reports" + File.separator + caseName + "-" + datenotime + ".xml";
|
||||
this.save(xmlPath);
|
||||
|
||||
} catch (TskCoreException tce) {
|
||||
logger.log(Level.WARNING, "Exception occurred", tce);
|
||||
}
|
||||
catch(ParserConfigurationException pce){
|
||||
logger.log(Level.WARNING, "Could not create XML parser", pce);
|
||||
}
|
||||
|
||||
return xmlPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(String path) {
|
||||
XMLUtil.saveDoc(ReportXML.class, xmlPath, "UTF-8", xmldoc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
String name = "Default XML";
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReportType() {
|
||||
String type = "XML";
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtension() {
|
||||
String ext = ".xml";
|
||||
return ext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReportConfiguration GetReportConfiguration() {
|
||||
ReportConfiguration config = reportconfig;
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPreview(String path) {
|
||||
BrowserControl.openUrl(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReportTypeDescription() {
|
||||
String desc = "This is an xml formatted report that is meant to be viewed in a modern browser.";
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 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.report;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ReportModule that implements a tabular style of reporting.
|
||||
*
|
||||
* All TableReportModules will be sent the exact data to report, and will only
|
||||
* have to determine how to write and display this data.
|
||||
*
|
||||
* The data sent consists of user-chosen fields such as Blackboard Artifacts
|
||||
* and File/Result Tags.
|
||||
*/
|
||||
public interface TableReportModule extends ReportModule {
|
||||
|
||||
/**
|
||||
* Start the report. Open any output streams, initialize member variables,
|
||||
* write summary and navigation pages. Considered the "constructor" of the report.
|
||||
*
|
||||
* @param path String path to save the report
|
||||
*/
|
||||
public void startReport(String path);
|
||||
|
||||
/**
|
||||
* End the report. Close all output streams and write any end-of-report
|
||||
* files.
|
||||
*/
|
||||
public void endReport();
|
||||
|
||||
/**
|
||||
* Start a new data type for the report. This is how the report will differentiate between
|
||||
* the start and end of a certain type of data, such as a Blackboard Artifact Type.
|
||||
* It is up to the report how the differentiation is shown.
|
||||
*
|
||||
* @param title String name of the data type
|
||||
*/
|
||||
public void startDataType(String title);
|
||||
|
||||
/**
|
||||
* End the current data type and prepare for either the end of the report
|
||||
* or the start of a new data type.
|
||||
*/
|
||||
public void endDataType();
|
||||
|
||||
/**
|
||||
* Start a new set, or sub-category, for the current data type.
|
||||
*
|
||||
* @param setName String name of the set
|
||||
*/
|
||||
public void startSet(String setName);
|
||||
|
||||
/**
|
||||
* End the current set and prepare for either the end of the current data type
|
||||
* or the start of a new set.
|
||||
*/
|
||||
public void endSet();
|
||||
|
||||
/**
|
||||
* Add an index of all the sets to the report's current data type. This method
|
||||
* is guaranteed to be called before any sets are added to the data type,
|
||||
* and may be ignored.
|
||||
*
|
||||
* @param sets List of all the String set names
|
||||
*/
|
||||
public void addSetIndex(List<String> sets);
|
||||
|
||||
/**
|
||||
* Add an element to the current set. An element is considered the 'title' of a
|
||||
* table in a set, a sub-set in a sense.
|
||||
*
|
||||
* @param elementName String name of element
|
||||
*/
|
||||
public void addSetElement(String elementName);
|
||||
|
||||
/**
|
||||
* Create a table with the column names given.
|
||||
*
|
||||
* @param titles List of String column names
|
||||
*/
|
||||
public void startTable(List<String> titles);
|
||||
|
||||
/**
|
||||
* End the current table.
|
||||
*/
|
||||
public void endTable();
|
||||
|
||||
/**
|
||||
* Add a row with the cell values given to the current table.
|
||||
*
|
||||
* @param row List of String cell values
|
||||
*/
|
||||
public void addRow(List<String> row);
|
||||
|
||||
/**
|
||||
* Returns a String date, created by the module. All date values will query
|
||||
* the module for it's interpretation of the date before sending it a row
|
||||
* with the date value.
|
||||
*
|
||||
* @param date long date as long
|
||||
* @return String date as String
|
||||
*/
|
||||
public String dateToString(long date);
|
||||
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 662 B After Width: | Height: | Size: 662 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 672 B After Width: | Height: | Size: 672 B |
|
Before Width: | Height: | Size: 284 KiB After Width: | Height: | Size: 284 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 877 B |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 634 B |
|
After Width: | Height: | Size: 577 B |
|
Before Width: | Height: | Size: 783 B After Width: | Height: | Size: 783 B |
|
Before Width: | Height: | Size: 290 B After Width: | Height: | Size: 290 B |
|
Before Width: | Height: | Size: 559 B After Width: | Height: | Size: 559 B |
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
\package org.sleuthkit.autopsy.report
|
||||
|
||||
This package provides the reporting framework. Reporting modules allow you to get output from Autopsy in the form of XML, HTML, etc.
|
||||
This package provides the reporting framework. Reporting modules allow you to get output from Autopsy in the form of an HTML webpage, an Excel document, etc.
|
||||
|
||||
Refer to \ref mod_report_page for details on building a report module.
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
---------------- VERSION Current (dev) --------------
|
||||
New features:
|
||||
- Documented report module API
|
||||
|
||||
|
||||
Improvements:
|
||||
- Remake of reporting UI and functionality
|
||||
- Significant increase in reporting speed
|
||||
|
||||
|
||||
Bugfixes:
|
||||
|
||||
@@ -1,12 +1,82 @@
|
||||
/*! \page mod_report_page Developing Report Modules
|
||||
|
||||
\section report_summary Summary
|
||||
There are two types of reporting modules: table report modules and general report modules.
|
||||
|
||||
<!-- @@@ Cleanup -->
|
||||
Each reporting submodule implements org.sleuthkit.autopsy.report.ReportModule interface and registers itself in layer.xml
|
||||
Each reporting submodule implements either the org.sleuthkit.autopsy.report.TableReportModule interface or the org.sleuthkit.autopsy.report.GeneralReportModule interface, and registers itself in layer.xml
|
||||
|
||||
Reporting submodule typically interacts with 3 components:
|
||||
- org.sleuthkit.autopsy.report.ReportConfiguration - to read current reporting configuration set by the user,
|
||||
- Blackboard API in org.sleuthkit.datamodel.SleuthkitCase class - to traverse and read blackboard artifacts and attributes,
|
||||
- an API (possibly external/thirdparty API) to convert blackboard artifacts data structures to the desired reporting format.
|
||||
Implementing either of those interfaces will require the reporting module to implement a number of abstract methods. And depending on the type of report module, different methods will be invoked by the application.
|
||||
|
||||
Table report modules require their sub-classes to override methods to start and end tables, and add rows to those tables. These methods are provided data, generated from a default configuration panel, for the module to report on. Because of this, when creating a table report module one only needs to focus on how to display the data, not how to find it.
|
||||
|
||||
On the other hand, general report modules have a single method to generate the report. This method gives the module freedom to find and process any data it so chooses. General modules also have the ability to provide a configuration panel, allowing the user to choose from various displayed settings. The report module may then use the user's selection to generate a more specific report.
|
||||
|
||||
General modules are also given the responsibility of updating their report's progress bar and processing label in the UI. A progress panel is given to every general report module. It contains basic API to start, stop, and add to the progress bar, as well as update the processing label. The module is also expeted to check the progress bar's status occasionally to see if the user has manually canceled the report.
|
||||
|
||||
\section report_create_module Creating a Report Module
|
||||
To create a table report module, start off by creating a class and implementing either the TableReportModule interface or the GeneralReportModule interface.
|
||||
|
||||
\subsection report_create_module_table Table Report Modules
|
||||
If you implement TableReportModule, you should override the methods:
|
||||
- org.sleuthkit.autopsy.report.TableReportModule::startReport(String path)
|
||||
- org.sleuthkit.autopsy.report.TableReportModule::endReport()
|
||||
- org.sleuthkit.autopsy.report.TableReportModule::startDataType(String title)
|
||||
- org.sleuthkit.autopsy.report.TableReportModule::endDataType()
|
||||
- org.sleuthkit.autopsy.report.TableReportModule::startSet(String setName)
|
||||
- org.sleuthkit.autopsy.report.TableReportModule::endSet()
|
||||
- org.sleuthkit.autopsy.report.TableReportModule::addSetIndex(List<String> sets)
|
||||
- org.sleuthkit.autopsy.report.TableReportModule::addSetElement(String elementName)
|
||||
- org.sleuthkit.autopsy.report.TableReportModule::startTable(List<String> titles)
|
||||
- org.sleuthkit.autopsy.report.TableReportModule::endTable()
|
||||
- org.sleuthkit.autopsy.report.TableReportModule::addRow(List<String> row)
|
||||
- org.sleuthkit.autopsy.report.TableReportModule::dateToString(long date)
|
||||
|
||||
When generating table module reports, Autopsy will iterate through a list of user selected data, and call methods such as addRow(List<String> row) for every "row" of data it finds, or startTable(List<String> titles) for every new category it finds. Developers are guarenteed that every start of a data type, set, or table will be followed by an approptiate end. The focus for a table report module should be to take the given information and display it in a user friendly format. See org.sleuthkit.autopsy.report.ReportExcel for an example.
|
||||
|
||||
\subsection report_create_module_general General Report Modules
|
||||
If you implement GeneralReportModule, the overriden methods will be:
|
||||
- org.sleuthkit.autopsy.report.GeneralReportModule::generateReport(String reportPath, ReportProgressPanel progressPanel)
|
||||
- org.sleuthkit.autopsy.report.GeneralReportModule::getConfigurationPanel()
|
||||
|
||||
For general report modules, Autopsy will simply call the generateReport(String reportPath, ReportProgressPanel progressPanel) method and leave it up to the module to aquire and report data in its desired format. The only requirements are that the module saves to the given report path and updates the org.sleuthkit.autopsy.report.ReportProgressPanel as the report progresses.
|
||||
|
||||
When updating the progress panel, it is recommened to update it as infrequently as possible, while still keeping the user informed. If your report processes 100,000 files and you chose to update the UI each time a file is reviewed, the UI would freeze when trying to process all your requests. This would cause problems to not only your reporting module, but to other modules running in parellel. A safer approach would be to update the UI every 1,000 files, or when a certain "category" of the files being processed has changed. For example, the HTML report module increments the progress bar and changes the processing label every time a new Blackboard Artifact Type is being processed.
|
||||
|
||||
Autopsy will also display the panel returned by getConfigurationPanel() in the generate report wizard, when that particular report module is selected. If null is returned, a blank panel will be displayed instead. This panel can be used to allow the user custom controls over the report.
|
||||
|
||||
Typically a general report module should interact with both the Blackboard API in the org.sleuthkit.datamodel.SleuthkitCase class, in addition to an API (possibly external/thirdparty) to convert Blackboard Artifacts to the desired reporting format.
|
||||
|
||||
\subsection report_create_module_layer Registering the Report in layer.xml
|
||||
Lastly, it is important to register each report module, regardless of the type, to a layer.xml file. This file serves as a globally excessible instance of the report module, and allows all report modules to be recognized abstractly without knowing each class. Without this file, Autopsy will be unable to see your report module.
|
||||
|
||||
An example entry into layer.xml is shown below:
|
||||
\code
|
||||
<folder name="Services">
|
||||
<file name="org-sleuthkit-autopsy-report-ReportHTML.instance">
|
||||
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.TableReportModule"/>
|
||||
<attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.report.ReportHTML.getDefault"/>
|
||||
<attr name="position" intvalue="910"/>
|
||||
</file>
|
||||
</folder>
|
||||
\endcode
|
||||
|
||||
In the above example, "org-sleuthkit-autopsy-report-ReportHTML" should be replaced with the package based path to your report module.
|
||||
|
||||
It is also important to remember to include a getDefault() method in your report module. As shown in the code above, the instance to each report module is accessed via it's getDefault() method.
|
||||
|
||||
\code
|
||||
// Static instance of this report
|
||||
private static MyReport instance;
|
||||
|
||||
// Get the default instance of this report
|
||||
public static synchronized MyReport getDefault() {
|
||||
if (instance == null) {
|
||||
instance = new MyReport();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
\endcode
|
||||
|
||||
Above is an example implementation of the getDefault() method.
|
||||
|
||||
*/
|
||||
|
||||