Merge pull request #349 from jawallace/ewfVerifyIngest

Ewf verify ingest
This commit is contained in:
Richard Cordovano 2013-12-18 07:34:14 -08:00
commit 94ededd14e
15 changed files with 769 additions and 219 deletions

View File

@ -47,3 +47,7 @@ ImageDetailsPanel.imgSectorSizeLabel.text=Sector Size:
ImageDetailsPanel.imgSectorSizeValue.text=... ImageDetailsPanel.imgSectorSizeValue.text=...
DirectoryTreeTopComponent.backButton.text= DirectoryTreeTopComponent.backButton.text=
DirectoryTreeTopComponent.forwardButton.text= DirectoryTreeTopComponent.forwardButton.text=
ImageDetailsPanel.imgTotalSizeValue.text=...
ImageDetailsPanel.imgTotalSizeLabel.text=Total Size:
ImageDetailsPanel.imgHashValue.text=...
ImageDetailsPanel.imgHashLabel.text=Hash Value:

View File

@ -1,159 +1,159 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 Basis Technology Corp. * Copyright 2011 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.sleuthkit.autopsy.directorytree; package org.sleuthkit.autopsy.directorytree;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
import javax.swing.Action; import javax.swing.Action;
import org.openide.nodes.FilterNode; import org.openide.nodes.FilterNode;
import org.openide.nodes.Node; import org.openide.nodes.Node;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
import org.openide.util.lookup.ProxyLookup; import org.openide.util.lookup.ProxyLookup;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.AbstractContentNode; import org.sleuthkit.autopsy.datamodel.AbstractContentNode;
import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
import org.sleuthkit.autopsy.ingest.IngestDialog; import org.sleuthkit.autopsy.ingest.IngestDialog;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.Directory; import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
/** /**
* This class sets the actions for the nodes in the directory tree and creates * This class sets the actions for the nodes in the directory tree and creates
* the children filter so that files and such are hidden from the tree. * the children filter so that files and such are hidden from the tree.
* *
*/ */
class DirectoryTreeFilterNode extends FilterNode { class DirectoryTreeFilterNode extends FilterNode {
private static final Action collapseAll = new CollapseAction("Collapse All"); private static final Action collapseAll = new CollapseAction("Collapse All");
private static final Logger logger = Logger.getLogger(DirectoryTreeFilterNode.class.getName()); private static final Logger logger = Logger.getLogger(DirectoryTreeFilterNode.class.getName());
/** /**
* the constructor * the constructor
*/ */
DirectoryTreeFilterNode(Node arg, boolean createChildren) { DirectoryTreeFilterNode(Node arg, boolean createChildren) {
super(arg, DirectoryTreeFilterChildren.createInstance(arg, createChildren), super(arg, DirectoryTreeFilterChildren.createInstance(arg, createChildren),
new ProxyLookup(Lookups.singleton(new OriginalNode(arg)), new ProxyLookup(Lookups.singleton(new OriginalNode(arg)),
arg.getLookup())); arg.getLookup()));
} }
@Override @Override
public String getDisplayName() { public String getDisplayName() {
final Node orig = getOriginal(); final Node orig = getOriginal();
String name = orig.getDisplayName(); String name = orig.getDisplayName();
//do not show children counts for non content nodes //do not show children counts for non content nodes
if (orig instanceof AbstractContentNode) { if (orig instanceof AbstractContentNode) {
//show only for file content nodes //show only for file content nodes
AbstractFile file = getLookup().lookup(AbstractFile.class); AbstractFile file = getLookup().lookup(AbstractFile.class);
if (file != null) { if (file != null) {
try { try {
final int numChildren = file.getChildrenCount(); final int numChildren = file.getChildrenCount();
name = name + " (" + numChildren + ")"; name = name + " (" + numChildren + ")";
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error getting children count to display for file: " + file, ex); logger.log(Level.SEVERE, "Error getting children count to display for file: " + file, ex);
} }
} }
} }
return name; return name;
} }
/** /**
* Right click action for the nodes in the directory tree. * Right click action for the nodes in the directory tree.
* *
* @param popup * @param popup
* @return * @return
*/ */
@Override @Override
public Action[] getActions(boolean popup) { public Action[] getActions(boolean popup) {
List<Action> actions = new ArrayList<Action>(); List<Action> actions = new ArrayList<Action>();
final Content content = this.getLookup().lookup(Content.class); final Content content = this.getLookup().lookup(Content.class);
if (content != null) { if (content != null) {
actions.addAll(DirectoryTreeFilterNode.getDetailActions(content)); actions.addAll(DirectoryTreeFilterNode.getDetailActions(content));
//extract dir action //extract dir action
Directory dir = this.getLookup().lookup(Directory.class); Directory dir = this.getLookup().lookup(Directory.class);
if (dir != null) { if (dir != null) {
actions.add(ExtractAction.getInstance()); actions.add(ExtractAction.getInstance());
} }
// file search action // file search action
final Image img = this.getLookup().lookup(Image.class); final Image img = this.getLookup().lookup(Image.class);
if (img != null) { if (img != null) {
actions.add(new FileSearchAction("Open File Search by Attributes")); actions.add(new FileSearchAction("Open File Search by Attributes"));
} }
//ingest action //ingest action
actions.add(new AbstractAction("Run Ingest Modules") { actions.add(new AbstractAction("Run Ingest Modules") {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
final IngestDialog ingestDialog = new IngestDialog(); final IngestDialog ingestDialog = new IngestDialog();
ingestDialog.setContent(Collections.<Content>singletonList(content)); ingestDialog.setContent(Collections.<Content>singletonList(content));
ingestDialog.display(); ingestDialog.display();
} }
}); });
} }
//check if delete actions should be added //check if delete actions should be added
final Node orig = getOriginal(); final Node orig = getOriginal();
//TODO add a mechanism to determine if DisplayableItemNode //TODO add a mechanism to determine if DisplayableItemNode
if (orig instanceof DisplayableItemNode) { if (orig instanceof DisplayableItemNode) {
actions.addAll(getDeleteActions((DisplayableItemNode) orig)); actions.addAll(getDeleteActions((DisplayableItemNode) orig));
} }
actions.add(collapseAll); actions.add(collapseAll);
return actions.toArray(new Action[actions.size()]); return actions.toArray(new Action[actions.size()]);
} }
private static List<Action> getDeleteActions(DisplayableItemNode original) { private static List<Action> getDeleteActions(DisplayableItemNode original) {
List<Action> actions = new ArrayList<Action>(); List<Action> actions = new ArrayList<Action>();
//actions.addAll(original.accept(getDeleteActionVisitor)); //actions.addAll(original.accept(getDeleteActionVisitor));
return actions; return actions;
} }
private static List<Action> getDetailActions(Content c) { private static List<Action> getDetailActions(Content c) {
List<Action> actions = new ArrayList<Action>(); List<Action> actions = new ArrayList<Action>();
actions.addAll(ExplorerNodeActionVisitor.getActions(c)); actions.addAll(ExplorerNodeActionVisitor.getActions(c));
return actions; return actions;
} }
} }
class OriginalNode { class OriginalNode {
private Node original; private Node original;
OriginalNode(Node original) { OriginalNode(Node original) {
this.original = original; this.original = original;
} }
Node getNode() { Node getNode() {
return original; return original;
} }
} }

