diff --git a/BUILDING.txt b/BUILDING.txt index b01dc103ad..69a3dfd988 100644 --- a/BUILDING.txt +++ b/BUILDING.txt @@ -1,3 +1,5 @@ + Last Updated: June 12, 2012 + This file outlines what it takes to build Autopsy from source. Note that it currently only works out of the box on Windows. We @@ -5,33 +7,49 @@ are working on getting the process working under non-WIndows systems. It generally works, but needs some custom mangling to find the correct C libraries. + STEPS: -1) Download and install 32-bit version of JDK (32-bit is currently +1) Get Java Setup +1a) Download and install 32-bit version of JDK (32-bit is currently needed even if you have a 64-bit system). -2) Ensure that JDK_HOME is set to the root JDK directory. +1b) Ensure that JDK_HOME is set to the root JDK directory. -3) Download and install Netbeans IDE 7.0.1 (http://netbeans.org/) +1c) Download and install Netbeans IDE 7.0.1 (http://netbeans.org/) -4) Download and build the release version of Libewf2 (20120304 or later). All you need is the dll file. Note that you will get a launching error if you use libewf 1. + +2) Get Sleuth Kit Setup +2a) Download and build the release version of Libewf2 (20120304 or later). All you need is the dll file. Note that you will get a launching error if you use libewf 1. - http://sourceforge.net/projects/libewf/ -5) Set LIBEWF_HOME environment variable to root directory of LIBEWF +2b) Set LIBEWF_HOME environment variable to root directory of LIBEWF -6) Download and build release version of Sleuth Kit (TSK) 4.0. You +2c) Download and build release version of Sleuth Kit (TSK) 4.0. You need to build the tsk_jni project. - At the time of this writing, 4.0 is not released. You can get it from either -- GIT: git://github.com/sleuthkit/sleuthkit.git -- SVN: http://svn.github.com/sleuthkit/sleuthkit.git -7) Build the TSK JAR file by typing 'ant' in bindings/java from a +2d) Build the TSK JAR file by typing 'ant' in bindings/java from a command line or by opening the project in NetBeans. -8) Set TSK_HOME environment variable to the root directory of TSK +2e) Set TSK_HOME environment variable to the root directory of TSK -9) Start NetBean IDE and open the Autopsy project. -10) Choose to build the Autopsy project / module. It is the highest +3) Get gstreamer Setup + +If Autopsy installer is not used, add the following entries to Windows PATH environment variable +(replace GSTREAMER_INSTALL_DIR with the location of the gstreamer root directory): + GSTREAMER_INSTALL_DIR\bin\; + GSTREAMER_INSTALL_DIR\lib\gstreamer-0.10\; +If you don't have gstreamer already, you can find a zipped gstreamer distribution in + AUTOPSYROOT/thirdparty/gstreamer + + +4) Compile Autopsy +4a) Start NetBean IDE and open the Autopsy project. + +4b) Choose to build the Autopsy project / module. It is the highest level project that will then cause the other modules to be compiled. @@ -55,5 +73,4 @@ rebuild both the dll and the JAR file. --------------- Brian Carrier -4/6/2012 carrier sleuthkit org diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageAction.java b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageAction.java index 9191612312..196092ebed 100644 --- a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageAction.java +++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageAction.java @@ -71,8 +71,7 @@ public final class AddImageAction extends CallableSystemAction implements Presen static final String LOOKUPFILES_PROP = "lookupFiles"; // boolean: whether or not to skip processing orphan files on FAT filesystems static final String NOFATORPHANS_PROP = "nofatorphans"; - // boolean: whether or not to skip processing of unallocated space - static final String NOUNALLOC_PROP = "nounalloc"; + static final Logger logger = Logger.getLogger(AddImageAction.class.getName()); diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel1.form b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel1.form index 5f37df3806..809858410c 100644 --- a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel1.form +++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel1.form @@ -10,7 +10,7 @@ - + @@ -28,9 +28,13 @@ - + + + + + @@ -43,15 +47,6 @@ - - - - - - - - - @@ -66,8 +61,10 @@ + + - + @@ -92,22 +89,21 @@ - + - + - - - - - - - + + + + + + @@ -245,16 +241,6 @@ - - - - - - - - - - diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel1.java b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel1.java index 7fc06a34bc..e554e7ec62 100644 --- a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel1.java +++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel1.java @@ -116,14 +116,6 @@ final class AddImageVisualPanel1 extends JPanel implements DocumentListener { return noFatOrphansCheckbox.isSelected(); } - /** - * - * @return true if no unalloc space processing is selected - */ - boolean getNoUnallocSpaceProcess() { - return noProcessUnallocSpace.isSelected(); - } - /** @@ -221,11 +213,10 @@ final class AddImageVisualPanel1 extends JPanel implements DocumentListener { timeZoneLabel = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel(); noFatOrphansCheckbox = new javax.swing.JCheckBox(); - noProcessUnallocSpace = new javax.swing.JCheckBox(); optionsLabel1 = new javax.swing.JLabel(); setMinimumSize(new java.awt.Dimension(559, 328)); - setPreferredSize(new java.awt.Dimension(588, 308)); + setPreferredSize(new java.awt.Dimension(588, 328)); org.openide.awt.Mnemonics.setLocalizedText(rawSingle, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.rawSingle.text")); // NOI18N rawSingle.setRequestFocusEnabled(false); @@ -281,13 +272,6 @@ final class AddImageVisualPanel1 extends JPanel implements DocumentListener { org.openide.awt.Mnemonics.setLocalizedText(noFatOrphansCheckbox, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.noFatOrphansCheckbox.text")); // NOI18N noFatOrphansCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.noFatOrphansCheckbox.toolTipText")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(noProcessUnallocSpace, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.noProcessUnallocSpace.text")); // NOI18N - noProcessUnallocSpace.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - noProcessUnallocSpaceActionPerformed(evt); - } - }); - org.openide.awt.Mnemonics.setLocalizedText(optionsLabel1, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.optionsLabel1.text")); // NOI18N javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -297,6 +281,9 @@ final class AddImageVisualPanel1 extends JPanel implements DocumentListener { .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(10, 10, 10) + .addComponent(noFatOrphansCheckbox)) .addComponent(imgTypeLabel) .addGroup(layout.createSequentialGroup() .addGap(10, 10, 10) @@ -307,13 +294,6 @@ final class AddImageVisualPanel1 extends JPanel implements DocumentListener { .addComponent(multipleSelectLabel) .addComponent(imgInfoLabel) .addComponent(jLabel1) - .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(optionsLabel1) - .addGroup(layout.createSequentialGroup() - .addGap(10, 10, 10) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(noFatOrphansCheckbox) - .addComponent(noProcessUnallocSpace))) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addComponent(timeZoneLabel) @@ -324,8 +304,10 @@ final class AddImageVisualPanel1 extends JPanel implements DocumentListener { .addGap(18, 18, 18) .addComponent(imgPathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 389, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(imgPathBrowserButton)))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(imgPathBrowserButton))) + .addComponent(optionsLabel1) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(39, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -347,21 +329,19 @@ final class AddImageVisualPanel1 extends JPanel implements DocumentListener { .addComponent(imgPathBrowserButton)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(multipleSelectLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(timeZoneLabel) .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(18, 18, 18) .addComponent(optionsLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(noProcessUnallocSpace) - .addGap(3, 3, 3) .addComponent(noFatOrphansCheckbox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel1) - .addContainerGap()) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel1) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(25, 25, 25)) ); }// //GEN-END:initComponents @@ -473,10 +453,6 @@ final class AddImageVisualPanel1 extends JPanel implements DocumentListener { this.wizPanel.moveFocusToNext(); }//GEN-LAST:event_imgPathBrowserButtonActionPerformed -private void noProcessUnallocSpaceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_noProcessUnallocSpaceActionPerformed -// TODO add your handling code here: -}//GEN-LAST:event_noProcessUnallocSpaceActionPerformed - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.ButtonGroup buttonGroup1; private javax.swing.JRadioButton encase; @@ -489,7 +465,6 @@ private void noProcessUnallocSpaceActionPerformed(java.awt.event.ActionEvent evt private javax.swing.JLabel jLabel2; private javax.swing.JLabel multipleSelectLabel; private javax.swing.JCheckBox noFatOrphansCheckbox; - private javax.swing.JCheckBox noProcessUnallocSpace; private javax.swing.JLabel optionsLabel1; private static javax.swing.JRadioButton rawSingle; private javax.swing.JRadioButton rawSplit; diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel1.java b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel1.java index babea16623..4063870630 100644 --- a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel1.java +++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel1.java @@ -214,7 +214,6 @@ class AddImageWizardPanel1 implements WizardDescriptor.Panel, settings.putProperty(AddImageAction.IMGPATHS_PROP, getComponent().getImagePaths()); settings.putProperty(AddImageAction.TIMEZONE_PROP, getComponent().getSelectedTimezone()); // store the timezone settings.putProperty(AddImageAction.NOFATORPHANS_PROP, Boolean.valueOf(getComponent().getNoFatOrphans())); - settings.putProperty(AddImageAction.NOUNALLOC_PROP, Boolean.valueOf(getComponent().getNoUnallocSpaceProcess())); //settings.putProperty(AddImageAction.LOOKUPFILES_PROP, getComponent().getLookupFilesCheckboxChecked()); //settings.putProperty(AddImageAction.SOLR_PROP, getComponent().getIndexImageCheckboxChecked()); diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel2.java b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel2.java index 68f608e118..cea82741d5 100644 --- a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel2.java +++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel2.java @@ -55,8 +55,6 @@ class AddImageWizardPanel2 implements WizardDescriptor.Panel { private String timeZone; //whether to not process FAT filesystem orphans private boolean noFatOrphans; - //whether to not process unalloc space - private boolean noUnallocSpace; // task that will clean up the created database file if the wizard is cancelled before it finishes private AddImageAction.CleanupTask cleanupImage; // initialized to null in readSettings() // flag to control the availiablity of next action @@ -195,7 +193,6 @@ class AddImageWizardPanel2 implements WizardDescriptor.Panel { imgPaths = (String[]) settings.getProperty(AddImageAction.IMGPATHS_PROP); timeZone = settings.getProperty(AddImageAction.TIMEZONE_PROP).toString(); noFatOrphans = ((Boolean) settings.getProperty(AddImageAction.NOFATORPHANS_PROP)).booleanValue(); - noUnallocSpace = ((Boolean) settings.getProperty(AddImageAction.NOUNALLOC_PROP)).booleanValue(); component.changeProgressBarTextAndColor("", 0, Color.black); @@ -278,7 +275,7 @@ class AddImageWizardPanel2 implements WizardDescriptor.Panel { } - process = currentCase.makeAddImageProcess(timeZone, !noUnallocSpace, noFatOrphans); + process = currentCase.makeAddImageProcess(timeZone, true, noFatOrphans); cancelledWhileRunning.enable(); try { process.run(imgPaths); diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/Bundle.properties b/Case/src/org/sleuthkit/autopsy/casemodule/Bundle.properties index 36defd4ee3..a29fc26e87 100755 --- a/Case/src/org/sleuthkit/autopsy/casemodule/Bundle.properties +++ b/Case/src/org/sleuthkit/autopsy/casemodule/Bundle.properties @@ -126,5 +126,4 @@ NewCaseVisualPanel2.examinerTextField.text= NewCaseVisualPanel2.optionalLabel.text=Optional: Set Case Number and Examiner AddImageVisualPanel1.noFatOrphansCheckbox.toolTipText= AddImageVisualPanel1.noFatOrphansCheckbox.text=Ignore orphan files in FAT file systems -AddImageVisualPanel1.noProcessUnallocSpace.text=Ignore unallocated space AddImageVisualPanel1.optionsLabel1.text=Options to produce results faster (although some data will not be searched): diff --git a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/Bundle.properties b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/Bundle.properties index e00c186e67..15569c2b05 100644 --- a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/Bundle.properties +++ b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/Bundle.properties @@ -1,18 +1,17 @@ OpenIDE-Module-Name=HashDatabase HashDatabaseManagementPanel.okayButton.text=Okay HashDbPanel.fileSelectButton.text=Select...\n -HashDbSimplePanel.knownLabel.text=Known files database: -HashDbSimplePanel.notableLabel.text=Notable files database: +HashDbSimplePanel.knownLabel.text=NSRL Database: +HashDbSimplePanel.notableLabel.text=Known Bad Database(s): HashDbSimplePanel.knownValLabel.text=- HashDbSimplePanel.notableValLabel.text=- -HashDbMgmtPanel.addNotableButton.text=Add Notable Database +HashDbMgmtPanel.addNotableButton.text=Add Known Bad Database HashDbMgmtPanel.removeNotableButton.text=Remove Selected -HashDbSimplePanel.jLabel1.text=Notable Hash Databases: -HashDbSimplePanel.jLabel2.text=NSRL Hash Database: -HashDbMgmtPanel.nsrlNameLabel.text=No NSRL Hashset +HashDbSimplePanel.jLabel1.text=Known Bad Database(s): +HashDbSimplePanel.jLabel2.text=NSRL Database: +HashDbMgmtPanel.nsrlNameLabel.text=Not Configured HashDbMgmtPanel.setNSRLButton.text=Change -HashDbSimplePanel.nsrlNameLabel.text=No NSRL database set. -HashDbMgmtPanel.jLabel1.text=Notable Hash Databases: +HashDbMgmtPanel.jLabel1.text=Known Bad Database(s): HashDbMgmtPanel.jLabel2.text=NSRL Database: HashDbMgmtPanel.indexNSRLButton.text=Index HashDbMgmtPanel.removeNSRLButton.text=Remove diff --git a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbMgmtPanel.form b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbMgmtPanel.form index 46b5d990b4..3f4e866cd1 100644 --- a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbMgmtPanel.form +++ b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbMgmtPanel.form @@ -19,7 +19,7 @@ - + @@ -27,7 +27,7 @@ - + @@ -38,17 +38,17 @@ - + - + - + diff --git a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbMgmtPanel.java b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbMgmtPanel.java index b3bf5254ec..706d0a824e 100644 --- a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbMgmtPanel.java +++ b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbMgmtPanel.java @@ -28,9 +28,7 @@ import java.awt.Component; import java.awt.event.ActionEvent; import java.io.File; import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; -import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.AbstractAction; @@ -95,9 +93,20 @@ public class HashDbMgmtPanel extends javax.swing.JPanel { fc.setMultiSelectionEnabled(false); TableColumn column1 = null; + final int width1 = jScrollPane1.getPreferredSize().width; for (int i = 0; i < notableHashSetTable.getColumnCount(); i++) { column1 = notableHashSetTable.getColumnModel().getColumn(i); + if (i == 0) { + column1.setPreferredWidth((int) (width1*.20)); + } + if (i == 1) { + column1.setPreferredWidth((int) (width1*.57)); + } + if (i == 2) { + column1.setPreferredWidth((int) (width1*.15)); + } if (i == 3) { + column1.setPreferredWidth((int) (width1*.07)); column1.setCellRenderer(new CheckBoxRenderer()); } } @@ -223,14 +232,14 @@ public class HashDbMgmtPanel extends javax.swing.JPanel { .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel1) - .addContainerGap(257, Short.MAX_VALUE)) + .addContainerGap(405, Short.MAX_VALUE)) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(10, 10, 10) .addComponent(nsrlNameLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 63, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 218, Short.MAX_VALUE) .addComponent(indexNSRLButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(setNSRLButton) @@ -238,16 +247,16 @@ public class HashDbMgmtPanel extends javax.swing.JPanel { .addComponent(removeNSRLButton)) .addComponent(jLabel2)) .addContainerGap()) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 389, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 534, Short.MAX_VALUE) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addComponent(addNotableButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 113, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 242, Short.MAX_VALUE) .addComponent(removeNotableButton) .addContainerGap()) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(ingestRunningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 369, Short.MAX_VALUE) + .addComponent(ingestRunningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 514, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( @@ -443,7 +452,7 @@ public class HashDbMgmtPanel extends javax.swing.JPanel { case 2: return "Status"; default: - return "Use For Ingest"; + return "Ingest"; } } @@ -559,7 +568,7 @@ public class HashDbMgmtPanel extends javax.swing.JPanel { theButton.setEnabled(false); break; default: - theButton.setText("No DB"); + theButton.setText("Index"); theButton.setEnabled(false); } if (ingestRunning) { diff --git a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbSimplePanel.form b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbSimplePanel.form index 12c08cd4fd..ac8c4ab233 100644 --- a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbSimplePanel.form +++ b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbSimplePanel.form @@ -1,6 +1,6 @@ -
+ @@ -18,32 +18,28 @@ - - + + - - - - - - - - + + + + - - - + + + - + @@ -88,12 +84,30 @@ - + - - + + + + - + + + + + + + + + + + + + + + + + diff --git a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbSimplePanel.java b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbSimplePanel.java index 7094c420e9..706094616c 100644 --- a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbSimplePanel.java +++ b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbSimplePanel.java @@ -24,8 +24,6 @@ */ package org.sleuthkit.autopsy.hashdatabase; -import java.util.ArrayList; -import java.util.List; import java.util.logging.Logger; import javax.swing.JOptionPane; import javax.swing.table.AbstractTableModel; @@ -39,12 +37,14 @@ public class HashDbSimplePanel extends javax.swing.JPanel { private static final Logger logger = Logger.getLogger(HashDbSimplePanel.class.getName()); private HashTableModel knownBadTableModel; + private NSRLTableModel nsrlTableModel; private HashDb nsrl; private static boolean ingestRunning = false; /** Creates new form HashDbSimplePanel */ public HashDbSimplePanel() { knownBadTableModel = new HashTableModel(); + nsrlTableModel = new NSRLTableModel(); initComponents(); customizeComponents(); } @@ -55,18 +55,26 @@ public class HashDbSimplePanel extends javax.swing.JPanel { private void customizeComponents() { notableHashTable.setModel(knownBadTableModel); + jTable1.setModel(nsrlTableModel); notableHashTable.setTableHeader(null); + jTable1.setTableHeader(null); notableHashTable.setRowSelectionAllowed(false); + jTable1.setRowSelectionAllowed(false); //customize column witdhs final int width1 = jScrollPane1.getPreferredSize().width; + final int width2 = jScrollPane2.getPreferredSize().width; TableColumn column1 = null; + TableColumn column2 = null; for (int i = 0; i < notableHashTable.getColumnCount(); i++) { column1 = notableHashTable.getColumnModel().getColumn(i); + column2 = jTable1.getColumnModel().getColumn(i); if (i == 0) { column1.setPreferredWidth(((int) (width1 * 0.15))); + column2.setPreferredWidth(((int) (width2 * 0.15))); } else { column1.setPreferredWidth(((int) (width1 * 0.84))); + column2.setPreferredWidth(((int) (width2 * 0.84))); } } @@ -86,7 +94,8 @@ public class HashDbSimplePanel extends javax.swing.JPanel { notableHashTable = new javax.swing.JTable(); jLabel1 = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel(); - nsrlNameLabel = new javax.swing.JLabel(); + jScrollPane2 = new javax.swing.JScrollPane(); + jTable1 = new javax.swing.JTable(); jScrollPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); @@ -99,7 +108,12 @@ public class HashDbSimplePanel extends javax.swing.JPanel { jLabel2.setText(org.openide.util.NbBundle.getMessage(HashDbSimplePanel.class, "HashDbSimplePanel.jLabel2.text")); // NOI18N - nsrlNameLabel.setText(org.openide.util.NbBundle.getMessage(HashDbSimplePanel.class, "HashDbSimplePanel.nsrlNameLabel.text")); // NOI18N + jScrollPane2.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); + + jTable1.setBackground(new java.awt.Color(240, 240, 240)); + jTable1.setShowHorizontalLines(false); + jTable1.setShowVerticalLines(false); + jScrollPane2.setViewportView(jTable1); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -107,28 +121,25 @@ public class HashDbSimplePanel extends javax.swing.JPanel { layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(jLabel1) - .addContainerGap(142, Short.MAX_VALUE)) - .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 274, Short.MAX_VALUE) + .addComponent(jLabel2) + .addContainerGap(51, Short.MAX_VALUE)) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(jLabel2) - .addContainerGap(159, Short.MAX_VALUE)) - .addGroup(layout.createSequentialGroup() - .addGap(53, 53, 53) - .addComponent(nsrlNameLabel) - .addContainerGap(110, Short.MAX_VALUE)) + .addComponent(jLabel1) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 139, Short.MAX_VALUE) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 139, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(nsrlNameLabel) + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 106, Short.MAX_VALUE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 98, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -136,19 +147,46 @@ public class HashDbSimplePanel extends javax.swing.JPanel { private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JTable jTable1; private javax.swing.JTable notableHashTable; - private javax.swing.JLabel nsrlNameLabel; // End of variables declaration//GEN-END:variables private void reloadSets() { nsrl = HashDbXML.getCurrent().getNSRLSet(); - if(nsrl == null) { - nsrlNameLabel.setText("No NSRL database set."); - } else { - nsrlNameLabel.setText(nsrl.getName()); - } + nsrlTableModel.resync(); knownBadTableModel.resync(); } + + private class NSRLTableModel extends AbstractTableModel { + + private void resync() { + fireTableDataChanged(); + } + + @Override + public int getRowCount() { + return 1; + } + + @Override + public int getColumnCount() { + return 2; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + if (columnIndex == 0) { + return ""; + } else { + if(nsrl == null) { + return "Not Configured"; + } else { + return nsrl.getName(); + } + } + } + } private class HashTableModel extends AbstractTableModel { @@ -175,7 +213,7 @@ public class HashDbSimplePanel extends javax.swing.JPanel { if (columnIndex == 0) { return ""; } else { - return "No notable databases set."; + return "Not Configured"; } } else { HashDb db = xmlHandle.getKnownBadSets().get(rowIndex); diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestDialogPanel.form b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestDialogPanel.form index 739e379216..1b9083e741 100644 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestDialogPanel.form +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestDialogPanel.form @@ -28,7 +28,7 @@ - + @@ -44,7 +44,7 @@ - + @@ -175,34 +175,30 @@ + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + - + - - @@ -210,7 +206,9 @@ - + + + diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestDialogPanel.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestDialogPanel.java index 1c25beff8e..8e6aa08b98 100644 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestDialogPanel.java +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestDialogPanel.java @@ -289,27 +289,25 @@ public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfi timePanelLayout.setHorizontalGroup( timePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(timePanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(timeLabel) + .addContainerGap(68, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, timePanelLayout.createSequentialGroup() + .addContainerGap() .addGroup(timePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(timePanelLayout.createSequentialGroup() - .addContainerGap() - .addGroup(timePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(timeRadioButton2) - .addComponent(timeRadioButton3))) - .addGroup(timePanelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(timeLabel)) - .addComponent(processUnallocCheckbox) - .addGroup(timePanelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(timeRadioButton1))) + .addComponent(timeRadioButton3) + .addComponent(timeRadioButton2) + .addComponent(timeRadioButton1)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(timePanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(processUnallocCheckbox) .addContainerGap(10, Short.MAX_VALUE)) ); timePanelLayout.setVerticalGroup( timePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, timePanelLayout.createSequentialGroup() + .addGroup(timePanelLayout.createSequentialGroup() .addContainerGap() - .addComponent(processUnallocCheckbox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 15, Short.MAX_VALUE) .addComponent(timeLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(timeRadioButton1) @@ -317,7 +315,9 @@ public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfi .addComponent(timeRadioButton2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(timeRadioButton3) - .addContainerGap()) + .addGap(18, 18, 18) + .addComponent(processUnallocCheckbox) + .addContainerGap(8, Short.MAX_VALUE)) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -327,7 +327,7 @@ public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfi .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(servicesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 173, Short.MAX_VALUE) + .addComponent(servicesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 169, Short.MAX_VALUE) .addComponent(timePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) @@ -340,7 +340,7 @@ public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfi .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() - .addComponent(servicesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 90, Short.MAX_VALUE) + .addComponent(servicesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 82, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(timePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap()) diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java index 90f2a5ce90..3a86f4d54a 100755 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java @@ -960,15 +960,9 @@ public class IngestManager { stats.start(); //notify main thread services started - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - for (IngestServiceAbstractFile s : AbstractFileServices) { - IngestManager.fireServiceEvent(SERVICE_STARTED_EVT, s.getName()); - } - } - }); + for (IngestServiceAbstractFile s : AbstractFileServices) { + IngestManager.fireServiceEvent(SERVICE_STARTED_EVT, s.getName()); + } final String displayName = "File Ingest"; progress = ProgressHandleFactory.createHandle(displayName, new Cancellable() { @@ -1041,7 +1035,10 @@ public class IngestManager { @Override protected void done() { try { + Date d1 = new Date(); super.get(); //block and get all exceptions thrown while doInBackground() + Date d2 = new Date(); + logger.log(Level.INFO, "File ingest get() took: " + (d2.getTime()-d1.getTime()) ); //notify services of completion if (!this.isCancelled()) { for (IngestServiceAbstractFile s : AbstractFileServices) { diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.form b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.form index d5baf08ac5..53f8479c93 100644 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.form +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.form @@ -5,7 +5,9 @@ - + + +
diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.java index 5c1d9cc228..7a6f2bb9c0 100644 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.java +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.java @@ -145,6 +145,7 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing for (int i = 0; i < tcs.length; ++i) { if (tcs[i] == this) //already floating { + this.open(); return; } } diff --git a/KNOWN_ISSUES.txt b/KNOWN_ISSUES.txt index f51fcbe88d..acd6746a23 100644 --- a/KNOWN_ISSUES.txt +++ b/KNOWN_ISSUES.txt @@ -1,17 +1,18 @@ -Known issues and limitations + Known Issues -We plan to address the following issues in future releases. + Last Reviewed: June 12, 2012 -General: -- Only a single instance of the application can be started at once. -There is no check if another instance is already running. Running a second instance will cause issues. -- Only a single case can be opened at a time. -Keyword search module: -- Keyword search maximum size of files of known types to be indexed and searched is 100MB. -There is no limit on size of unknown file types indexed using string extraction. -- Currently we extract only English strings from files of unknown types. +This lists the bugs and issues thare are known and could effect +investigation results. There are other minor interface bugs that +are not listed here. -Installation: -- Installer version currently supports only Windows OS (XP or newer), -- Currently only 32 bit version of Autopsy is provided with the installer (works on 64 bit Windows OS) \ No newline at end of file +Keyword Search module: +- Slack space of files is not added to the index and therefore will +not be searched. +- Files larger than 100MB AND that are file types that are supported +by Tika (word docs, PDF, HTML, JPEG, etc.) are not being added to +the index. +- For unknown file types, we extract UTF-8 (Ascii) and UTF-16 English +strings. No non-English strings are extracted. +- Comments and java script in HTML files are not being added to index. diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java index 3e55f8d194..87f6436f76 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java @@ -37,6 +37,8 @@ import org.apache.commons.lang.StringEscapeUtils; import org.sleuthkit.autopsy.datamodel.HighlightLookup; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.ContentVisitor; +import org.sleuthkit.datamodel.Directory; /** * Displays marked-up (HTML) content for a Node. The sources are all the @@ -312,6 +314,19 @@ public class ExtractedContentViewer implements DataContentViewer { panel.setSources(sources); } } + + private class IsDirVisitor extends ContentVisitor.Default { + + @Override + protected Boolean defaultVisit(Content cntnt) { + return false; + } + + @Override + public Boolean visit(Directory d) { + return true; + } + } /** * Check if Solr has extracted content for a given node @@ -323,10 +338,17 @@ public class ExtractedContentViewer implements DataContentViewer { if (content == null) { return false; } + final Server solrServer = KeywordSearch.getServer(); + + boolean isDir = content.accept(new IsDirVisitor()); + if (isDir) + return false; final long contentID = content.getId(); + + try { return solrServer.queryIsIndexed(contentID); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java index 76bbd73161..b5a02f3559 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java @@ -114,6 +114,7 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec public void valueChanged(ListSelectionEvent e) { if (lsm.isSelectionEmpty() || currentKeywordList.isLocked()) { deleteWordButton.setEnabled(false); + return; } else { deleteWordButton.setEnabled(true); } @@ -529,6 +530,7 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec //add & reset checkbox tableModel.addKeyword(keyword); + KeywordSearchListsXML.getCurrent().addList(currentKeywordList); chRegex.setSelected(false); addWordField.setText(""); @@ -584,6 +586,7 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec private void deleteWordButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteWordButtonActionPerformed tableModel.deleteSelected(keywordTable.getSelectedRows()); + KeywordSearchListsXML.getCurrent().addList(currentKeywordList); initButtons(); }//GEN-LAST:event_deleteWordButtonActionPerformed @@ -693,11 +696,12 @@ private void useForIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt) listSelectionModel.setSelectionInterval(index, index); KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent(); - currentKeywordList = loader.getListsL().get(index); + currentKeywordList = loader.getListsL(false).get(index); tableModel.resync(); initButtons(); } else { currentKeywordList = null; + tableModel.resync(); initButtons(); } } @@ -737,6 +741,9 @@ private void useForIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt) @Override public Object getValueAt(int rowIndex, int columnIndex) { Object ret = null; + if(currentKeywordList == null) { + return ""; + } Keyword word = currentKeywordList.getKeywords().get(rowIndex); switch (columnIndex) { case 0: diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java index cfb57c5218..6b8f9f5f99 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java @@ -88,7 +88,7 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi private volatile boolean searcherDone = true; private Map> currentResults; private static final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(true); //use fairness policy - private static final Lock searcherLock = rwLock.writeLock(); + private static final Lock searcherLock = rwLock.writeLock(); private volatile int messageID = 0; private boolean processedFiles; private volatile boolean finalSearcherDone = true; @@ -99,7 +99,8 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi private enum IngestStatus { - INGESTED, EXTRACTED_INGESTED, SKIPPED,}; + INGESTED, EXTRACTED_INGESTED, SKIPPED, + }; private Map ingestStatus; /** @@ -161,18 +162,19 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi //logger.log(Level.INFO, "complete()"); commitTimer.stop(); - + //handle case if previous search running //cancel it, will re-run after final commit //note: cancellation of Searcher worker is graceful (between keywords) if (currentSearcher != null) { currentSearcher.cancel(false); - } - + } + //cancel searcher timer, ensure unwanted searcher does not start //before we start the final one - if (searchTimer.isRunning()) + if (searchTimer.isRunning()) { searchTimer.stop(); + } runSearcher = false; logger.log(Level.INFO, "Running final index commit and search"); @@ -181,7 +183,6 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi postIndexSummary(); - updateKeywords(); //run one last search as there are probably some new files committed if (keywords != null && !keywords.isEmpty() && processedFiles == true) { finalSearcher = new Searcher(keywords, true); //final searcher run @@ -208,10 +209,11 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi if (currentSearcher != null) { currentSearcher.cancel(true); } - + //cancel searcher timer, ensure unwanted searcher does not start - if (searchTimer.isRunning()) + if (searchTimer.isRunning()) { searchTimer.stop(); + } runSearcher = false; finalSearcherDone = true; @@ -324,8 +326,8 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi */ @Override public boolean hasBackgroundJobsRunning() { - if ( (currentSearcher != null && searcherDone == false) - || (finalSearcherDone == false)) { + if ((currentSearcher != null && searcherDone == false) + || (finalSearcherDone == false)) { return true; } else { return false; @@ -416,34 +418,10 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi } } - /** - * Retrieve the updated keyword search lists from the XML loader - */ - private void updateKeywords() { - KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent(); - - searcherLock.lock(); - try { - keywords.clear(); - keywordToList.clear(); - - for (String name : keywordLists) { - KeywordSearchList list = loader.getList(name); - for (Keyword k : list.getKeywords()) { - keywords.add(k); - keywordToList.put(k.getQuery(), list); - } - } - } - finally { - searcherLock.unlock(); - } - } - List getKeywordLists() { return keywordLists == null ? new ArrayList() : keywordLists; } - + /** * Check if time to commit, if so, run commit. * Then run search if search timer is also set. @@ -458,7 +436,6 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi //NOTE commit/searcher timings don't need to align //in worst case, we will run search next time after commit timer goes off, or at the end of ingest if (searcherDone && runSearcher) { - updateKeywords(); //start search if previous not running if (keywords != null && !keywords.isEmpty()) { currentSearcher = new Searcher(keywords); @@ -483,7 +460,7 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi } } - /** + /** * SearchTimerAction to run by searchTimer * Sets a flag to indicate we are ready to search */ @@ -590,7 +567,6 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi this(keywords); this.finalRun = finalRun; } - @Override protected Object doInBackground() throws Exception { @@ -621,10 +597,13 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi //make sure other searchers are not spawned searcherDone = false; runSearcher = false; - if (searchTimer.isRunning()) + if (searchTimer.isRunning()) { searchTimer.stop(); + } int numSearched = 0; + + updateKeywords(); progress.switchToDeterminate(keywords.size()); for (Keyword keywordQuery : keywords) { @@ -822,21 +801,37 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi } //end try block catch (Exception ex) { logger.log(Level.WARNING, "searcher exception occurred", ex); - } - finally { + } finally { finalizeSearcher(); searcherLock.unlock(); } return null; } - - + + /** + * Retrieve the updated keyword search lists from the XML loader + */ + private void updateKeywords() { + KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent(); + + keywords.clear(); + keywordToList.clear(); + + for (String name : keywordLists) { + KeywordSearchList list = loader.getList(name); + for (Keyword k : list.getKeywords()) { + keywords.add(k); + keywordToList.put(k.getQuery(), list); + } + } + + + } //perform all essential cleanup that needs to be done right AFTER doInBackground() returns //without relying on done() method that is not guaranteed to run after background thread completes //NEED to call this method always right before doInBackground() returns - /** * Performs the cleanup that needs to be done right AFTER doInBackground() returns * without relying on done() method that is not guaranteed to run after background thread completes @@ -864,12 +859,12 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi currentResults = new HashMap>(); managerProxy.postMessage(IngestMessage.createMessage(++messageID, MessageType.INFO, KeywordSearchIngestService.instance, "Completed")); - } - else { + } else { //start counting time for a new searcher to start //unless final searcher is pending - if (finalSearcher != null) - searchTimer.start(); + if (finalSearcher != null) { + searchTimer.start(); + } } } } @@ -899,7 +894,7 @@ public final class KeywordSearchIngestService implements IngestServiceAbstractFi void setSkipKnown(boolean skip) { this.skipKnown = skip; } - + boolean getSkipKnown() { return skipKnown; } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsAbstract.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsAbstract.java index 82fdb4dce5..ddd86c02f5 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsAbstract.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsAbstract.java @@ -127,14 +127,40 @@ public abstract class KeywordSearchListsAbstract { } return ret; } + + List getListsL(boolean locked) { + List ret = new ArrayList(); + for (KeywordSearchList list : theLists.values()) { + if(list.isLocked().equals(locked)) { + ret.add(list); + } + } + return ret; + } /** - * get list of all loaded keyword list names + * Get list names of all loaded keyword list names * @return List of keyword list names */ List getListNames() { return new ArrayList(theLists.keySet()); } + + /** + * Get list names of all locked or unlocked loaded keyword list names + * @param locked true if look for locked lists, false otherwise + * @return List of keyword list names + */ + List getListNames(boolean locked) { + ArrayList lists = new ArrayList(); + for (String listName : theLists.keySet()) { + KeywordSearchList list = theLists.get(listName); + if (locked == list.isLocked()) + lists.add(listName); + } + + return lists; + } /** * return first list that contains the keyword @@ -175,6 +201,21 @@ public abstract class KeywordSearchListsAbstract { int getNumberLists() { return theLists.size(); } + + /** + * get number of unlocked or locked lists currently stored + * @param locked true if look for locked lists, false otherwise + * @return number of unlocked lists currently stored + */ + int getNumberLists(boolean locked) { + int numLists = 0; + for (String listName : theLists.keySet()) { + KeywordSearchList list = theLists.get(listName); + if (locked == list.isLocked()) + ++ numLists; + } + return numLists; + } /** * get list by name or null @@ -231,6 +272,10 @@ public abstract class KeywordSearchListsAbstract { boolean addList(String name, List newList) { return addList(name, newList, true, true); } + + boolean addList(KeywordSearchList list) { + return addList(list.getName(), list.getKeywords(), list.getUseForIngest(), list.getIngestMessages(), list.isLocked()); + } /** * write out multiple lists diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java index 08b69b1a6f..6fa2ce3951 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java @@ -93,8 +93,6 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel { listsTable.getSelectionModel().setSelectionInterval(0, 0); else listsTable.getSelectionModel().clearSelection(); - } else if (evt.getPropertyName().equals(KeywordSearchListsXML.ListsEvt.LIST_UPDATED.toString())) { - tableModel.resync(); //changed list name } } }); @@ -192,9 +190,18 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel { } boolean shouldAdd = false; if (writer.listExists(listName)) { - boolean replace = KeywordSearchUtil.displayConfirmDialog("New Keyword List", "Keyword List <" + listName + "> already exists, do you want to replace it?", KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN); - if (replace) { - shouldAdd = true; + if (writer.getList(listName).isLocked() ) { + boolean replace = KeywordSearchUtil.displayConfirmDialog("New Keyword List", "Keyword List <" + listName + + "> already exists as a read-only list. Do you want to replace it for the duration of the program (the change will not be persistent).", KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN); + if (replace) { + shouldAdd = true; + } + } + else { + boolean replace = KeywordSearchUtil.displayConfirmDialog("New Keyword List", "Keyword List <" + listName + "> already exists, do you want to replace it?", KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN); + if (replace) { + shouldAdd = true; + } } } else { shouldAdd = true; @@ -323,7 +330,7 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel { @Override public int getRowCount() { - return listsHandle.getNumberLists(); + return listsHandle.getNumberLists(false); } @Override @@ -333,7 +340,7 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel { @Override public Object getValueAt(int rowIndex, int columnIndex) { - return listsHandle.getListNames().get(rowIndex); + return listsHandle.getListNames(false).get(rowIndex); } @Override diff --git a/NEWS.txt b/NEWS.txt index 2bdc2f48a7..081431d045 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,7 +1,7 @@ -3.0.0b3 (June X, 2012) -New Features: +3.0.0b3 (June 12, 2012) +New Features (Funded by US Army Intelligence Center of Excellence (USAICoE)): - Ingest manager runs triage/ingest task after disk is added. -- Keyword search (indexed via SOLR) +- Basic keyword search (indexed via SOLR) - Recent activity extract (web artifacts, recent documents, devices, etc.) - Improved UI diff --git a/README.txt b/README.txt index c7691a9b09..ca546bd46e 100644 --- a/README.txt +++ b/README.txt @@ -21,61 +21,71 @@ There is no need for manual installation of additional dependencies if the insta Refer to the next section for additional info on third-party software requirements to run Autopsy without installer. +Refer to the KNOWN_ISSUES.txt file for known bugs that could cause investigation problems. + + +SUPPORT + +There is a built-in help system in Autopsy once you get it started. There is also a QuickStart Guide that came +with the installer. + +Send any bug reports or feature requests to the sleuthkit-users e-mail list. + http://www.sleuthkit.org/support.php + + +LICENSE + +The Autopsy code is released under the Apache License, Version 2. See LICENSE-2.0.txt for details. + EMBEDDED SOFTWARE -Autopsy (core) utilizes the following third-party software tools. -The tools are bundled with the installer, unless specified otherwise. +This section lists the software components and libraries that are used inside of +Autopsy. These tools are bundled with the installer, unless specified otherwise. -* JRE (Java Runtime Environment) 1.6, 32 bit +JRE (Java Runtime Environment) 1.6, 32 bit +- Web page: http://www.oracle.com/technetwork/java/index.html +- License: http://www.oracle.com/technetwork/java/javase/terms/license/index.html -Web page: http://www.oracle.com/technetwork/java/index.html -Oracle license: http://www.oracle.com/technetwork/java/javase/terms/license/index.html - -JRE needs to be manually installed on the system if Autopsy installer is not used. - -* Netbeans 7.0.1 RCP platform and .jar files bundled with the platform - -Web page: http://netbeans.org/features/platform/ -License: +Netbeans 7.0.1 RCP platform and .jar files bundled with the platform +- Web page: http://netbeans.org/features/platform/ +- License: http://services.netbeans.org/downloads/licence/nb-7.0-final-2011-04-20-license.txt -* Solr (including Lucene and TIKA) -Web page: http://projects.apache.org/projects/solr.html -Apache license: http://www.apache.org/licenses/LICENSE-2.0 +Sleuth Kit for analyzing disk images. +- Web page: http://www.sleuthkit.org/sleuthkit/ +- License: http://sleuthkit.org/sleuthkit/licenses.php -* GStreamer -Web page: http://gstreamer.freedesktop.org/ -License: http://www.gnu.org/licenses/lgpl.html +Libewf for opening E01 files +- Web page: http://sourceforge.net/projects/libewf/ +- License: http://www.gnu.org/licenses/lgpl.html -If Autopsy installer is not used, add the following entries to Windows PATH environment variable -(replace GSTREAMER_INSTALL_DIR with the location of gstreamer install root directory): +zlib for opening E01 files +- Web page: http://zlib.net/ +- License: http://zlib.net/zlib_license.html -GSTREAMER_INSTALL_DIR\bin\; -GSTREAMER_INSTALL_DIR\lib\gstreamer-0.10\; +Solr (including Lucene and TIKA) for keyword search +- Web page: http://projects.apache.org/projects/solr.html +- License: http://www.apache.org/licenses/LICENSE-2.0 +GStreamer for viewing video files +- Web page: http://gstreamer.freedesktop.org/ +- License: http://www.gnu.org/licenses/lgpl.html -* GStreamer-java -Web page: http://code.google.com/p/gstreamer-java/ -License: http://www.gnu.org/licenses/lgpl.html +GStreamer-java for viewing video files +- Web page: http://code.google.com/p/gstreamer-java/ +- License: http://www.gnu.org/licenses/lgpl.html +Regripper for pulling recently activity +(Including custom plugins) +- Web page: http://regripper.wordpress.com/ +- License: http://www.gnu.org/licenses/gpl.html -* Regripper -(regripper and custom plugins found in autopsy/thirdparty) -Web page: http://regripper.wordpress.com/ -License: http://www.gnu.org/licenses/gpl.html +Pasco2 for pulling Internet Explorer activity +- Web page: http://sourceforge.net/projects/pasco2/ +- License: http://www.gnu.org/licenses/gpl.html -* Pasco -Web page: http://sourceforge.net/projects/odessa/files/Pasco/ - -* Advanced installer 9.0 (Freeware) +Advanced installer 9.0 (Freeware) (not embedded in Autopsy, but used to generate Autopsy installer.) -If you want to generate Autopsy installer, you will need to install the freeware version of Advanced Installer software) +- Web page: http://www.advancedinstaller.com/ -Web page: http://www.advancedinstaller.com/ - - -FEEDBACK - -Send any bug reports or feature requests to the sleuthkit-users e-mail list. - http://www.sleuthkit.org/support.php \ No newline at end of file diff --git a/build-unix.xml b/build-unix.xml index b13b938a3f..256817c681 100644 --- a/build-unix.xml +++ b/build-unix.xml @@ -1,11 +1,28 @@ - - - - + + + + - + + + + + + + + + + + + + + + + + + + diff --git a/build-windows.xml b/build-windows.xml index 7ce153c278..9c1d5ff057 100755 --- a/build-windows.xml +++ b/build-windows.xml @@ -3,7 +3,7 @@ Release - + @@ -15,7 +15,7 @@ - + ${env.TSK_HOME}/win32/tsk_jni/${TSK_BUILD_TYPE}/libtsk_jni.dll.intermediate.manifest @@ -44,9 +44,9 @@ - + value="C:\Program Files (x86)\Caphyon\Advanced Installer 9.2\bin\x86\AdvancedInstaller.com"/> diff --git a/build.xml b/build.xml index dfa13f8a4e..41d3041beb 100644 --- a/build.xml +++ b/build.xml @@ -51,7 +51,7 @@ - + @@ -77,7 +77,7 @@ - + diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 9808239a10..bd7f249337 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -883,7 +883,7 @@ GENERATE_HTML = YES # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. -HTML_OUTPUT = +HTML_OUTPUT = api-docs # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank diff --git a/installer_autopsy/installer_autopsy.aip b/installer_autopsy/installer_autopsy.aip index 52feac8f8d..2430baf71d 100644 --- a/installer_autopsy/installer_autopsy.aip +++ b/installer_autopsy/installer_autopsy.aip @@ -1,4883 +1,4838 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +