diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties index 12abeb5237..0420f6278a 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties @@ -47,3 +47,7 @@ ImageDetailsPanel.imgSectorSizeLabel.text=Sector Size: ImageDetailsPanel.imgSectorSizeValue.text=... DirectoryTreeTopComponent.backButton.text= DirectoryTreeTopComponent.forwardButton.text= +ImageDetailsPanel.imgTotalSizeValue.text=... +ImageDetailsPanel.imgTotalSizeLabel.text=Total Size: +ImageDetailsPanel.imgHashValue.text=... +ImageDetailsPanel.imgHashLabel.text=Hash Value: diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java index d71ea25216..cd3322fd81 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java @@ -1,159 +1,159 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2011 Basis Technology Corp. - * Contact: carrier sleuthkit 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.directorytree; - -import java.awt.event.ActionEvent; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.logging.Level; -import javax.swing.AbstractAction; -import javax.swing.Action; -import org.openide.nodes.FilterNode; -import org.openide.nodes.Node; -import org.openide.util.lookup.Lookups; -import org.openide.util.lookup.ProxyLookup; -import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.datamodel.AbstractContentNode; -import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; -import org.sleuthkit.autopsy.ingest.IngestDialog; -import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.Directory; -import org.sleuthkit.datamodel.Image; -import org.sleuthkit.datamodel.TskCoreException; - -/** - * 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. - * - */ -class DirectoryTreeFilterNode extends FilterNode { - - private static final Action collapseAll = new CollapseAction("Collapse All"); - private static final Logger logger = Logger.getLogger(DirectoryTreeFilterNode.class.getName()); - - /** - * the constructor - */ - DirectoryTreeFilterNode(Node arg, boolean createChildren) { - super(arg, DirectoryTreeFilterChildren.createInstance(arg, createChildren), - new ProxyLookup(Lookups.singleton(new OriginalNode(arg)), - arg.getLookup())); - } - - @Override - public String getDisplayName() { - final Node orig = getOriginal(); - - String name = orig.getDisplayName(); - - //do not show children counts for non content nodes - if (orig instanceof AbstractContentNode) { - //show only for file content nodes - AbstractFile file = getLookup().lookup(AbstractFile.class); - if (file != null) { - try { - final int numChildren = file.getChildrenCount(); - name = name + " (" + numChildren + ")"; - } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Error getting children count to display for file: " + file, ex); - } - - } - } - - return name; - } - - /** - * Right click action for the nodes in the directory tree. - * - * @param popup - * @return - */ - @Override - public Action[] getActions(boolean popup) { - List actions = new ArrayList(); - - final Content content = this.getLookup().lookup(Content.class); - if (content != null) { - actions.addAll(DirectoryTreeFilterNode.getDetailActions(content)); - - //extract dir action - Directory dir = this.getLookup().lookup(Directory.class); - if (dir != null) { - actions.add(ExtractAction.getInstance()); - } - - // file search action - final Image img = this.getLookup().lookup(Image.class); - if (img != null) { - actions.add(new FileSearchAction("Open File Search by Attributes")); - } - - //ingest action - actions.add(new AbstractAction("Run Ingest Modules") { - @Override - public void actionPerformed(ActionEvent e) { - final IngestDialog ingestDialog = new IngestDialog(); - ingestDialog.setContent(Collections.singletonList(content)); - ingestDialog.display(); - } - }); - } - - //check if delete actions should be added - final Node orig = getOriginal(); - //TODO add a mechanism to determine if DisplayableItemNode - if (orig instanceof DisplayableItemNode) { - actions.addAll(getDeleteActions((DisplayableItemNode) orig)); - } - - actions.add(collapseAll); - return actions.toArray(new Action[actions.size()]); - } - - private static List getDeleteActions(DisplayableItemNode original) { - List actions = new ArrayList(); - //actions.addAll(original.accept(getDeleteActionVisitor)); - return actions; - } - - private static List getDetailActions(Content c) { - List actions = new ArrayList(); - - actions.addAll(ExplorerNodeActionVisitor.getActions(c)); - - return actions; - } -} - -class OriginalNode { - - private Node original; - - OriginalNode(Node original) { - this.original = original; - } - - Node getNode() { - return original; - } +/* + * Autopsy Forensic Browser + * + * Copyright 2011 Basis Technology Corp. + * Contact: carrier sleuthkit 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.directorytree; + +import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; +import javax.swing.AbstractAction; +import javax.swing.Action; +import org.openide.nodes.FilterNode; +import org.openide.nodes.Node; +import org.openide.util.lookup.Lookups; +import org.openide.util.lookup.ProxyLookup; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.datamodel.AbstractContentNode; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.autopsy.ingest.IngestDialog; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.Directory; +import org.sleuthkit.datamodel.Image; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * 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. + * + */ +class DirectoryTreeFilterNode extends FilterNode { + + private static final Action collapseAll = new CollapseAction("Collapse All"); + private static final Logger logger = Logger.getLogger(DirectoryTreeFilterNode.class.getName()); + + /** + * the constructor + */ + DirectoryTreeFilterNode(Node arg, boolean createChildren) { + super(arg, DirectoryTreeFilterChildren.createInstance(arg, createChildren), + new ProxyLookup(Lookups.singleton(new OriginalNode(arg)), + arg.getLookup())); + } + + @Override + public String getDisplayName() { + final Node orig = getOriginal(); + + String name = orig.getDisplayName(); + + //do not show children counts for non content nodes + if (orig instanceof AbstractContentNode) { + //show only for file content nodes + AbstractFile file = getLookup().lookup(AbstractFile.class); + if (file != null) { + try { + final int numChildren = file.getChildrenCount(); + name = name + " (" + numChildren + ")"; + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error getting children count to display for file: " + file, ex); + } + + } + } + + return name; + } + + /** + * Right click action for the nodes in the directory tree. + * + * @param popup + * @return + */ + @Override + public Action[] getActions(boolean popup) { + List actions = new ArrayList(); + + final Content content = this.getLookup().lookup(Content.class); + if (content != null) { + actions.addAll(DirectoryTreeFilterNode.getDetailActions(content)); + + //extract dir action + Directory dir = this.getLookup().lookup(Directory.class); + if (dir != null) { + actions.add(ExtractAction.getInstance()); + } + + // file search action + final Image img = this.getLookup().lookup(Image.class); + if (img != null) { + actions.add(new FileSearchAction("Open File Search by Attributes")); + } + + //ingest action + actions.add(new AbstractAction("Run Ingest Modules") { + @Override + public void actionPerformed(ActionEvent e) { + final IngestDialog ingestDialog = new IngestDialog(); + ingestDialog.setContent(Collections.singletonList(content)); + ingestDialog.display(); + } + }); + } + + //check if delete actions should be added + final Node orig = getOriginal(); + //TODO add a mechanism to determine if DisplayableItemNode + if (orig instanceof DisplayableItemNode) { + actions.addAll(getDeleteActions((DisplayableItemNode) orig)); + } + + actions.add(collapseAll); + return actions.toArray(new Action[actions.size()]); + } + + private static List getDeleteActions(DisplayableItemNode original) { + List actions = new ArrayList(); + //actions.addAll(original.accept(getDeleteActionVisitor)); + return actions; + } + + private static List getDetailActions(Content c) { + List actions = new ArrayList(); + + actions.addAll(ExplorerNodeActionVisitor.getActions(c)); + + return actions; + } +} + +class OriginalNode { + + private Node original; + + OriginalNode(Node original) { + this.original = original; + } + + Node getNode() { + return original; + } } \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java b/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java index 82b374eb99..0cf73adc5e 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java @@ -255,6 +255,13 @@ public class ExplorerNodeActionVisitor extends ContentVisitor.Default +
@@ -17,31 +17,33 @@ + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + - + + + + + + + + + + + + + + @@ -52,24 +54,39 @@ - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - + - + @@ -134,5 +151,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ImageDetailsPanel.java b/Core/src/org/sleuthkit/autopsy/directorytree/ImageDetailsPanel.java index eeadbee6d4..07241253e6 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ImageDetailsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ImageDetailsPanel.java @@ -55,6 +55,10 @@ class ImageDetailsPanel extends javax.swing.JPanel { imgTypeValue = new javax.swing.JLabel(); imgSectorSizeValue = new javax.swing.JLabel(); 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.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 + 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); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .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.createSequentialGroup() - .addGap(89, 89, 89) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(imgNameLabel) - .addComponent(imgTypeLabel) - .addComponent(imgSectorSizeLabel)) - .addGap(29, 29, 29) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(imgNameValue) - .addComponent(imgTypeValue) - .addComponent(imgSectorSizeValue))) - .addGroup(layout.createSequentialGroup() - .addGap(118, 118, 118) - .addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addGap(71, 71, 71) - .addComponent(imageInfoLabel))) - .addContainerGap(75, Short.MAX_VALUE)) + .addComponent(imgNameLabel) + .addComponent(imgTypeLabel) + .addComponent(imgSectorSizeLabel) + .addComponent(imgTotalSizeLabel) + .addComponent(imgHashLabel)) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(imgNameValue) + .addComponent(imgTypeValue) + .addComponent(imgSectorSizeValue) + .addComponent(imgTotalSizeValue) + .addComponent(imgHashValue)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -105,21 +121,33 @@ class ImageDetailsPanel extends javax.swing.JPanel { .addComponent(imageInfoLabel) .addGap(18, 18, 18) .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() .addComponent(imgNameValue) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(imgTypeValue) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(imgSectorSizeValue))) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 29, Short.MAX_VALUE) + .addComponent(imgSectorSizeValue) + .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) - .addGap(22, 22, 22)) + .addContainerGap()) ); }// //GEN-END:initComponents @@ -127,10 +155,14 @@ class ImageDetailsPanel extends javax.swing.JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton OKButton; private javax.swing.JLabel imageInfoLabel; + private javax.swing.JLabel imgHashLabel; + private javax.swing.JLabel imgHashValue; private javax.swing.JLabel imgNameLabel; private javax.swing.JLabel imgNameValue; private javax.swing.JLabel imgSectorSizeLabel; private javax.swing.JLabel imgSectorSizeValue; + private javax.swing.JLabel imgTotalSizeLabel; + private javax.swing.JLabel imgTotalSizeValue; private javax.swing.JLabel imgTypeLabel; private javax.swing.JLabel imgTypeValue; // 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 */ public void setImgSectorSizeValue(String 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. * diff --git a/ewfVerify/build.xml b/ewfVerify/build.xml new file mode 100755 index 0000000000..8148da5b31 --- /dev/null +++ b/ewfVerify/build.xml @@ -0,0 +1,8 @@ + + + + + + Builds, tests, and runs the project org.sleuthkit.autopsy.ewfverify. + + diff --git a/ewfVerify/manifest.mf b/ewfVerify/manifest.mf new file mode 100755 index 0000000000..58bae736ac --- /dev/null +++ b/ewfVerify/manifest.mf @@ -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 + diff --git a/ewfVerify/nbproject/build-impl.xml b/ewfVerify/nbproject/build-impl.xml new file mode 100755 index 0000000000..f6669a3613 --- /dev/null +++ b/ewfVerify/nbproject/build-impl.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + You must set 'suite.dir' to point to your containing module suite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ewfVerify/nbproject/platform.properties b/ewfVerify/nbproject/platform.properties new file mode 100755 index 0000000000..a9fa87f749 --- /dev/null +++ b/ewfVerify/nbproject/platform.properties @@ -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 + diff --git a/ewfVerify/nbproject/project.properties b/ewfVerify/nbproject/project.properties new file mode 100755 index 0000000000..6baf44e2f5 --- /dev/null +++ b/ewfVerify/nbproject/project.properties @@ -0,0 +1,2 @@ +javac.source=1.7 +javac.compilerargs=-Xlint -Xlint:-serial diff --git a/ewfVerify/nbproject/project.xml b/ewfVerify/nbproject/project.xml new file mode 100755 index 0000000000..a3955c75fa --- /dev/null +++ b/ewfVerify/nbproject/project.xml @@ -0,0 +1,31 @@ + + + org.netbeans.modules.apisupport.project + + + org.sleuthkit.autopsy.ewfverify + + + + org.sleuthkit.autopsy.core + + + + 9 + 7.0 + + + + org.sleuthkit.autopsy.corelibs + + + + 3 + 1.1 + + + + + + + diff --git a/ewfVerify/nbproject/suite.properties b/ewfVerify/nbproject/suite.properties new file mode 100755 index 0000000000..29d7cc9bd6 --- /dev/null +++ b/ewfVerify/nbproject/suite.properties @@ -0,0 +1 @@ +suite.dir=${basedir}/.. diff --git a/ewfVerify/src/org/sleuthkit/autopsy/ewfverify/Bundle.properties b/ewfVerify/src/org/sleuthkit/autopsy/ewfverify/Bundle.properties new file mode 100755 index 0000000000..3b02b79f43 --- /dev/null +++ b/ewfVerify/src/org/sleuthkit/autopsy/ewfverify/Bundle.properties @@ -0,0 +1 @@ +OpenIDE-Module-Name=ewfVerify diff --git a/ewfVerify/src/org/sleuthkit/autopsy/ewfverify/EwfVerifyIngestModule.java b/ewfVerify/src/org/sleuthkit/autopsy/ewfverify/EwfVerifyIngestModule.java new file mode 100755 index 0000000000..3da40b3fff --- /dev/null +++ b/ewfVerify/src/org/sleuthkit/autopsy/ewfverify/EwfVerifyIngestModule.java @@ -0,0 +1,225 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2013 Basis Technology Corp. + * Contact: carrier sleuthkit 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 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 = "

EWF Verification Results for " + imgName + "

"; + extra += "
  • Result:" + msg + "
  • "; + extra += "
  • Calculated hash: " + calculatedHash + "
  • "; + extra += "
  • Stored hash: " + storedHash + "
  • "; + 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; + } +} diff --git a/nbproject/project.properties b/nbproject/project.properties index 7e397a51ff..799d3b4e1e 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -33,6 +33,7 @@ modules=\ ${project.org.sleuthkit.autopsy.sevenzip}:\ ${project.org.sleuthkit.autopsy.scalpel}:\ ${project.org.sleuthkit.autopsy.timeline}:\ + ${project.org.sleuthkit.autopsy.ewfverify}:\ ${project.org.sleuthkit.autopsy.filetypeid} project.org.sleuthkit.autopsy.core=Core 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.scalpel=ScalpelCarver project.org.sleuthkit.autopsy.timeline=Timeline +project.org.sleuthkit.autopsy.ewfverify=ewfVerify