View File

@ -255,6 +255,13 @@ public class ExplorerNodeActionVisitor extends ContentVisitor.Default<List<? ext
imgDetailPanel.setImgNameValue(img.getName()); imgDetailPanel.setImgNameValue(img.getName());
imgDetailPanel.setImgTypeValue(img.getType().getName()); imgDetailPanel.setImgTypeValue(img.getType().getName());
imgDetailPanel.setImgSectorSizeValue(Long.toString(img.getSsize())); imgDetailPanel.setImgSectorSizeValue(Long.toString(img.getSsize()));
imgDetailPanel.setImgTotalSizeValue(Long.toString(img.getSize()));
String hash = img.getHash();
// don't show the hash if there isn't one
imgDetailPanel.setVisibleHashInfo(hash != null);
imgDetailPanel.setImgHashValue(hash);
counter = true; counter = true;
if (counter) { if (counter) {

View File

@ -1,4 +1,4 @@
<?xml version="1.1" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> <Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues> <AuxValues>
@ -17,31 +17,33 @@
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<EmptySpace min="0" pref="68" max="32767" attributes="0"/>
<Component id="imageInfoLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="78" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="32767" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0"> <Component id="imgNameLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="89" max="-2" attributes="0"/> <Component id="imgTypeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Component id="imgSectorSizeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="imgNameLabel" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="imgTotalSizeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="imgTypeLabel" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="imgHashLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="imgSectorSizeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="29" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="imgNameValue" min="-2" max="-2" attributes="0"/>
<Component id="imgTypeValue" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="imgSectorSizeValue" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="118" max="-2" attributes="0"/>
<Component id="OKButton" min="-2" pref="80" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="71" max="-2" attributes="0"/>
<Component id="imageInfoLabel" min="-2" max="-2" attributes="0"/>
</Group>
</Group> </Group>
<EmptySpace pref="75" max="32767" attributes="0"/> <EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="imgNameValue" min="-2" max="-2" attributes="0"/>
<Component id="imgTypeValue" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="imgSectorSizeValue" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="imgTotalSizeValue" min="-2" max="-2" attributes="0"/>
<Component id="imgHashValue" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="32767" attributes="0"/>
<Component id="OKButton" min="-2" pref="80" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -52,24 +54,39 @@
<Component id="imageInfoLabel" min="-2" max="-2" attributes="0"/> <Component id="imageInfoLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/> <EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0"> <Group type="103" groupAlignment="1" attributes="0">
<Group type="102" attributes="0">
<Component id="imgNameLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="imgTypeLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="imgSectorSizeLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<Component id="imgNameValue" min="-2" max="-2" attributes="0"/> <Component id="imgNameValue" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="imgTypeValue" min="-2" max="-2" attributes="0"/> <Component id="imgTypeValue" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="imgSectorSizeValue" min="-2" max="-2" attributes="0"/> <Component id="imgSectorSizeValue" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="imgTotalSizeValue" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="imgHashValue" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="imgNameLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="imgTypeLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="25" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="50" pref="50" max="-2" attributes="0"/>
<Component id="imgSectorSizeLabel" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="imgTotalSizeLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="imgHashLabel" min="-2" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
<EmptySpace pref="29" max="32767" attributes="0"/> <EmptySpace pref="64" max="32767" attributes="0"/>
<Component id="OKButton" min="-2" max="-2" attributes="0"/> <Component id="OKButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="22" max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -134,5 +151,33 @@
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="imgTotalSizeLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="ImageDetailsPanel.imgTotalSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="imgTotalSizeValue">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="ImageDetailsPanel.imgTotalSizeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="imgHashLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="ImageDetailsPanel.imgHashLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="imgHashValue">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="ImageDetailsPanel.imgHashValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -55,6 +55,10 @@ class ImageDetailsPanel extends javax.swing.JPanel {
imgTypeValue = new javax.swing.JLabel(); imgTypeValue = new javax.swing.JLabel();
imgSectorSizeValue = new javax.swing.JLabel(); imgSectorSizeValue = new javax.swing.JLabel();
OKButton = new javax.swing.JButton(); OKButton = new javax.swing.JButton();
imgTotalSizeLabel = new javax.swing.JLabel();
imgTotalSizeValue = new javax.swing.JLabel();
imgHashLabel = new javax.swing.JLabel();
imgHashValue = new javax.swing.JLabel();
imageInfoLabel.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N imageInfoLabel.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
imageInfoLabel.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.imageInfoLabel.text")); // NOI18N imageInfoLabel.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.imageInfoLabel.text")); // NOI18N
@ -73,30 +77,42 @@ class ImageDetailsPanel extends javax.swing.JPanel {
OKButton.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.OKButton.text")); // NOI18N OKButton.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.OKButton.text")); // NOI18N
imgTotalSizeLabel.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.imgTotalSizeLabel.text")); // NOI18N
imgTotalSizeValue.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.imgTotalSizeValue.text")); // NOI18N
imgHashLabel.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.imgHashLabel.text")); // NOI18N
imgHashValue.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.imgHashValue.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGap(0, 68, Short.MAX_VALUE)
.addComponent(imageInfoLabel)
.addContainerGap(78, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addComponent(imgNameLabel)
.addGap(89, 89, 89) .addComponent(imgTypeLabel)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(imgSectorSizeLabel)
.addComponent(imgNameLabel) .addComponent(imgTotalSizeLabel)
.addComponent(imgTypeLabel) .addComponent(imgHashLabel))
.addComponent(imgSectorSizeLabel)) .addGap(18, 18, 18)
.addGap(29, 29, 29) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(imgNameValue)
.addComponent(imgNameValue) .addComponent(imgTypeValue)
.addComponent(imgTypeValue) .addComponent(imgSectorSizeValue)
.addComponent(imgSectorSizeValue))) .addComponent(imgTotalSizeValue)
.addGroup(layout.createSequentialGroup() .addComponent(imgHashValue))
.addGap(118, 118, 118) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup()
.addGroup(layout.createSequentialGroup() .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(71, 71, 71) .addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(imageInfoLabel))) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap(75, Short.MAX_VALUE))
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -105,21 +121,33 @@ class ImageDetailsPanel extends javax.swing.JPanel {
.addComponent(imageInfoLabel) .addComponent(imageInfoLabel)
.addGap(18, 18, 18) .addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addComponent(imgNameLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(imgTypeLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(imgSectorSizeLabel))
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(imgNameValue) .addComponent(imgNameValue)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(imgTypeValue) .addComponent(imgTypeValue)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(imgSectorSizeValue))) .addComponent(imgSectorSizeValue)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 29, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(imgTotalSizeValue)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(imgHashValue))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addComponent(imgNameLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(imgTypeLabel)
.addGap(25, 25, 25))
.addGroup(layout.createSequentialGroup()
.addGap(50, 50, 50)
.addComponent(imgSectorSizeLabel)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(imgTotalSizeLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(imgHashLabel)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 64, Short.MAX_VALUE)
.addComponent(OKButton) .addComponent(OKButton)
.addGap(22, 22, 22)) .addContainerGap())
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
@ -127,10 +155,14 @@ class ImageDetailsPanel extends javax.swing.JPanel {
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton OKButton; private javax.swing.JButton OKButton;
private javax.swing.JLabel imageInfoLabel; private javax.swing.JLabel imageInfoLabel;
private javax.swing.JLabel imgHashLabel;
private javax.swing.JLabel imgHashValue;
private javax.swing.JLabel imgNameLabel; private javax.swing.JLabel imgNameLabel;
private javax.swing.JLabel imgNameValue; private javax.swing.JLabel imgNameValue;
private javax.swing.JLabel imgSectorSizeLabel; private javax.swing.JLabel imgSectorSizeLabel;
private javax.swing.JLabel imgSectorSizeValue; private javax.swing.JLabel imgSectorSizeValue;
private javax.swing.JLabel imgTotalSizeLabel;
private javax.swing.JLabel imgTotalSizeValue;
private javax.swing.JLabel imgTypeLabel; private javax.swing.JLabel imgTypeLabel;
private javax.swing.JLabel imgTypeValue; private javax.swing.JLabel imgTypeValue;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
@ -155,14 +187,36 @@ class ImageDetailsPanel extends javax.swing.JPanel {
} }
/** /**
* Sets the image size value on this panel. * Sets the image sector size value on this panel.
* *
* @param arg the new image size value * @param arg the new image size value
*/ */
public void setImgSectorSizeValue(String arg){ public void setImgSectorSizeValue(String arg){
imgSectorSizeValue.setText(arg); imgSectorSizeValue.setText(arg);
} }
/**
* Sets the image size value on this panel.
*
* @param arg the new image size value
*/
public void setImgTotalSizeValue(String arg) {
imgTotalSizeValue.setText(arg);
}
/**
* Sets the image hash value on this panel.
*
* @param arg the new image size value
*/
public void setImgHashValue(String arg) {
imgHashValue.setText(arg);
}
public void setVisibleHashInfo(boolean visible) {
imgHashLabel.setVisible(visible);
imgHashValue.setVisible(visible);
}
/** /**
* Sets the OK button action listener. * Sets the OK button action listener.
* *

8
ewfVerify/build.xml Executable file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
<!-- for some information on what you could do (e.g. targets to override). -->
<!-- If you delete this file and reopen the project it will be recreated. -->
<project name="org.sleuthkit.autopsy.ewfverify" default="netbeans" basedir=".">
<description>Builds, tests, and runs the project org.sleuthkit.autopsy.ewfverify.</description>
<import file="nbproject/build-impl.xml"/>
</project>

5
ewfVerify/manifest.mf Executable file
View File

@ -0,0 +1,5 @@
Manifest-Version: 1.0
OpenIDE-Module: org.sleuthkit.autopsy.ewfverify
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/ewfverify/Bundle.properties
OpenIDE-Module-Specification-Version: 1.0

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
*** GENERATED FROM project.xml - DO NOT EDIT ***
*** EDIT ../build.xml INSTEAD ***
-->
<project name="org.sleuthkit.autopsy.ewfverify-impl" basedir="..">
<fail message="Please build using Ant 1.7.1 or higher.">
<condition>
<not>
<antversion atleast="1.7.1"/>
</not>
</condition>
</fail>
<property file="nbproject/private/suite-private.properties"/>
<property file="nbproject/suite.properties"/>
<fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
<property file="${suite.dir}/nbproject/private/platform-private.properties"/>
<property file="${suite.dir}/nbproject/platform.properties"/>
<macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
<attribute name="name"/>
<attribute name="value"/>
<sequential>
<property name="@{name}" value="${@{value}}"/>
</sequential>
</macrodef>
<macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
<attribute name="property"/>
<attribute name="value"/>
<sequential>
<property name="@{property}" value="@{value}"/>
</sequential>
</macrodef>
<property file="${user.properties.file}"/>
<nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
<nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
<nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
<fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
<condition>
<not>
<contains string="${cluster.path.evaluated}" substring="platform"/>
</not>
</condition>
</fail>
<import file="${harness.dir}/build.xml"/>
</project>

View File

@ -0,0 +1,120 @@
branding.token=autopsy
netbeans-plat-version=7.3.1
suite.dir=${basedir}
nbplatform.active.dir=${suite.dir}/netbeans-plat/${netbeans-plat-version}
harness.dir=${nbplatform.active.dir}/harness
bootstrap.url=http://deadlock.netbeans.org/hudson/job/nbms-and-javadoc/lastStableBuild/artifact/nbbuild/netbeans/harness/tasks.jar
autoupdate.catalog.url=http://dlc.sun.com.edgesuite.net/netbeans/updates/${netbeans-plat-version}/uc/final/distribution/catalog.xml.gz
cluster.path=\
${nbplatform.active.dir}/harness:\
${nbplatform.active.dir}/java:\
${nbplatform.active.dir}/platform
disabled.modules=\
org.apache.tools.ant.module,\
org.netbeans.api.debugger.jpda,\
org.netbeans.api.java,\
org.netbeans.lib.nbjavac,\
org.netbeans.libs.cglib,\
org.netbeans.libs.javacapi,\
org.netbeans.libs.javacimpl,\
org.netbeans.libs.springframework,\
org.netbeans.modules.ant.browsetask,\
org.netbeans.modules.ant.debugger,\
org.netbeans.modules.ant.freeform,\
org.netbeans.modules.ant.grammar,\
org.netbeans.modules.ant.kit,\
org.netbeans.modules.beans,\
org.netbeans.modules.classfile,\
org.netbeans.modules.dbschema,\
org.netbeans.modules.debugger.jpda,\
org.netbeans.modules.debugger.jpda.ant,\
org.netbeans.modules.debugger.jpda.kit,\
org.netbeans.modules.debugger.jpda.projects,\
org.netbeans.modules.debugger.jpda.ui,\
org.netbeans.modules.debugger.jpda.visual,\
org.netbeans.modules.findbugs.installer,\
org.netbeans.modules.form,\
org.netbeans.modules.form.binding,\
org.netbeans.modules.form.j2ee,\
org.netbeans.modules.form.kit,\
org.netbeans.modules.form.nb,\
org.netbeans.modules.form.refactoring,\
org.netbeans.modules.hibernate,\
org.netbeans.modules.hibernatelib,\
org.netbeans.modules.hudson.ant,\
org.netbeans.modules.hudson.maven,\
org.netbeans.modules.i18n,\
org.netbeans.modules.i18n.form,\
org.netbeans.modules.j2ee.core.utilities,\
org.netbeans.modules.j2ee.eclipselink,\
org.netbeans.modules.j2ee.eclipselinkmodelgen,\
org.netbeans.modules.j2ee.jpa.refactoring,\
org.netbeans.modules.j2ee.jpa.verification,\
org.netbeans.modules.j2ee.metadata,\
org.netbeans.modules.j2ee.metadata.model.support,\
org.netbeans.modules.j2ee.persistence,\
org.netbeans.modules.j2ee.persistence.kit,\
org.netbeans.modules.j2ee.persistenceapi,\
org.netbeans.modules.java.api.common,\
org.netbeans.modules.java.debug,\
org.netbeans.modules.java.editor,\
org.netbeans.modules.java.editor.lib,\
org.netbeans.modules.java.examples,\
org.netbeans.modules.java.freeform,\
org.netbeans.modules.java.guards,\
org.netbeans.modules.java.helpset,\
org.netbeans.modules.java.hints,\
org.netbeans.modules.java.hints.declarative,\
org.netbeans.modules.java.hints.declarative.test,\
org.netbeans.modules.java.hints.legacy.spi,\
org.netbeans.modules.java.hints.test,\
org.netbeans.modules.java.hints.ui,\
org.netbeans.modules.java.j2seplatform,\
org.netbeans.modules.java.j2seproject,\
org.netbeans.modules.java.kit,\
org.netbeans.modules.java.lexer,\
org.netbeans.modules.java.navigation,\
org.netbeans.modules.java.platform,\
org.netbeans.modules.java.preprocessorbridge,\
org.netbeans.modules.java.project,\
org.netbeans.modules.java.source,\
org.netbeans.modules.java.source.ant,\
org.netbeans.modules.java.source.queries,\
org.netbeans.modules.java.source.queriesimpl,\
org.netbeans.modules.java.sourceui,\
org.netbeans.modules.java.testrunner,\
org.netbeans.modules.javadoc,\
org.netbeans.modules.javawebstart,\
org.netbeans.modules.junit,\
org.netbeans.modules.maven,\
org.netbeans.modules.maven.checkstyle,\
org.netbeans.modules.maven.coverage,\
org.netbeans.modules.maven.embedder,\
org.netbeans.modules.maven.grammar,\
org.netbeans.modules.maven.graph,\
org.netbeans.modules.maven.hints,\
org.netbeans.modules.maven.indexer,\
org.netbeans.modules.maven.junit,\
org.netbeans.modules.maven.kit,\
org.netbeans.modules.maven.model,\
org.netbeans.modules.maven.osgi,\
org.netbeans.modules.maven.persistence,\
org.netbeans.modules.maven.refactoring,\
org.netbeans.modules.maven.repository,\
org.netbeans.modules.maven.search,\
org.netbeans.modules.maven.spring,\
org.netbeans.modules.projectimport.eclipse.core,\
org.netbeans.modules.projectimport.eclipse.j2se,\
org.netbeans.modules.refactoring.java,\
org.netbeans.modules.spellchecker.bindings.java,\
org.netbeans.modules.spring.beans,\
org.netbeans.modules.testng,\
org.netbeans.modules.testng.ant,\
org.netbeans.modules.testng.maven,\
org.netbeans.modules.websvc.jaxws21,\
org.netbeans.modules.websvc.jaxws21api,\
org.netbeans.modules.websvc.saas.codegen.java,\
org.netbeans.modules.xml.jaxb,\
org.netbeans.modules.xml.tools.java,\
org.netbeans.spi.java.hints

View File

@ -0,0 +1,2 @@
javac.source=1.7
javac.compilerargs=-Xlint -Xlint:-serial

31
ewfVerify/nbproject/project.xml Executable file
View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.apisupport.project</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
<code-name-base>org.sleuthkit.autopsy.ewfverify</code-name-base>
<suite-component/>
<module-dependencies>
<dependency>
<code-name-base>org.sleuthkit.autopsy.core</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>9</release-version>
<specification-version>7.0</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.sleuthkit.autopsy.corelibs</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<release-version>3</release-version>
<specification-version>1.1</specification-version>
</run-dependency>
</dependency>
</module-dependencies>
<public-packages/>
</data>
</configuration>
</project>

View File

@ -0,0 +1 @@
suite.dir=${basedir}/..

View File

@ -0,0 +1 @@
OpenIDE-Module-Name=ewfVerify

View File

@ -0,0 +1,225 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 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.ewfverify;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.DatatypeConverter;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.autopsy.ingest.IngestDataSourceWorkerController;
import org.sleuthkit.autopsy.ingest.IngestMessage;
import org.sleuthkit.autopsy.ingest.IngestMessage.MessageType;
import org.sleuthkit.autopsy.ingest.IngestModuleDataSource;
import org.sleuthkit.autopsy.ingest.IngestModuleInit;
import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.PipelineContext;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
/**
* Data Source Ingest Module that generates a hash of an E01 image file and
* verifies it with the value stored in the image.
*
* @author jwallace
*/
public class EwfVerifyIngestModule extends IngestModuleDataSource {
private static final String MODULE_NAME = "EWF Verify";
private static final String MODULE_VERSION = Version.getVersion();
private static final String MODULE_DESCRIPTION = "Validates the integrity of E01 files.";
private static final long DEFAULT_CHUNK_SIZE = 32 * 1024;
private IngestServices services;
private volatile boolean running = false;
private Image img;
private String imgName;
private MessageDigest messageDigest;
private static Logger logger = null;
private static int messageId = 0;
private boolean verified = false;
private boolean skipped = false;
private String calculatedHash = "";
private String storedHash = "";
private SleuthkitCase skCase;
public EwfVerifyIngestModule() {
}
@Override
public void process(PipelineContext<IngestModuleDataSource> pipelineContext, Content dataSource, IngestDataSourceWorkerController controller) {
imgName = dataSource.getName();
try {
img = dataSource.getImage();
} catch (TskCoreException ex) {
img = null;
logger.log(Level.SEVERE, "Failed to get image from Content.", ex);
services.postMessage(IngestMessage.createMessage(++messageId, MessageType.ERROR, this,
"Error processing " + imgName));
return;
}
// Skip images that are not E01
if (img.getType() != TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_EWF_EWF) {
img = null;
logger.log(Level.INFO, "Skipping non-ewf image " + imgName);
services.postMessage(IngestMessage.createMessage(++messageId, MessageType.INFO, this,
"Skipping non-ewf image " + imgName));
skipped = true;
return;
}
// Get the hash stored in the E01 file from the database
if (skCase.imageHasHash(img)) {
try {
storedHash = skCase.getImageHash(img).toLowerCase();
logger.info("Hash value stored in " + imgName + ": " + storedHash);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get stored hash from image " + imgName, ex);
services.postMessage(IngestMessage.createMessage(++messageId, MessageType.ERROR, this,
"Error retrieving stored hash value from " + imgName));
return;
}
} else {
services.postMessage(IngestMessage.createMessage(++messageId, MessageType.ERROR, this,
"Image " + imgName + " does not have stored hash."));
return;
}
logger.log(Level.INFO, "Starting ewf verification of " + img.getName());
services.postMessage(IngestMessage.createMessage(++messageId, MessageType.INFO, this,
"Starting " + imgName));
long size = img.getSize();
if (size == 0) {
logger.log(Level.WARNING, "Size of image " + imgName + " was 0 when queried.");
services.postMessage(IngestMessage.createMessage(++messageId, MessageType.ERROR, this,
"Error getting size of " + imgName + ". Image will not be processed."));
}
// Libewf uses a sector size of 64 times the sector size, which is the
// motivation for using it here.
long chunkSize = 64 * img.getSsize();
chunkSize = (chunkSize == 0) ? DEFAULT_CHUNK_SIZE : chunkSize;
int totalChunks = (int) Math.ceil(size / chunkSize);
logger.log(Level.INFO, "Total chunks = " + totalChunks);
int read;
byte[] data;
controller.switchToDeterminate(totalChunks);
running = true;
// Read in byte size chunks and update the hash value with the data.
for (int i = 0; i < totalChunks; i++) {
if (controller.isCancelled()) {
running = false;
return;
}
data = new byte[ (int) chunkSize ];
try {
read = img.read(data, i * chunkSize, chunkSize);
} catch (TskCoreException ex) {
String msg = "Error reading " + imgName + " at chunk " + i;
services.postMessage(IngestMessage.createMessage(++messageId, MessageType.ERROR, this, msg));
logger.log(Level.SEVERE, msg, ex);
return;
}
messageDigest.update(data);
controller.progress(i);
}
// Finish generating the hash and get it as a string value
calculatedHash = DatatypeConverter.printHexBinary(messageDigest.digest()).toLowerCase();
verified = calculatedHash.equals(storedHash);
logger.info("Hash calculated from " + imgName + ": " + calculatedHash);
running = false;
}
@Override
public void init(IngestModuleInit initContext) {
services = IngestServices.getDefault();
skCase = Case.getCurrentCase().getSleuthkitCase();
running = false;
verified = false;
skipped = false;
img = null;
imgName = "";
storedHash = "";
calculatedHash = "";
if (logger == null) {
logger = services.getLogger(this);
}
if (messageDigest == null) {
try {
messageDigest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException ex) {
logger.log(Level.WARNING, "Error getting md5 algorithm", ex);
throw new RuntimeException("Failed to get MD5 algorithm");
}
} else {
messageDigest.reset();
}
}
@Override
public void complete() {
logger.info("complete() " + this.getName());
if (skipped == false) {
String msg = verified ? " verified" : " not verified";
String extra = "<p>EWF Verification Results for " + imgName + "</p>";
extra += "<li>Result:" + msg + "</li>";
extra += "<li>Calculated hash: " + calculatedHash + "</li>";
extra += "<li>Stored hash: " + storedHash + "</li>";
services.postMessage(IngestMessage.createMessage(++messageId, MessageType.INFO, this, imgName + msg, extra));
logger.info(imgName + msg);
}
}
@Override
public void stop() {
running = false;
}
@Override
public String getName() {
return MODULE_NAME;
}
@Override
public String getVersion() {
return MODULE_VERSION;
}
@Override
public String getDescription() {
return MODULE_DESCRIPTION;
}
@Override
public boolean hasBackgroundJobsRunning() {
return running;
}
}

View File

@ -33,6 +33,7 @@ modules=\
${project.org.sleuthkit.autopsy.sevenzip}:\ ${project.org.sleuthkit.autopsy.sevenzip}:\
${project.org.sleuthkit.autopsy.scalpel}:\ ${project.org.sleuthkit.autopsy.scalpel}:\
${project.org.sleuthkit.autopsy.timeline}:\ ${project.org.sleuthkit.autopsy.timeline}:\
${project.org.sleuthkit.autopsy.ewfverify}:\
${project.org.sleuthkit.autopsy.filetypeid} ${project.org.sleuthkit.autopsy.filetypeid}
project.org.sleuthkit.autopsy.core=Core project.org.sleuthkit.autopsy.core=Core
project.org.sleuthkit.autopsy.corelibs=CoreLibs project.org.sleuthkit.autopsy.corelibs=CoreLibs
@ -45,4 +46,5 @@ project.org.sleuthkit.autopsy.exifparser=ExifParser
project.org.sleuthkit.autopsy.sevenzip=SevenZip project.org.sleuthkit.autopsy.sevenzip=SevenZip
project.org.sleuthkit.autopsy.scalpel=ScalpelCarver project.org.sleuthkit.autopsy.scalpel=ScalpelCarver
project.org.sleuthkit.autopsy.timeline=Timeline project.org.sleuthkit.autopsy.timeline=Timeline
project.org.sleuthkit.autopsy.ewfverify=ewfVerify