This commit is contained in:
U-BASIS\smoss 2013-06-05 11:24:59 -04:00
commit b467db95ca
53 changed files with 897 additions and 287 deletions

View File

@ -105,10 +105,10 @@ public class AddImageLoadingPanel extends javax.swing.JPanel {
void setErrors(final String errors, boolean critical) {
crDbProgressBar.setValue(100); //always invoked when process completed
if (critical) {
progressLabel.setText("*Failed to add image (critical errors encountered). Click below to view the Add Image Log.");
progressLabel.setText("*Failed to add image (critical errors encountered). Click below to view the log.");
}
else {
progressLabel.setText("*Image added (non-critical image errors encountered). Click below to view the Add Image Log.");
progressLabel.setText("*Data Source added (non-critical errors encountered). Click below to view the log.");
}
errorButton = new JButton();
errorButton.setText("View Log");

View File

@ -103,6 +103,9 @@
<StringArray count="0"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JCheckBox" name="noFatOrphansCheckbox">
<Properties>
@ -200,6 +203,9 @@
<StringArray count="0"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;ContentTypePanel&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>

View File

@ -57,7 +57,7 @@ final class AddImageVisualPanel1 extends JPanel {
private AddImageWizardPanel1 wizPanel;
private ContentTypeModel model;
ContentTypePanel currentPanel;
private ContentTypePanel currentPanel;
/**
* Creates new form AddImageVisualPanel1
@ -231,13 +231,13 @@ final class AddImageVisualPanel1 extends JPanel {
jLabel2 = new javax.swing.JLabel();
nextLabel = new javax.swing.JLabel();
timeZoneLabel = new javax.swing.JLabel();
timeZoneComboBox = new javax.swing.JComboBox();
timeZoneComboBox = new javax.swing.JComboBox<String>();
noFatOrphansCheckbox = new javax.swing.JCheckBox();
descLabel = new javax.swing.JLabel();
inputPanel = new javax.swing.JPanel();
typeTabel = new javax.swing.JLabel();
typePanel = new javax.swing.JPanel();
typeComboBox = new javax.swing.JComboBox();
typeComboBox = new javax.swing.JComboBox<ContentTypePanel>();
imgInfoLabel = new javax.swing.JLabel();
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.jLabel2.text")); // NOI18N
@ -355,9 +355,9 @@ final class AddImageVisualPanel1 extends JPanel {
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel nextLabel;
private javax.swing.JCheckBox noFatOrphansCheckbox;
private javax.swing.JComboBox timeZoneComboBox;
private javax.swing.JComboBox<String> timeZoneComboBox;
private javax.swing.JLabel timeZoneLabel;
private javax.swing.JComboBox typeComboBox;
private javax.swing.JComboBox<ContentTypePanel> typeComboBox;
private javax.swing.JPanel typePanel;
private javax.swing.JLabel typeTabel;
// End of variables declaration//GEN-END:variables
@ -377,9 +377,10 @@ final class AddImageVisualPanel1 extends JPanel {
/**
* ComboBoxModel to control typeComboBox and supply ImageTypePanels.
*/
private class ContentTypeModel implements ComboBoxModel {
ContentTypePanel selected;
ContentTypePanel[] types = ContentTypePanel.getPanels();
private class ContentTypeModel implements ComboBoxModel<ContentTypePanel> {
private ContentTypePanel selected;
private ContentTypePanel[] types = ContentTypePanel.getPanels();
@Override
public void setSelectedItem(Object anItem) {
@ -398,7 +399,7 @@ final class AddImageVisualPanel1 extends JPanel {
}
@Override
public Object getElementAt(int index) {
public ContentTypePanel getElementAt(int index) {
return types[index];
}

View File

@ -23,7 +23,7 @@ import java.awt.BorderLayout;
import javax.swing.JPanel;
/**
* Image added, ingest configure wizard visual panel 3
* Data Source added, ingest configure wizard visual panel 3
*/
public class AddImageVisualPanel3 extends javax.swing.JPanel {
private JPanel ingestPanel = null;

View File

@ -29,7 +29,7 @@ import org.openide.util.HelpCtx;
import org.openide.util.Lookup;
/**
* The "Add Image" wizard panel2. Handles processing the image in a worker
* The "Add Data Source" wizard panel2. Handles processing the image in a worker
* thread, and any errors that may occur during the add process.
*/
class AddImageWizardPanel2 implements WizardDescriptor.Panel<WizardDescriptor> {
@ -90,7 +90,7 @@ class AddImageWizardPanel2 implements WizardDescriptor.Panel<WizardDescriptor> {
*/
void setStateStarted() {
component.getCrDbProgressBar().setIndeterminate(true);
component.changeProgressBarTextAndColor("*Adding the image may take some time for large images.", 0, Color.black);
component.changeProgressBarTextAndColor("*This process take some time for large data sources.", 0, Color.black);
}
/**

View File

@ -570,7 +570,7 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
cleanupImage.enable();
if (errorString == null) { // complete progress bar
wizPanel.getComponent().changeProgressBarTextAndColor("*Image added.", 100, Color.black);
wizPanel.getComponent().changeProgressBarTextAndColor("*Data Source added.", 100, Color.black);
}
// Get attention for the process finish

View File

@ -94,9 +94,6 @@ NewJPanel.jFormattedTextField1.text=jFormattedTextField1
NewJPanel.jButton1.text=Rename
NewJPanel.jLabel4.text=Database:
AddImageVisualPanel2.indexImageCheckBox.text=Index image for keyword search
AddImageVisualPanel4.jLabel1.text=Image was successfully added to the case and is being processed.
AddImageVisualPanel4.crDbLabel.text=Image Added and Being Processed
AddImageVisualPanel4.addImgButton.text=Add Another Image
AddImageVisualPanel3.titleLabel.text=Configure Ingest Modules
AddImageVisualPanel3.subtitleLabel.text=Configure the ingest modules you would like to run on this data source.
CasePropertiesForm.caseNumberLabel.text=Case Number:
@ -132,12 +129,12 @@ MissingImageDialog.cancelButton.text=Cancel
LocalDiskPanel.errorLabel.text=Error Label
AddImageVisualPanel1.typeTabel.text=Select source type to add:
AddImageVisualPanel1.imgInfoLabel.text=Enter Data Source Information:
AddImageLoadingPanel.crDbLabel.text=Adding Image
AddImageLoadingPanel.crDbLabel.text=Adding Data Source
AddImageLoadingPanel.Label_CurrentDirectory_Static.text=Currently Processing:
AddImageLoadingPanel.jLabel5.text=Processing Image and Adding to Database
AddImageLoadingPanel.jLabel5.text=Processing Data Source and Adding to Database
AddImageLoadingPanel.jLabel1.text=File system information is being added to a local database. File analysis will start when this finishes.
AddImageDonePanel.statusLabel.text=File system has been added to the local database. Files are being analyzed.
AddImageDonePanel.crDbLabel.text=Adding Image - Complete
AddImageDonePanel.crDbLabel.text=Adding Data Source - Complete
LocalFilesPanel.infoLabel.text=Add local files and folders:
LocalFilesPanel.selectButton.text=Add
LocalFilesPanel.localFileChooser.dialogTitle=Select Local Files or Folders

View File

@ -75,7 +75,7 @@ public final class CasePropertiesAction extends CallableSystemAction {
int totalImage = currentCase.getRootObjectsCount();
// put the image paths information into hashmap
Map<Long, String> imgPaths = currentCase.getImagePaths(currentCase.getSleuthkitCase());
Map<Long, String> imgPaths = Case.getImagePaths(currentCase.getSleuthkitCase());
// create the case properties form
CasePropertiesForm cpf = new CasePropertiesForm(currentCase, crDate, caseDir, imgPaths);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -1,35 +1,51 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Disk Image Basics</title>
<title>Data Source Basics</title>
<link rel="stylesheet" href="nbdocs:/org/sleuthkit/autopsy/core/docs/ide.css" type="text/css">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h2>About Disk Images</h2>
<h2>About Data Sources</h2>
<p>
In Autopsy, an "image" refers to a byte-for-byte copy of a hard drive or other storage media.
To analyze an image, you must use the <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/addImage.html">Add Image Wizard</a>
Autopsy supports 3 types of data sources that can be added to the Case:</p>
<ul>
<li>Disk Image (raw, Encase, etc).
"Image" refers to a byte-for-byte copy of a hard drive or other storage media.
</li>
<li>Disk Device (physical or logical disk partition, plugged in the user machine and detected by Autopsy).
Note: to correctly detect all devices, Autopsy needs to run as Administrator.
</li>
<li>Logical Files (files and folders on the user machine file system)</li>
</ul>
<p>
User needs to select the data source type from the pull down menu in the Add Data Source wizard.
</p>
<p>
To analyze a Data Source, user should use the <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/addImage.html">Add Data Source Wizard</a>
to add it to a <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/casemodule-about.html">case</a>.
</p>
<p>
Autopsy populates an embedded database for each image that it imports.
This database is a SQLite database and it contains all of the file system metadata from the image.
The database is stored in the case directory, but the image will stay in its original location.
The image must remain accessible for the duration of the analysis because the database contains only basic file system information.
The image is needed to retrieve file content.
Autopsy populates an embedded database for each data source (image, disk device, logical files) that it imports.
This database is a SQLite database and it contains all of the file system metadata from the input data source.
The database is stored in the case directory, but the data source will stay in its original location.
The data source must remain accessible for the duration of the analysis because the database contains only basic file system information (meta-data, not the actual content).
The image / files are needed to retrieve file content.
</p>
<h2>Supported Formats</h2>
<h2>Supported Image Formats</h2>
<p>Currently, Autopsy supports these image formats:</p>
<ul>
<li>Raw Single (For example: *.img, *.dd, etc)</li>
<li>Raw Single (For example: *.img, *.dd, *.raw, etc)</li>
<li>Raw Split (For example: *.001, *.002, *.aa, *.ab, etc)</li>
<li>EnCase (For example: *.e01, *e02, etc)</li>
</ul>
<h2>Removing an Image</h2>
<p>You cannot currently remove an image from a case.</p>
<h2>Removing a Data Source</h2>
<p>You cannot currently remove an data source from a case.</p>
</body>
</html>

View File

@ -1,23 +1,27 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Adding Image Wizard</title>
<title>Adding Data Source (Image, Disk, Files) Wizard</title>
<link rel="stylesheet" href="nbdocs:/org/sleuthkit/autopsy/core/docs/ide.css" type="text/css">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h2>Adding An Image</h2>
<p>There are two ways to add an image to the currently opened case:</p>
<h2>Adding a Data Source</h2>
<p>There are two ways to add an data source to the currently opened case:</p>
<ul>
<li>Go to "File" and select "Add Image..." </li>
<li>Go to "File" and select "Add Data Source..." </li>
<li>Select the <img src="addImage-icon.png" alt="Add Image Icon" /> icon on the toolbar</li>
</ul>
<p>This will bring up the Add Image wizard. It will guide you through the process.</p>
<p>This will bring up the Add Data Source wizard. It will guide you through the process.</p>
<p>Here are some notes on what is going on during the process:</p>
<ul>
<li>
The first panel will ask you to browse for the image on your machine.
You will also need to specify the timezone that the disk image came from so that the dates and times can be properly displayed and converted.
The first panel will ask you to select the data source type and
browse for the data source (image or files located on the computer, or select the device detected).
In case of adding a disk image, you will also need to specify the timezone that the disk image came from
so that the dates and times can be properly displayed and converted.
As soon as you click 'Next >', Autopsy will begin analyzing the disk image and populating the database in the background.
<br />
<img src="AddImageWizard1_Help.png" alt="Add Image Wizard Panel 1 Help" />
@ -29,21 +33,21 @@
<img src="AddImageWizard2_Help.png" alt="Add Image Wizard Panel 3 Help" />
</li>
<li>
The third panel provides a progress bar and information about the image Autopsy is currently processing.
If small enough, the image may have already finished processing, allowing you to continue past this panel.
The third panel provides a progress bar and information about the data source Autopsy is currently processing.
If small enough, the input may have already finished processing, allowing you to continue past this panel.
However, it may be necessary to wait for a short time while the database is populated.
<br />
<img src="AddImageWizard3_Help.png" alt="Add Image Wizard Panel 2 Help" />
</li>
<li>
Once the image finishes adding, the ingest modules you selected will automatically run in the background.
If the image is processed before you select ingest modules, Autopsy will wait until you have done so.
Once the input data source finishes adding, the ingest modules you selected will automatically run in the background.
If the data source is processed before you select ingest modules, Autopsy will wait until you have done so.
</li>
</ul>
</p>
<p>
Note that Autopsy will store the path to the image in its configuration file.
If the image moves, then Autopsy will give an error because it can't find the image file.
Note that in case of image, Autopsy will store the path to the image in its configuration file.
If the image moves, then Autopsy will give an error because it can't find the image file and it will prompt user to point to the new image location.
</p>
</body>
</html>

View File

@ -8,8 +8,8 @@
<body>
<h2>About Cases</h2>
<p>
In Autopsy, a "case" is a container concept for a set of <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/aboutImage.html">images</a>.
The set of images could be from multiple drives in a single computer or from multiple computers.
In Autopsy, a "case" is a container concept for a set of <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/aboutImage.html">input data sources (disk images, disk devices, logical files)</a>.
The set of data could be from multiple drives in a single computer or from multiple computers.
When you make a case, it will create a directory to hold all of the information.
The directory will contain the main Autopsy configuration file, other module's configuration files,
some databases, generated reports, and some other information (temporary files, cache files).

View File

@ -9,8 +9,8 @@ and open the template in the editor.
<indexitem text="Quick Start" target="org.sleuthkit.autopsy.casemodule.quickstart"/>
<indexitem text="About Cases" target="org.sleuthkit.autopsy.casemodule.about"/>
<indexitem text="Creating a Case" target="org.sleuthkit.autopsy.casemodule.how-to-create-case"/>
<indexitem text="About Images" target="org.sleuthkit.autopsy.casemodule.image-about"/>
<indexitem text="Adding an Image" target="org.sleuthkit.autopsy.casemodule.add-image"/>
<indexitem text="About Data Sources" target="org.sleuthkit.autopsy.casemodule.image-about"/>
<indexitem text="Adding a Data Source" target="org.sleuthkit.autopsy.casemodule.add-image"/>
<indexitem text="Case Properties Window" target="org.sleuthkit.autopsy.casemodule.caseproperties"/>
<indexitem text="Hash Database Management" target="org.sleuthkit.autopsy.casemodule.hashdbmgmt"/>
</index>

View File

@ -12,9 +12,9 @@ and open the template in the editor.
<tocitem text="About Cases" target="org.sleuthkit.autopsy.casemodule.about"/>
<tocitem text="Creating a Case" target="org.sleuthkit.autopsy.casemodule.how-to-create-case"/>
</tocitem>
<tocitem text="Image">
<tocitem text="About Images" target="org.sleuthkit.autopsy.casemodule.image-about"/>
<tocitem text="Adding an Image" target="org.sleuthkit.autopsy.casemodule.add-image"/>
<tocitem text="Data Source">
<tocitem text="About Data Source" target="org.sleuthkit.autopsy.casemodule.image-about"/>
<tocitem text="Adding a Data Source" target="org.sleuthkit.autopsy.casemodule.add-image"/>
</tocitem>
<tocitem text="Case Properties Window" target="org.sleuthkit.autopsy.casemodule.caseproperties"/>
<tocitem text="Hash Database Management Window" target="org.sleuthkit.autopsy.casemodule.hashdbmgmt"/>

View File

@ -14,7 +14,7 @@
The remainder of the help guide is organized around these concepts.
</p>
<p>
The main Autopsy features include: importing and image and exploring its file systems,
The main Autopsy features include: importing a Data Source (image, disk, files) and exploring its file systems,
running analysis modules (ingest), viewing ingest results, viewing content and generating reports.
</p>
<p>
@ -24,7 +24,7 @@
</p>
<p>
All data is organized around the concept of a <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/casemodule-about.html">case</a>.
A case can have one or more disk <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/aboutImage.html">images</a> loaded into it.
A case can have one or more data <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/aboutImage.html">sources</a> loaded into it.
</p>
<p>The main window has three major areas:</p>
<ul>

View File

@ -177,20 +177,22 @@ public class FileManager implements Closeable {
* Adds a carved file to the VirtualDirectory '$CarvedFiles' in the volume
* or file system given by systemId.
*
* @param name the name of the carved file (containing appropriate
* @param carvedFileName the name of the carved file (containing appropriate
* extension)
* @param carvedFileSize size of the carved file to add
* @param systemId the ID of the parent volume or file system
* @param sectors a list of SectorGroups giving this sectors that make up
* this carved file.
* @throws TskCoreException exception thrown when critical tsk error occurred and carved file could not be added
*/
public synchronized LayoutFile addCarvedFile(String carvedFileName, long carvedFileSize,
long systemId, List<TskFileRange> data) throws TskCoreException {
long systemId, List<TskFileRange> sectors) throws TskCoreException {
if (tskCase == null) {
throw new TskCoreException("Attempted to use FileManager after it was closed.");
}
return tskCase.addCarvedFile(carvedFileName, carvedFileSize, systemId, data);
return tskCase.addCarvedFile(carvedFileName, carvedFileSize, systemId, sectors);
}
/**

View File

@ -418,7 +418,7 @@ public class PlatformUtil {
/**
* Query and get PID of another java process
*
* @sigarSubQuery a sigar subquery to identify a unique java process among
* @param sigarSubQuery a sigar subquery to identify a unique java process among
* other java processes, for example, by class name, use:
* Args.*.eq=org.jboss.Main more examples here:
* http://support.hyperic.com/display/SIGAR/PTQL
@ -448,7 +448,7 @@ public class PlatformUtil {
/**
* Query and get PIDs of another java processes matching a query
*
* @sigarSubQuery a sigar subquery to identify a java processes among other
* @param sigarSubQuery a sigar subquery to identify a java processes among other
* java processes, for example, by class name, use: Args.*.eq=org.jboss.Main
* more examples here: http://support.hyperic.com/display/SIGAR/PTQL
*

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.datamodel;
import org.openide.nodes.AbstractNode;
@ -39,14 +38,14 @@ import org.sleuthkit.datamodel.Volume;
/**
* Abstract subclass for ContentChildren and RootContentChildren implementations
* that handles creating Nodes from Content objects.
*/
*/
abstract class AbstractContentChildren<T> extends Keys<T> {
private final CreateSleuthkitNodeVisitor createSleuthkitNodeVisitor = new CreateSleuthkitNodeVisitor();
private final CreateAutopsyNodeVisitor createAutopsyNodeVisitor = new CreateAutopsyNodeVisitor();
/**
* Uses lazy Content.Keys
* Uses lazy Content.Keys
*/
AbstractContentChildren() {
super(true); // use lazy behavior
@ -54,21 +53,18 @@ abstract class AbstractContentChildren<T> extends Keys<T> {
@Override
protected Node[] createNodes(T key) {
if(key instanceof SleuthkitVisitableItem) {
if (key instanceof SleuthkitVisitableItem) {
return new Node[]{((SleuthkitVisitableItem) key).accept(createSleuthkitNodeVisitor)};
}
else {
} else {
return new Node[]{((AutopsyVisitableItem) key).accept(createAutopsyNodeVisitor)};
}
}
/**
* Creates appropriate Node for each sub-class of Content
*/
public static class CreateSleuthkitNodeVisitor extends SleuthkitItemVisitor.Default<AbstractContentNode> {
@Override
public AbstractContentNode visit(Directory drctr) {
return new DirectoryNode(drctr);
@ -88,22 +84,22 @@ abstract class AbstractContentChildren<T> extends Keys<T> {
public AbstractContentNode visit(Volume volume) {
return new VolumeNode(volume);
}
@Override
public AbstractContentNode visit(LayoutFile lf) {
return new LayoutFileNode(lf);
}
@Override
public AbstractContentNode visit(DerivedFile df) {
return new LocalFileNode(df);
}
@Override
public AbstractContentNode visit(LocalFile lf) {
return new LocalFileNode(lf);
}
@Override
public AbstractContentNode visit(VirtualDirectory ld) {
return new VirtualDirectoryNode(ld);
@ -114,53 +110,57 @@ abstract class AbstractContentChildren<T> extends Keys<T> {
throw new UnsupportedOperationException("No Node defined for the given SleuthkitItem");
}
}
/**
* Creates appropriate Node for each supported artifact category / grouping
*/
static class CreateAutopsyNodeVisitor extends AutopsyItemVisitor.Default<AbstractNode> {
@Override
public ExtractedContentNode visit(ExtractedContent ec) {
return new ExtractedContentNode(ec.getSleuthkitCase());
}
@Override
public AbstractNode visit(SearchFilters sf) {
return new SearchFiltersNode(sf.getSleuthkitCase(), true);
return new SearchFiltersNode(sf.getSleuthkitCase(), null);
}
@Override
public AbstractNode visit(RecentFiles rf) {
return new RecentFilesNode(rf.getSleuthkitCase());
}
@Override
public AbstractNode visit(DeletedContent dc) {
return new DeletedContent.DeletedContentsNode(dc.getSleuthkitCase());
}
@Override
public AbstractNode visit(FileSize dc) {
return new FileSize.FileSizeRootNode(dc.getSleuthkitCase());
}
@Override
public AbstractNode visit(KeywordHits kh) {
return kh.new KeywordHitsRootNode();
}
@Override
public AbstractNode visit(HashsetHits hh) {
return hh.new HashsetHitsRootNode();
}
@Override
public AbstractNode visit(EmailExtracted ee) {
return ee.new EmailExtractedRootNode();
}
@Override
public AbstractNode visit(Tags t) {
return t.new TagsRootNode();
}
@Override
public AbstractNode visit(DataSources i) {
try {
@ -169,12 +169,12 @@ abstract class AbstractContentChildren<T> extends Keys<T> {
return defaultVisit(i);
}
}
@Override
public AbstractNode visit(Views v) {
return new ViewsNode(v.getSleuthkitCase());
}
@Override
public AbstractNode visit(Results r) {
return new ResultsNode(r.getSleuthkitCase());
@ -185,5 +185,4 @@ abstract class AbstractContentChildren<T> extends Keys<T> {
throw new UnsupportedOperationException("No Node defined for the given DisplayableItem");
}
}
}

View File

@ -23,98 +23,132 @@ package org.sleuthkit.autopsy.datamodel;
* @author dfickling
*/
public interface AutopsyItemVisitor<T> {
T visit(ExtractedContent ec);
T visit(SearchFilters sf);
T visit(SearchFilters.FileSearchFilter fsf);
T visit(SearchFilters.DocumentFilter df);
T visit(SearchFilters.ExecutableFilter ef);
T visit(RecentFiles rf);
T visit(RecentFiles.RecentFilesFilter rff);
T visit(DeletedContent dc);
T visit(DeletedContent.DeletedContentFilter dcf);
T visit(FileSize fs);
T visit(FileSize.FileSizeFilter fsf);
T visit(KeywordHits kh);
T visit(HashsetHits hh);
T visit(EmailExtracted ee);
T visit(Tags t);
T visit(DataSources i);
T visit(Views v);
T visit(Results r);
static abstract public class Default<T> implements AutopsyItemVisitor<T> {
protected abstract T defaultVisit(AutopsyVisitableItem ec);
@Override
public T visit(ExtractedContent ec) {
return defaultVisit(ec);
}
@Override
public T visit(SearchFilters sf) {
return defaultVisit(sf);
}
@Override
public T visit(SearchFilters.FileSearchFilter fsf) {
return defaultVisit(fsf);
}
@Override
public T visit(SearchFilters.DocumentFilter df) {
return defaultVisit(df);
}
@Override
@Override
public T visit(SearchFilters.ExecutableFilter ef) {
return defaultVisit(ef);
}
@Override
public T visit(DeletedContent dc) {
return defaultVisit(dc);
}
@Override
public T visit(DeletedContent.DeletedContentFilter dcf) {
return defaultVisit(dcf);
}
@Override
public T visit(FileSize fs) {
return defaultVisit(fs);
}
@Override
public T visit(FileSize.FileSizeFilter fsf) {
return defaultVisit(fsf);
}
@Override
public T visit(RecentFiles rf) {
return defaultVisit(rf);
}
@Override
public T visit(RecentFiles.RecentFilesFilter rff) {
return defaultVisit(rff);
}
@Override
public T visit(KeywordHits kh) {
return defaultVisit(kh);
}
@Override
public T visit(HashsetHits hh) {
return defaultVisit(hh);
}
@Override
public T visit(EmailExtracted ee) {
return defaultVisit(ee);
}
@Override
public T visit(Tags t) {
return defaultVisit(t);
}
@Override
public T visit(DataSources i) {
return defaultVisit(i);
}
@Override
public T visit(Views v) {
return defaultVisit(v);
}
@Override
public T visit(Results r) {
return defaultVisit(r);

View File

@ -162,13 +162,17 @@ public class DeletedContent implements AutopsyVisitableItem {
DeletedContentNode(SleuthkitCase skCase, DeletedContent.DeletedContentFilter filter) {
super(Children.create(new DeletedContentChildren(filter, skCase), true), Lookups.singleton(filter.getDisplayName()));
super.setName(filter.getName());
super.setDisplayName(filter.getDisplayName());
this.skCase = skCase;
this.filter = filter;
String tooltip = filter.getDisplayName();
this.setShortDescription(tooltip);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-icon-deleted.png");
//get count of children without preloading all children nodes
final long count = new DeletedContentChildren(filter, skCase).calculateItems();
//final long count = getChildren().getNodesCount(true);
super.setDisplayName(filter.getDisplayName() + " (" + count + ")");
}
@Override
@ -225,30 +229,30 @@ public class DeletedContent implements AutopsyVisitableItem {
String query = "";
switch (filter) {
case FS_DELETED_FILTER:
query = "dir_flags = " + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue()
query = "dir_flags = " + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue()
+ " AND meta_flags != " + TskData.TSK_FS_META_FLAG_ENUM.ORPHAN.getValue()
+ " AND type = " + TskData.TSK_DB_FILES_TYPE_ENUM.FS.getFileType();
break;
case ALL_DELETED_FILTER:
query = " ( "
query = " ( "
+ "( "
+ "(dir_flags = " + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue()
+ " OR "
+ "meta_flags = " + TskData.TSK_FS_META_FLAG_ENUM.ORPHAN.getValue()
+ "meta_flags = " + TskData.TSK_FS_META_FLAG_ENUM.ORPHAN.getValue()
+ ")"
+ " AND type = " + TskData.TSK_DB_FILES_TYPE_ENUM.FS.getFileType()
+ " )"
+ " OR type = " + TskData.TSK_DB_FILES_TYPE_ENUM.CARVED.getFileType()
+ " )";
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS.getFileType()
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS.getFileType()
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS.getFileType()
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.DERIVED.getFileType()
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.LOCAL.getFileType()
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType();
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS.getFileType()
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS.getFileType()
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS.getFileType()
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.DERIVED.getFileType()
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.LOCAL.getFileType()
//+ " AND type != " + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType();
break;
default:
logger.log(Level.SEVERE, "Unsupported filter type to get deleted content: " + filter);
@ -271,6 +275,20 @@ public class DeletedContent implements AutopsyVisitableItem {
}
/**
* Get children count without actually loading all nodes
*
* @return
*/
long calculateItems() {
try {
return skCase.countFilesWhere(makeQuery());
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error getting deleted files search view count", ex);
return 0;
}
}
@Override
protected Node createNodeForKey(AbstractFile key) {
return key.accept(new ContentVisitor.Default<AbstractNode>() {

View File

@ -23,6 +23,8 @@ import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsNode;
import org.sleuthkit.autopsy.datamodel.EmailExtracted.EmailExtractedAccountNode;
import org.sleuthkit.autopsy.datamodel.EmailExtracted.EmailExtractedFolderNode;
import org.sleuthkit.autopsy.datamodel.EmailExtracted.EmailExtractedRootNode;
import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootChildren.FileSizeNode;
import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootNode;
import org.sleuthkit.autopsy.datamodel.HashsetHits.HashsetHitsRootNode;
import org.sleuthkit.autopsy.datamodel.HashsetHits.HashsetHitsSetNode;
import org.sleuthkit.autopsy.datamodel.KeywordHits.KeywordHitsKeywordNode;
@ -38,45 +40,80 @@ import org.sleuthkit.autopsy.datamodel.Tags.TagsRootNode;
public interface DisplayableItemNodeVisitor<T> {
T visit(DirectoryNode dn);
T visit(FileNode fn);
T visit(ImageNode in);
T visit(VolumeNode vn);
T visit(BlackboardArtifactNode ban);
T visit(ArtifactTypeNode atn);
T visit(ExtractedContentNode ecn);
T visit(FileSearchFilterNode fsfn);
T visit(DeletedContentNode dcn);
T visit(DeletedContentsNode dcn);
T visit(FileSizeRootNode fsrn);
T visit(FileSizeNode fsn);
T visit(SearchFiltersNode sfn);
T visit(RecentFilesNode rfn);
T visit(RecentFilesFilterNode rffn);
T visit(KeywordHitsRootNode khrn);
T visit(KeywordHitsListNode khsn);
T visit(KeywordHitsKeywordNode khmln);
T visit(HashsetHitsRootNode hhrn);
T visit(HashsetHitsSetNode hhsn);
T visit(EmailExtractedRootNode eern);
T visit(EmailExtractedAccountNode eean);
T visit(EmailExtractedFolderNode eefn);
T visit(TagsRootNode bksrn);
T visit(TagsNodeRoot bksrn);
T visit(TagNodeRoot tnr);
T visit(ViewsNode vn);
T visit(ResultsNode rn);
T visit(DataSourcesNode in);
T visit(LayoutFileNode lfn);
T visit(LocalFileNode dfn);
T visit(VirtualDirectoryNode ldn);
/**
* Visitor with an implementable default behavior for all types. Override
* specific visit types to not use the default behavior.
*
* @param <T>
*/
static abstract class Default<T> implements DisplayableItemNodeVisitor<T> {
/**
* Default visit for all types
*
* @param c
* @return
*/
@ -103,126 +140,135 @@ public interface DisplayableItemNodeVisitor<T> {
}
@Override
public T visit(BlackboardArtifactNode ban){
public T visit(BlackboardArtifactNode ban) {
return defaultVisit(ban);
}
@Override
public T visit(ArtifactTypeNode atn){
public T visit(ArtifactTypeNode atn) {
return defaultVisit(atn);
}
@Override
public T visit(ExtractedContentNode ecn){
public T visit(ExtractedContentNode ecn) {
return defaultVisit(ecn);
}
@Override
public T visit(FileSearchFilterNode fsfn){
public T visit(FileSearchFilterNode fsfn) {
return defaultVisit(fsfn);
}
@Override
public T visit(DeletedContentNode dcn){
return defaultVisit(dcn);
}
@Override
public T visit(DeletedContentsNode dcn){
public T visit(DeletedContentNode dcn) {
return defaultVisit(dcn);
}
@Override
public T visit(SearchFiltersNode sfn){
public T visit(DeletedContentsNode dcn) {
return defaultVisit(dcn);
}
@Override
public T visit(FileSizeRootNode fsrn) {
return defaultVisit(fsrn);
}
@Override
public T visit(FileSizeNode fsn) {
return defaultVisit(fsn);
}
@Override
public T visit(SearchFiltersNode sfn) {
return defaultVisit(sfn);
}
@Override
public T visit(RecentFilesNode rfn) {
return defaultVisit(rfn);
}
@Override
public T visit(RecentFilesFilterNode rffn) {
return defaultVisit(rffn);
}
@Override
public T visit(KeywordHitsRootNode khrn) {
return defaultVisit(khrn);
}
@Override
public T visit(KeywordHitsListNode khsn) {
return defaultVisit(khsn);
}
@Override
public T visit(KeywordHitsKeywordNode khmln) {
return defaultVisit(khmln);
}
@Override
public T visit(ViewsNode vn) {
return defaultVisit(vn);
}
@Override
public T visit(ResultsNode rn) {
return defaultVisit(rn);
}
@Override
public T visit(DataSourcesNode in) {
return defaultVisit(in);
}
@Override
public T visit(HashsetHitsRootNode hhrn) {
return defaultVisit(hhrn);
}
@Override
public T visit(HashsetHitsSetNode hhsn) {
return defaultVisit(hhsn);
}
@Override
public T visit(EmailExtractedRootNode eern) {
return defaultVisit(eern);
}
@Override
public T visit(EmailExtractedAccountNode eean) {
return defaultVisit(eean);
}
@Override
public T visit(EmailExtractedFolderNode eefn) {
return defaultVisit(eefn);
}
@Override
public T visit(LayoutFileNode lfn) {
return defaultVisit(lfn);
}
@Override
public T visit(LocalFileNode dfn) {
return defaultVisit(dfn);
}
@Override
public T visit(VirtualDirectoryNode ldn) {
return defaultVisit(ldn);
}
@Override
public T visit(TagsRootNode bksrn) {
return defaultVisit(bksrn);
}
@Override
public T visit(TagsNodeRoot bksnr) {
return defaultVisit(bksnr);
@ -232,7 +278,5 @@ public interface DisplayableItemNodeVisitor<T> {
public T visit(TagNodeRoot tnr) {
return defaultVisit(tnr);
}
}
}

View File

@ -29,12 +29,13 @@ import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.DerivedFile;
import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.FsContent;
import org.sleuthkit.datamodel.LocalFile;
import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
/**
* Children factory for the file by type view in dir tree
@ -59,7 +60,8 @@ class FileSearchFilterChildren extends ChildFactory<Content> {
private String createQuery(){
String query = "(known IS NULL OR known != 1) AND (0";
String query = "(dir_type = " + TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue() + ")"
+ " AND (known IS NULL OR known != 1) AND (0";
for(String s : filter.getFilter()){
query += " OR name LIKE '%" + s + "'";
}
@ -74,17 +76,28 @@ class FileSearchFilterChildren extends ChildFactory<Content> {
try {
List<AbstractFile> res = skCase.findAllFilesWhere(createQuery());
for(AbstractFile c : res){
if(c.isFile()){
list.add(c);
}
}
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Couldn't get search results", ex);
logger.log(Level.SEVERE, "Couldn't get search results", ex);
}
return list;
}
/**
* Get children count without actually loading all nodes
* @return
*/
long calculateItems() {
try {
return skCase.countFilesWhere(createQuery());
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error getting file search view count", ex);
return 0;
}
}
@Override
protected Node createNodeForKey(Content key) {
@ -94,6 +107,11 @@ class FileSearchFilterChildren extends ChildFactory<Content> {
return new FileNode(f, false);
}
@Override
public DirectoryNode visit(Directory d) {
return new DirectoryNode(d);
}
@Override
public LayoutFileNode visit(LayoutFile lf) {
return new LayoutFileNode(lf);

View File

@ -18,11 +18,9 @@
*/
package org.sleuthkit.autopsy.datamodel;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Sheet;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.datamodel.SearchFilters.FileSearchFilter;
import org.sleuthkit.datamodel.SleuthkitCase;
/**
@ -35,10 +33,17 @@ public class FileSearchFilterNode extends DisplayableItemNode {
FileSearchFilterNode(SearchFilters.SearchFilterInterface filter, SleuthkitCase skCase) {
super(Children.create(new FileSearchFilterChildren(filter, skCase), true), Lookups.singleton(filter.getDisplayName()));
super.setName(filter.getName());
super.setDisplayName(filter.getDisplayName());
this.filter = filter;
this.skCase = skCase;
super.setName(filter.getName());
//get count of children without preloading all children nodes
final long count = new FileSearchFilterChildren(filter, skCase).calculateItems();
//final long count = getChildren().getNodesCount(true);
super.setDisplayName(filter.getDisplayName() + " (" + count + ")");
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-filter-icon.png");
}

View File

@ -0,0 +1,314 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.datamodel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.nodes.Sheet;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.FsContent;
import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Files by Size View node and related child nodes
*/
public class FileSize implements AutopsyVisitableItem {
private SleuthkitCase skCase;
public enum FileSizeFilter implements AutopsyVisitableItem {
SIZE_50_200(0, "SIZE_50_200", "50 - 200MB"),
SIZE_200_1000(1, "SIZE_200_1GB", "200MB - 1GB"),
SIZE_1000_(2, "SIZE_1000+", "1GB+");
private int id;
private String name;
private String displayName;
private FileSizeFilter(int id, String name, String displayName) {
this.id = id;
this.name = name;
this.displayName = displayName;
}
public String getName() {
return this.name;
}
public int getId() {
return this.id;
}
public String getDisplayName() {
return this.displayName;
}
@Override
public <T> T accept(AutopsyItemVisitor<T> v) {
return v.visit(this);
}
}
public FileSize(SleuthkitCase skCase) {
this.skCase = skCase;
}
@Override
public <T> T accept(AutopsyItemVisitor<T> v) {
return v.visit(this);
}
public SleuthkitCase getSleuthkitCase() {
return this.skCase;
}
public static class FileSizeRootNode extends DisplayableItemNode {
private static final String NAME = "File Size";
private SleuthkitCase skCase;
FileSizeRootNode(SleuthkitCase skCase) {
super(Children.create(new FileSizeRootChildren(skCase), true), Lookups.singleton(NAME));
super.setName(NAME);
super.setDisplayName(NAME);
this.skCase = skCase;
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-size-16.png");
}
@Override
public DisplayableItemNode.TYPE getDisplayableItemNodeType() {
return DisplayableItemNode.TYPE.META;
}
@Override
public <T> T accept(DisplayableItemNodeVisitor<T> v) {
return v.visit(this);
}
@Override
protected Sheet createSheet() {
Sheet s = super.createSheet();
Sheet.Set ss = s.get(Sheet.PROPERTIES);
if (ss == null) {
ss = Sheet.createPropertiesSet();
s.put(ss);
}
ss.put(new NodeProperty("Name",
"Name",
"no description",
NAME));
return s;
}
}
public static class FileSizeRootChildren extends ChildFactory<org.sleuthkit.autopsy.datamodel.FileSize.FileSizeFilter> {
private SleuthkitCase skCase;
public FileSizeRootChildren(SleuthkitCase skCase) {
this.skCase = skCase;
}
@Override
protected boolean createKeys(List<FileSizeFilter> list) {
list.addAll(Arrays.asList(FileSizeFilter.values()));
return true;
}
@Override
protected Node createNodeForKey(FileSizeFilter key) {
return new FileSizeNode(skCase, key);
}
public class FileSizeNode extends DisplayableItemNode {
private SleuthkitCase skCase;
private FileSizeFilter filter;
private final Logger logger = Logger.getLogger(FileSizeNode.class.getName());
FileSizeNode(SleuthkitCase skCase, FileSizeFilter filter) {
super(Children.create(new FileSizeChildren(filter, skCase), true), Lookups.singleton(filter.getDisplayName()));
super.setName(filter.getName());
this.skCase = skCase;
this.filter = filter;
String tooltip = filter.getDisplayName();
this.setShortDescription(tooltip);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-size-16.png");
//get count of children without preloading all children nodes
final long count = new FileSizeChildren(filter, skCase).calculateItems();
//final long count = getChildren().getNodesCount(true);
super.setDisplayName(filter.getDisplayName() + " (" + count + ")");
}
@Override
public <T> T accept(DisplayableItemNodeVisitor<T> v) {
return v.visit(this);
}
@Override
protected Sheet createSheet() {
Sheet s = super.createSheet();
Sheet.Set ss = s.get(Sheet.PROPERTIES);
if (ss == null) {
ss = Sheet.createPropertiesSet();
s.put(ss);
}
ss.put(new NodeProperty("Filter Type",
"Filter Type",
"no description",
filter.getDisplayName()));
return s;
}
@Override
public DisplayableItemNode.TYPE getDisplayableItemNodeType() {
return DisplayableItemNode.TYPE.META;
}
@Override
public boolean isLeafTypeNode() {
return true;
}
}
class FileSizeChildren extends ChildFactory<AbstractFile> {
private SleuthkitCase skCase;
private FileSizeFilter filter;
private final Logger logger = Logger.getLogger(FileSizeChildren.class.getName());
FileSizeChildren(FileSizeFilter filter, SleuthkitCase skCase) {
this.skCase = skCase;
this.filter = filter;
}
@Override
protected boolean createKeys(List<AbstractFile> list) {
list.addAll(runFsQuery());
return true;
}
private String makeQuery() {
String query = "";
switch (filter) {
case SIZE_50_200:
query = "size >= 50000000 AND size < 200000000";
break;
case SIZE_200_1000:
query = "size >= 200000000 AND size < 1000000000";
break;
case SIZE_1000_:
query = "size >= 1000000000";
break;
default:
logger.log(Level.SEVERE, "Unsupported filter type to get files by size: " + filter);
}
return query;
}
private List<AbstractFile> runFsQuery() {
List<AbstractFile> ret = new ArrayList<AbstractFile>();
String query = makeQuery();
try {
ret = skCase.findAllFilesWhere(query);
} catch (TskCoreException e) {
logger.log(Level.SEVERE, "Error getting files for the file size view using: " + query, e);
}
return ret;
}
/**
* Get children count without actually loading all nodes
*
* @return
*/
long calculateItems() {
try {
return skCase.countFilesWhere(makeQuery());
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error getting files by size search view count", ex);
return 0;
}
}
@Override
protected Node createNodeForKey(AbstractFile key) {
return key.accept(new ContentVisitor.Default<AbstractNode>() {
public FileNode visit(AbstractFile f) {
return new FileNode(f, false);
}
public FileNode visit(FsContent f) {
return new FileNode(f, false);
}
@Override
public FileNode visit(LayoutFile f) {
return new FileNode(f, false);
}
@Override
public FileNode visit(File f) {
return new FileNode(f, false);
}
@Override
public FileNode visit(Directory f) {
return new FileNode(f, false);
}
@Override
protected AbstractNode defaultVisit(Content di) {
throw new UnsupportedOperationException("Not supported for this type of Displayable Item: " + di.toString());
}
});
}
}
}
}

View File

@ -36,8 +36,8 @@ import org.sleuthkit.datamodel.SleuthkitCase;
*/
public class RecentFilesChildren extends ChildFactory<RecentFiles.RecentFilesFilter> {
SleuthkitCase skCase;
Calendar lastDay;
private SleuthkitCase skCase;
private Calendar lastDay;
private final static Logger logger = Logger.getLogger(RecentFilesChildren.class.getName());
public RecentFilesChildren(SleuthkitCase skCase) {
@ -74,8 +74,9 @@ public class RecentFilesChildren extends ChildFactory<RecentFiles.RecentFilesFil
return Math.max(maxcr, Math.max(maxc, maxm));
}
//TODO add a generic query to SleuthkitCase
private String createMaxQuery(String attr) {
return "select max(" + attr + ") from tsk_files where " + attr + " < " + System.currentTimeMillis() / 1000;
return "SELECT MAX(" + attr + ") from tsk_files WHERE " + attr + " < " + System.currentTimeMillis() / 1000;
}
@SuppressWarnings("deprecation")

View File

@ -27,12 +27,16 @@ import org.openide.nodes.AbstractNode;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Node;
import org.sleuthkit.autopsy.datamodel.RecentFiles.RecentFilesFilter;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.DerivedFile;
import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.FsContent;
import org.sleuthkit.datamodel.LocalFile;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
/**
*
@ -40,9 +44,9 @@ import org.sleuthkit.datamodel.TskCoreException;
*/
public class RecentFilesFilterChildren extends ChildFactory<Content> {
SleuthkitCase skCase;
RecentFilesFilter filter;
Calendar prevDay;
private SleuthkitCase skCase;
private RecentFilesFilter filter;
private Calendar prevDay;
private final static Logger logger = Logger.getLogger(RecentFilesFilterChildren.class.getName());
//private final static int MAX_OBJECTS = 1000000;
@ -55,16 +59,18 @@ public class RecentFilesFilterChildren extends ChildFactory<Content> {
@Override
protected boolean createKeys(List<Content> list) {
list.addAll(runFsQuery());
list.addAll(runQuery());
return true;
}
private String createQuery() {
String query = "(known IS NULL OR known != 1) AND (";
long lowerLimit = prevDay.getTimeInMillis() / 1000;
prevDay.add(Calendar.DATE, 1);
prevDay.add(Calendar.MILLISECOND, -1);
long upperLimit = prevDay.getTimeInMillis() / 1000;
Calendar prevDayQuery = (Calendar) prevDay.clone();
String query = "(dir_type = " + TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue() + ")"
+ " AND (known IS NULL OR known != 1) AND (";
long lowerLimit = prevDayQuery.getTimeInMillis() / 1000;
prevDayQuery.add(Calendar.DATE, 1);
prevDayQuery.add(Calendar.MILLISECOND, -1);
long upperLimit = prevDayQuery.getTimeInMillis() / 1000;
query += "(crtime BETWEEN " + lowerLimit + " AND " + upperLimit + ") OR ";
query += "(ctime BETWEEN " + lowerLimit + " AND " + upperLimit + ") OR ";
//query += "(atime BETWEEN " + lowerLimit + " AND " + upperLimit + ") OR ";
@ -73,14 +79,12 @@ public class RecentFilesFilterChildren extends ChildFactory<Content> {
return query;
}
private List<FsContent> runFsQuery() {
List<FsContent> ret = new ArrayList<FsContent>();
private List<AbstractFile> runQuery() {
List<AbstractFile> ret = new ArrayList<AbstractFile>();
try {
List<FsContent> found = skCase.findFilesWhere(createQuery());
for (FsContent c : found) {
if (c.isFile()) {
List<AbstractFile> found = skCase.findAllFilesWhere(createQuery());
for (AbstractFile c : found) {
ret.add(c);
}
}
} catch (TskCoreException ex) {
@ -89,6 +93,21 @@ public class RecentFilesFilterChildren extends ChildFactory<Content> {
return ret;
}
/**
* Get children count without actually loading all nodes
* @return
*/
long calculateItems() {
try {
return skCase.countFilesWhere(createQuery());
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error getting recent files search view count", ex);
return 0;
}
}
@Override
protected Node createNodeForKey(Content key) {
@ -97,7 +116,23 @@ public class RecentFilesFilterChildren extends ChildFactory<Content> {
public FileNode visit(File f) {
return new FileNode(f, false);
}
@Override
public DirectoryNode visit(Directory d) {
return new DirectoryNode(d);
}
@Override
public LocalFileNode visit(DerivedFile f) {
return new LocalFileNode(f);
}
@Override
public LocalFileNode visit(LocalFile f) {
return new LocalFileNode(f);
}
@Override
protected AbstractNode defaultVisit(Content di) {

View File

@ -40,7 +40,7 @@ public class RecentFilesFilterNode extends DisplayableItemNode {
RecentFilesFilterNode(SleuthkitCase skCase, RecentFilesFilter filter, Calendar lastDay) {
super(Children.create(new RecentFilesFilterChildren(filter, skCase, lastDay), true), Lookups.singleton(filter.getDisplayName()));
super.setName(filter.getName());
super.setDisplayName(filter.getDisplayName());
//super.setDisplayName(filter.getDisplayName());
this.skCase = skCase;
this.filter = filter;
Calendar prevDay = (Calendar) lastDay.clone();
@ -50,6 +50,11 @@ public class RecentFilesFilterNode extends DisplayableItemNode {
+ prevDay.get(Calendar.YEAR);
this.setShortDescription(tooltip);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/recent_files.png");
//get count of children without preloading all children nodes
final long count = new RecentFilesFilterChildren(filter, skCase, lastDay).calculateItems();
//final long count = getChildren().getNodesCount(true);
super.setDisplayName(filter.getDisplayName() + " (" + count + ")");
}
@Override

View File

@ -30,7 +30,7 @@ import org.sleuthkit.datamodel.SleuthkitCase;
public class RecentFilesNode extends DisplayableItemNode {
private static final String NAME = "Recent Files";
SleuthkitCase skCase;
private SleuthkitCase skCase;
RecentFilesNode(SleuthkitCase skCase) {
super(Children.create(new RecentFilesChildren(skCase), true), Lookups.singleton(NAME));
@ -38,6 +38,7 @@ public class RecentFilesNode extends DisplayableItemNode {
super.setDisplayName(NAME);
this.skCase = skCase;
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/recent_files.png");
}
@Override

View File

@ -33,7 +33,9 @@ public class SearchFilters implements AutopsyVisitableItem {
TSK_IMAGE_FILTER(0, "TSK_IMAGE_FILTER", "Images", FileTypeExtensions.getImageExtensions()),
TSK_VIDEO_FILTER(1, "TSK_VIDEO_FILTER", "Videos", FileTypeExtensions.getVideoExtensions()),
TSK_AUDIO_FILTER(2, "TSK_AUDIO_FILTER", "Audio", FileTypeExtensions.getAudioExtensions()),
TSK_DOCUMENT_FILTER(3, "TSK_DOCUMENT_FILTER", "Documents", Arrays.asList(".doc", ".docx", ".pdf", ".xls", ".rtf", ".txt"));
TSK_ARCHIVE_FILTER(3, "TSK_ARCHIVE_FILTER", "Archives", FileTypeExtensions.getArchiveExtensions()),
TSK_DOCUMENT_FILTER(3, "TSK_DOCUMENT_FILTER", "Documents", Arrays.asList(".doc", ".docx", ".pdf", ".xls", ".rtf", ".txt")),
TSK_EXECUTABLE_FILTER(3, "TSK_EXECUTABLE_FILTER", "Executable", Arrays.asList(".exe", ".dll", ".bat", ".cmd", ".com"));
private int id;
private String name;
@ -81,10 +83,10 @@ public class SearchFilters implements AutopsyVisitableItem {
AUT_DOC_TXT(3, "AUT_DOC_TXT", "Plain Text", Arrays.asList(".txt")),
AUT_DOC_RTF(4, "AUT_DOC_RTF", "Rich Text", Arrays.asList(".rtf"));
int id;
String name;
String displayName;
List<String> filter;
private int id;
private String name;
private String displayName;
private List<String> filter;
private DocumentFilter(int id, String name, String displayName, List<String> filter){
this.id = id;
@ -118,6 +120,52 @@ public class SearchFilters implements AutopsyVisitableItem {
return this.filter;
}
}
public enum ExecutableFilter implements AutopsyVisitableItem,SearchFilterInterface {
ExecutableFilter_EXE(0, "ExecutableFilter_EXE", ".exe", Arrays.asList(".exe")),
ExecutableFilter_DLL(1, "ExecutableFilter_DLL", ".dll", Arrays.asList(".dll")),
ExecutableFilter_BAT(2, "ExecutableFilter_BAT", ".bat", Arrays.asList(".bat")),
ExecutableFilter_CMD(3, "ExecutableFilter_CMD", ".cmd", Arrays.asList(".cmd")),
ExecutableFilter_COM(4, "ExecutableFilter_COM", ".com", Arrays.asList(".com"));
private int id;
private String name;
private String displayName;
private List<String> filter;
private ExecutableFilter(int id, String name, String displayName, List<String> filter){
this.id = id;
this.name = name;
this.displayName = displayName;
this.filter = filter;
}
@Override
public <T> T accept(AutopsyItemVisitor<T> v) {
return v.visit(this);
}
@Override
public String getName(){
return this.name;
}
@Override
public int getId(){
return this.id;
}
@Override
public String getDisplayName(){
return this.displayName;
}
@Override
public List<String> getFilter(){
return this.filter;
}
}
public SearchFilters(SleuthkitCase skCase){
this.skCase = skCase;

View File

@ -31,28 +31,38 @@ import org.sleuthkit.datamodel.SleuthkitCase;
class SearchFiltersChildren extends ChildFactory<SearchFilters.SearchFilterInterface> {
private SleuthkitCase skCase;
private boolean root;
private SearchFilters.FileSearchFilter filter;
public SearchFiltersChildren(SleuthkitCase skCase, boolean root) {
public SearchFiltersChildren(SleuthkitCase skCase, SearchFilters.FileSearchFilter filter) {
this.skCase = skCase;
this.root = root;
this.filter = filter;
}
@Override
protected boolean createKeys(List<SearchFilters.SearchFilterInterface> list) {
if(root)
if (filter == null) {
list.addAll(Arrays.asList(FileSearchFilter.values()));
else
}
else if (filter.equals(FileSearchFilter.TSK_DOCUMENT_FILTER) ){
list.addAll(Arrays.asList(SearchFilters.DocumentFilter.values()));
}
else if (filter.equals(FileSearchFilter.TSK_EXECUTABLE_FILTER) ){
list.addAll(Arrays.asList(SearchFilters.ExecutableFilter.values()));
}
return true;
}
@Override
protected Node createNodeForKey(SearchFilters.SearchFilterInterface key){
if(key.getName().equals(SearchFilters.FileSearchFilter.TSK_DOCUMENT_FILTER.getName())){
return new SearchFiltersNode(skCase, false);
return new SearchFiltersNode(skCase, SearchFilters.FileSearchFilter.TSK_DOCUMENT_FILTER);
}
else if(key.getName().equals(SearchFilters.FileSearchFilter.TSK_EXECUTABLE_FILTER.getName())){
return new SearchFiltersNode(skCase, SearchFilters.FileSearchFilter.TSK_EXECUTABLE_FILTER);
}
else {
return new FileSearchFilterNode(key, skCase);
}
return new FileSearchFilterNode(key, skCase);
}
}

View File

@ -18,7 +18,6 @@
*/
package org.sleuthkit.autopsy.datamodel;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Sheet;
import org.openide.util.lookup.Lookups;
@ -30,17 +29,16 @@ import org.sleuthkit.datamodel.SleuthkitCase;
public class SearchFiltersNode extends DisplayableItemNode {
private static final String FNAME = "File Types";
private static final String DNAME = "Documents";
SleuthkitCase skCase;
private SleuthkitCase skCase;
SearchFiltersNode(SleuthkitCase skCase, boolean root) {
super(Children.create(new SearchFiltersChildren(skCase, root), true), Lookups.singleton(root ? FNAME : DNAME));
if (root) {
SearchFiltersNode(SleuthkitCase skCase, SearchFilters.FileSearchFilter filter) {
super(Children.create(new SearchFiltersChildren(skCase, filter), true), Lookups.singleton(filter == null ? FNAME : filter.getName()));
if (filter == null) {
super.setName(FNAME);
super.setDisplayName(FNAME);
} else {
super.setName(DNAME);
super.setDisplayName(DNAME);
super.setName(filter.getName());
super.setDisplayName(filter.getDisplayName());
}
this.skCase = skCase;
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file_types.png");

View File

@ -19,7 +19,6 @@
package org.sleuthkit.autopsy.datamodel;
import java.util.Arrays;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Sheet;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.datamodel.SleuthkitCase;
@ -34,7 +33,13 @@ public class ViewsNode extends DisplayableItemNode {
public static final String NAME = "Views";
public ViewsNode(SleuthkitCase sleuthkitCase) {
super(new RootContentChildren(Arrays.asList(new SearchFilters(sleuthkitCase), new RecentFiles(sleuthkitCase), new DeletedContent(sleuthkitCase))), Lookups.singleton(NAME));
super(new RootContentChildren(Arrays.asList(
new SearchFilters(sleuthkitCase),
new RecentFiles(sleuthkitCase),
new DeletedContent(sleuthkitCase),
new FileSize(sleuthkitCase)
)),
Lookups.singleton(NAME));
setName(NAME);
setDisplayName(NAME);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/views.png");

View File

@ -48,6 +48,8 @@ import org.sleuthkit.autopsy.datamodel.EmailExtracted.EmailExtractedRootNode;
import org.sleuthkit.autopsy.datamodel.ExtractedContentNode;
import org.sleuthkit.autopsy.datamodel.FileNode;
import org.sleuthkit.autopsy.datamodel.FileSearchFilterNode;
import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootChildren.FileSizeNode;
import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootNode;
import org.sleuthkit.autopsy.datamodel.HashsetHits.HashsetHitsRootNode;
import org.sleuthkit.autopsy.datamodel.HashsetHits.HashsetHitsSetNode;
import org.sleuthkit.autopsy.datamodel.ImageNode;
@ -365,17 +367,27 @@ public class DataResultFilterNode extends FilterNode {
public AbstractAction visit(RecentFilesNode rfn) {
return openChild(rfn);
}
@Override
public AbstractAction visit(DeletedContentsNode dcn) {
return openChild(dcn);
}
@Override
public AbstractAction visit(DeletedContentNode dcn) {
return openChild(dcn);
}
@Override
public AbstractAction visit(FileSizeRootNode fsrn) {
return openChild(fsrn);
}
@Override
public AbstractAction visit(FileSizeNode fsn) {
return openChild(fsn);
}
@Override
public AbstractAction visit(BlackboardArtifactNode ban) {
return new ViewContextAction("View in Directory", ban);

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 B

View File

@ -325,7 +325,7 @@ public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfi
}
});
save(); // save the simple panel
dialog.display(currentModule.getAdvancedConfiguration());
dialog.display(currentModule.getAdvancedConfiguration(null));
}//GEN-LAST:event_advancedButtonActionPerformed
private void processUnallocCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_processUnallocCheckboxActionPerformed
@ -452,7 +452,7 @@ public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfi
if(this.modulesTable.getSelectedRow() != -1) {
simplePanel.removeAll();
if (currentModule.hasSimpleConfiguration()) {
simplePanel.add(currentModule.getSimpleConfiguration());
simplePanel.add(currentModule.getSimpleConfiguration(null));
}
simplePanel.revalidate();
simplePanel.repaint();

View File

@ -101,7 +101,7 @@ public abstract class IngestModuleAbstract {
/**
* Gets the arguments as set in XML
* Gets the module arguments as set in pipeline/module configuration
* @return arguments string
*/
public String getArguments() {
@ -109,11 +109,11 @@ public abstract class IngestModuleAbstract {
}
/**
* Sets the arguments from XML
* @param args arguments string in XML
* Sets the module arguments (e.g. from pipeline/module configuration)
* @param moduleArgs arguments string
*/
public void setArguments(String a_args) {
args = a_args;
public void setArguments(String moduleArgs) {
args = moduleArgs;
}
/**
@ -162,27 +162,34 @@ public abstract class IngestModuleAbstract {
public void saveAdvancedConfiguration() {}
/**
* Returns a panel that displays the simple (run-time) configuration.
* Returns a panel that displays the simple (run-time) configuration
* for the given configuration context (such as pipeline instance).
* This is presented to the user before ingest starts and only basic
* settings should be given here. use the advanced (general) configuration
* settings should be given here. Use the advanced (general) configuration
* panel for more in-depth interfaces.
* The module is responsible for preserving / saving its configuration state
* In addition, saveSimpleConfiguration() can be used
* The module (or its configuration controller object) is responsible for preserving / saving its configuration state
* In addition, saveSimpleConfiguration() can be used as the trigger.
*
* @param context the configuration context to use in the panel
* @return JPanel containing basic configuration widgets or null if simple configuration is not available
*/
public javax.swing.JPanel getSimpleConfiguration() {
public javax.swing.JPanel getSimpleConfiguration(String context) {
return null;
}
/**
* Implements advanced module conf iguration exposed to the user before ingest starts
* The module is responsible for preserving / saving its configuration state
* In addition, saveAdvancedConfiguration() can be used
* Returns a panel that displays the advanced (run-time) configuration
* for the given configuration context (such as pipeline instance).
* Implements advanced module configuration exposed to the user before ingest starts.
*
* The module (or its configuration controller object)
* is responsible for preserving / saving its configuration state
* In addition, saveAdvancedConfiguration() can be used as the trigger.
*
* @param context the configuration context to use in the panel
* @return JPanel containing advanced configuration widgets or null if advanced configuration is not available
*/
public javax.swing.JPanel getAdvancedConfiguration() {
public javax.swing.JPanel getAdvancedConfiguration(String context) {
return null;
};
}

View File

@ -25,7 +25,7 @@
and even for very large images to be processed there can be initial results available minutes, sometimes seconds after the analysis has started.
</p>
<p>
You can start image ingest in two ways. When you add an image with the <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/addImage.html">Add Image wizard</a>,
You can start image ingest in two ways. When you add an image with the <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/addImage.html">Add Data Source wizard</a>,
you will be shown the list of ingest modules and you can choose which you want to run.
You can also launch the Ingest Manager run ingest by right clicking on an image in the explorer tree and choosing "Restart Image Ingest".
</p>

View File

@ -222,13 +222,13 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
}
@Override
public javax.swing.JPanel getSimpleConfiguration() {
public javax.swing.JPanel getSimpleConfiguration(String context) {
HashDbXML.getCurrent().reload();
return new HashDbSimplePanel();
}
@Override
public javax.swing.JPanel getAdvancedConfiguration() {
public javax.swing.JPanel getAdvancedConfiguration(String context) {
//return HashDbManagementPanel.getDefault();
getPanel().load();
return getPanel();

View File

@ -427,13 +427,13 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
}
@Override
public javax.swing.JPanel getSimpleConfiguration() {
public javax.swing.JPanel getSimpleConfiguration(String context) {
KeywordSearchListsXML.getCurrent().reload();
return new KeywordSearchIngestSimplePanel();
}
@Override
public javax.swing.JPanel getAdvancedConfiguration() {
public javax.swing.JPanel getAdvancedConfiguration(String context) {
//return KeywordSearchConfigurationPanel.getDefault();
getPanel().load();
return getPanel();

View File

@ -359,7 +359,7 @@ public class Server {
} else {
loggingPropertiesFilePath += "logging-release.properties";
}
//loggingPropertiesFilePath = PlatformUtil.getOSFilePath(loggingPropertiesFilePath);
final String loggingProperties = loggingPropertiesOpt + loggingPropertiesFilePath;
final String [] SOLR_START_CMD = {
@ -371,7 +371,13 @@ public class Server {
loggingProperties,
"-jar",
"start.jar"};
logger.log(Level.INFO, "Starting Solr using: " + SOLR_START_CMD);
StringBuilder cmdSb = new StringBuilder();
for (int i = 0; i<SOLR_START_CMD.length; ++i ) {
cmdSb.append(SOLR_START_CMD[i]).append(" ");
}
logger.log(Level.INFO, "Starting Solr using: " + cmdSb.toString());
curSolrProcess = Runtime.getRuntime().exec(SOLR_START_CMD, null, solrFolder);
logger.log(Level.INFO, "Finished starting Solr");

View File

@ -1,8 +1,8 @@
---------------- VERSION Current (development) --------------
New features:
- Local files and folders support
- Deleted files view in directory tree
- Logical files and folders support
- New file views in directory tree to view: deleted, executable, archive files and files by size
Improvements:
- Improvements to tagging of files and keyword search results
@ -13,6 +13,7 @@ Bugfixes:
- fix for "Process Unallocated Space" option doesn't do anything
- fixed result viewer for "File Search by MD5 Hash"
- fix Solr, Timeline and RecentActivity issues with java 7.0.21
- Views->Recent Files showing inconsistent results when clicked many times
---------------- VERSION 3.0.5 --------------

View File

@ -311,12 +311,12 @@ public class ScalpelCarverIngestModule { // disable autodiscovery for now // imp
public void saveAdvancedConfiguration() { }
// @Override
public JPanel getSimpleConfiguration() {
public JPanel getSimpleConfiguration(String context) {
throw new UnsupportedOperationException("Not supported yet.");
}
// @Override
public JPanel getAdvancedConfiguration() {
public JPanel getAdvancedConfiguration(String context) {
throw new UnsupportedOperationException("Not supported yet.");
}

View File

@ -156,7 +156,7 @@ public class ScalpelCarver {
File outputFile = new File(outputFolderPath, SCALPEL_OUTPUT_FILE_NAME);
// parse the output
List<CarvedFileMeta> output = Collections.EMPTY_LIST;
List<CarvedFileMeta> output = Collections.<CarvedFileMeta>emptyList();
try {
output = ScalpelOutputParser.parse(outputFile);
} catch (FileNotFoundException ex) {

View File

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

View File

@ -4,3 +4,5 @@ license.file=../LICENSE-2.0.txt
nbm.homepage=http://www.sleuthkit.org/autopsy/
nbm.module.author=Brian Carrier
nbm.needs.restart=true
spec.version.base=1.0.0

View File

@ -1,8 +1,7 @@
Manifest-Version: 1.0
OpenIDE-Module: org.sleuthkit.autopsy.timeline
OpenIDE-Module: org.sleuthkit.autopsy.timeline/1
OpenIDE-Module-Layer: org/sleuthkit/autopsy/timeline/layer.xml
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/timeline/Bundle.properties
OpenIDE-Module-Requires: org.openide.windows.WindowManager
OpenIDE-Module-Specification-Version: 1.0
OpenIDE-Module-Implementation-Version: 1

View File

@ -1,2 +1,6 @@
javac.source=1.7
javac.compilerargs=-Xlint -Xlint:-serial
license.file=../LICENSE-2.0.txt
nbm.homepage=http://www.sleuthkit.org/autopsy/
nbm.needs.restart=true
spec.version.base=1.0.0

View File

@ -80,7 +80,6 @@ import org.openide.modules.ModuleInstall;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.util.Exceptions;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
@ -99,15 +98,11 @@ import org.sleuthkit.autopsy.datamodel.FileNode;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.coreutils.ExecUtil;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.FsContent;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.timeline.Timeline")
@ActionRegistration(displayName = "#CTL_MakeTimeline")
@ActionRegistration(displayName = "#CTL_MakeTimeline", lazy=false)
@ActionReferences(value = {
@ActionReference(path = "Menu/Tools", position = 100)})
@NbBundle.Messages(value = "CTL_TimelineView=Generate Timeline")
@ -121,14 +116,14 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
private HBox fxHBoxCharts; //Holds the navigation buttons in horiztonal fashion.
private VBox fxVBox; //Holds the JavaFX Elements in vertical fashion.
private JFXPanel fxPanelCharts; //FX panel to hold the group
private BarChart fxChartEvents; //Yearly/Monthly events - Bar chart
private BarChart<String,Number> fxChartEvents; //Yearly/Monthly events - Bar chart
private ScrollPane fxScrollEvents; //Scroll Panes for dealing with oversized an oversized chart
private static final int FRAME_HEIGHT = 700; //Sizing constants
private static final int FRAME_WIDTH = 1200;
private Button fxZoomOutButton; //Navigation buttons
private ComboBox<String> fxDropdownSelectYears; //Dropdown box for selecting years. Useful when the charts' scale means some years are unclickable, despite having events.
private final Stack<BarChart> fxStackPrevCharts = new Stack<BarChart>(); //Stack for storing drill-up information.
private BarChart fxChartTopLevel; //the topmost chart, used for resetting to default view.
private final Stack<BarChart<String,Number>> fxStackPrevCharts = new Stack<BarChart<String,Number>>(); //Stack for storing drill-up information.
private BarChart<String,Number> fxChartTopLevel; //the topmost chart, used for resetting to default view.
private DataResultPanel dataResultPanel;
private DataContentPanel dataContentPanel;
private ProgressHandle progress;
@ -138,8 +133,8 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
private boolean listeningToAddImage = false;
private long lastObjectId = -1;
private TimelineProgressDialog progressDialog;
private EventHandler fxMouseEnteredListener;
private EventHandler fxMouseExitedListener;
private EventHandler<MouseEvent> fxMouseEnteredListener;
private EventHandler<MouseEvent> fxMouseExitedListener;
private SleuthkitCase skCase;
private boolean fxInited = false;
@ -270,14 +265,14 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
lsi.add(ye.year + " : " + ye.getNumFiles());
}
ObservableList<String> listSelect = FXCollections.observableArrayList(lsi);
fxDropdownSelectYears = new ComboBox(listSelect);
fxDropdownSelectYears = new ComboBox<String>(listSelect);
//Buttons for navigating up and down the timeline
fxZoomOutButton = new Button("Zoom Out");
fxZoomOutButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
BarChart bc;
BarChart<String,Number> bc;
if (fxStackPrevCharts.size() == 0) {
bc = fxChartTopLevel;
} else {
@ -344,7 +339,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
* @param allYears The list of years that have barData from the mactime file
* @return BarChart scaled to the year level
*/
private BarChart createYearChartWithDrill(final List<YearEpoch> allYears) {
private BarChart<String,Number> createYearChartWithDrill(final List<YearEpoch> allYears) {
final CategoryAxis xAxis = new CategoryAxis(); //Axes are very specific types. Categorys are strings.
final NumberAxis yAxis = new NumberAxis();
final Label l = new Label("");
@ -372,7 +367,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
// But it is for this reason that the chart generating functions have two forloops. I do not believe they can be condensed into a single loop due to the nodes being null until
// an undetermined point in time.
BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, bcData);
for (final BarChart.Data barData : bc.getData().get(0).getData()) { //.get(0) refers to the BarChart.Series class to work on. There is only one series in this graph, so get(0) is safe.
for (final BarChart.Data<String,Number> barData : bc.getData().get(0).getData()) { //.get(0) refers to the BarChart.Series class to work on. There is only one series in this graph, so get(0) is safe.
barData.getNode().setScaleX(.5);
final javafx.scene.Node barNode = barData.getNode();
@ -390,7 +385,8 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
Platform.runLater(new Runnable() {
@Override
public void run() {
BarChart b = createMonthsWithDrill((YearEpoch) findYear(allYears, Integer.valueOf((String) barData.getXValue())));
BarChart<String,Number> b =
createMonthsWithDrill(findYear(allYears, Integer.valueOf(barData.getXValue())));
fxChartEvents = b;
fxScrollEvents.setContent(fxChartEvents);
}
@ -412,7 +408,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
* Displays a chart with events from one year only, separated into 1-month chunks.
* Always 12 per year, empty months are represented by no bar.
*/
private BarChart createMonthsWithDrill(final YearEpoch ye) {
private BarChart<String,Number> createMonthsWithDrill(final YearEpoch ye) {
final CategoryAxis xAxis = new CategoryAxis();
final NumberAxis yAxis = new NumberAxis();
@ -431,7 +427,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
final BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, bcData);
for (int i = 0; i < 12; i++) {
for (final BarChart.Data barData : bc.getData().get(0).getData()) {
for (final BarChart.Data<String,Number> barData : bc.getData().get(0).getData()) {
//Note:
// All the charts of this package have a problem where when the chart gets below a certain pixel ratio, the barData stops drawing. The axes and the labels remain,
// But the actual chart barData is invisible, unclickable, and unrendered. To partially compensate for that, barData.getNode() can be manually scaled up to increase visibility.
@ -454,7 +450,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
Platform.runLater(new Runnable() {
@Override
public void run() {
fxChartEvents = createEventsByMonth(findMonth(ye.months, monthStringToInt((String) barData.getXValue())), ye);
fxChartEvents = createEventsByMonth(findMonth(ye.months, monthStringToInt(barData.getXValue())), ye);
fxScrollEvents.setContent(fxChartEvents);
}
});
@ -477,20 +473,22 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
* Displays a chart with events from one month only.
* Up to 31 days per month, as low as 28 as determined by the specific MonthEpoch
*/
private BarChart createEventsByMonth(final MonthEpoch me, final YearEpoch ye) {
private BarChart<String,Number> createEventsByMonth(final MonthEpoch me, final YearEpoch ye) {
final CategoryAxis xAxis = new CategoryAxis();
final NumberAxis yAxis = new NumberAxis();
xAxis.setLabel("Day of Month");
yAxis.setLabel("Number of Events");
ObservableList<BarChart.Data> bcData = makeObservableListByMonthAllDays(me, ye.getYear());
BarChart.Series<String, Number> series = new BarChart.Series(bcData);
ObservableList<BarChart.Data<String,Number>> bcData
= makeObservableListByMonthAllDays(me, ye.getYear());
BarChart.Series<String, Number> series = new BarChart.Series<String,Number>(bcData);
series.setName(me.getMonthName() + " " + ye.getYear());
ObservableList<BarChart.Series<String, Number>> ol = FXCollections.observableArrayList(series);
ObservableList<BarChart.Series<String, Number>> ol =
FXCollections.<BarChart.Series<String, Number>>observableArrayList(series);
final BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, ol);
for (final BarChart.Data barData : bc.getData().get(0).getData()) {
for (final BarChart.Data<String,Number> barData : bc.getData().get(0).getData()) {
//data.getNode().setScaleX(2);
final javafx.scene.Node barNode = barData.getNode();
@ -505,7 +503,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
@Override
public void handle(MouseEvent e) {
final int day = (Integer.valueOf(((String) barData.getXValue()).split("-")[1]));
final int day = (Integer.valueOf((barData.getXValue()).split("-")[1]));
final DayEpoch de = myme.getDay(day);
final List<AbstractFile> afs;
if (de != null) {
@ -535,13 +533,13 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
return bc;
}
private static ObservableList<BarChart.Data> makeObservableListByMonthAllDays(final MonthEpoch me, int year) {
ObservableList<BarChart.Data> bcData = FXCollections.observableArrayList();
private static ObservableList<BarChart.Data<String,Number>> makeObservableListByMonthAllDays(final MonthEpoch me, int year) {
ObservableList<BarChart.Data<String,Number>> bcData = FXCollections.observableArrayList();
int totalDays = me.getTotalNumDays(year);
for (int i = 1; i <= totalDays; ++i) {
DayEpoch day = me.getDay(i);
int numFiles = day == null ? 0 : day.getNumFiles();
BarChart.Data d = new BarChart.Data(me.month + 1 + "-" + i, numFiles);
BarChart.Data<String,Number> d = new BarChart.Data<String,Number>(me.month + 1 + "-" + i, numFiles);
d.setExtraValue(me);
bcData.add(d);
}

View File

@ -1,11 +1,11 @@
#Updated by build script
#Thu, 23 May 2013 00:04:58 -0400
#Sun, 02 Jun 2013 00:12:29 -0400
LBL_splash_window_title=Starting Autopsy
SPLASH_HEIGHT=288
SPLASH_WIDTH=538
SplashProgressBarBounds=3,236,533,6
SplashRunningTextBounds=5,212,530,17
SplashProgressBarBounds=3,282,533,6
SplashRunningTextBounds=5,266,530,17
SplashRunningTextColor=0x0
SplashRunningTextFontSize=18
currentVersion=Autopsy 20130523
currentVersion=Autopsy 20130602

View File

@ -26,10 +26,10 @@
</p>
<p>Note that Autopsy 3 is a complete rewrite from Autopsy 2 and none of this document is relevant to Autopsy 2.</p>
<h1>Adding a Disk Image</h1>
<h1>Adding a Data Source (image, local disk, logical files)</h1>
<p>
Disk images are added to a <strong>case</strong>. A case can have a single image or it can have multiple images if they are related.
Currently, a single report is generated for an entire case, so if you need to report on individual images, then you should use one image per case.
Data sources are added to a <strong>case</strong>. A case can have a single data source or it can have multiple data source if they are related.
Currently, a single report is generated for an entire case, so if you need to report on individual data sources, then you should use one data source per case.
</p>
<h2>Creating a Case</h2>
@ -40,16 +40,32 @@
</p>
<h2>Adding an Image</h2>
<h2>Adding a Data Source</h2>
<p>
The next step is to add a disk image to the case.
The <strong>Add Image Wizard</strong> will start automatically after the case is created or you can manually start it from the &quot;File&quot; menu or toolbar.
You will need to supply it with the location of the disk image to add. Autopsy currently supports E01 and raw (dd) files.
You need to specify only the first file in an image set (i.e. the E01 file) and Autopsy will find the rest of the files.
The next step is to add input data source to the case.
The <strong>Add Data Source Wizard</strong> will start automatically after the case is created or you can manually start it from the &quot;File&quot; menu or toolbar.
You will need to choose the type of input data source to add (image, local disk or logical files and folders).
Next, supply it with the location of the source to add.
</p>
<ul>
<li>For image, point to location of disk image on your system. Autopsy currently supports E01 and raw (dd) files.
For multi-part/split images, you will need to specify only the first file in an image set (i.e. the E01 file) and Autopsy will find the rest of the files.
</li>
<li>
For local disk, select one of the detected disks.
Autopsy will add the current view of the disk to the case (i.e. snapshot of the meta-data).
However, the individual file content (not meta-data) does get updated with the changes made to the disk.
Note, you may need run Autopsy as an Administrator to detect all disks.
</li>
<li>For logical files, add one or more local files or folders on your system.</li>
</ul>
<p>
It may take a few minutes to add the disk image.
It may take a few minutes to add the data source to the case.
During this time, an internal database is being created of the file system contents.
</p>
@ -105,7 +121,9 @@
<img src="screenshot.png" alt="Autopsy Screenshot" />
<p>You will start all of your analysis techniques from the tree on the left.</p>
<ul>
<li>The Images node shows the file system structure of the disk images.</li>
<li>The Data Sources root node shows all data in the case.</li>
<li>The individual image nodes show the file system structure of the disk images or local disks in the case.</li>
<li>The LogicalFileSet nodes show the logical files in the case.</li>
<li>The Views node shows the same data from a file type or timeline perspective.</li>
<li>The Results node shows the output from the ingest modules.</li>
</ul>
@ -157,7 +175,7 @@
<h2>Known Bad Hash Files</h2>
<p>
If you want to see if the image had known bad files, make sure that the Hash Lookup ingest module was enabled.
If you want to see if the data source had known bad files, make sure that the Hash Lookup ingest module was enabled.
You can then view the &quot;Hashset Hits&quot; section in the &quot;Results&quot; area of the tree on the left.
Note that hash lookup can take a long time, so this section will be updated as long as the ingest process is occurring.
Use the Ingest Inbox to keep track of what known bad files were recently found.
@ -167,7 +185,7 @@
You may find additional files that are relevant and stored in the same folder as this file.
</p>
<h2>Images and Videos</h2>
<h2>Media: Images and Videos</h2>
<p>
If you want to see all images and video on the disk image, then go to the &quot;Views&quot; section in the tree on the left and then &quot;File Types&quot;.
Select either &quot;Images&quot; or &quot;Videos&quot;.

View File

@ -12,7 +12,7 @@ build.type=DEVELOPMENT
update_versions=false
#custom JVM options
#Note: can be higher on 64 bit systems, should be in sync with build.xml
run.args.extra=-J-Xms24m -J-Xmx768m -J-XX:MaxPermSize=256M -J-Xverify:none
run.args.extra=-J-Xms24m -J-Xmx512m -J-XX:MaxPermSize=128M -J-Xverify:none
auxiliary.org-netbeans-modules-apisupport-installer.license-type=apache.v2
auxiliary.org-netbeans-modules-apisupport-installer.os-linux=false
auxiliary.org-netbeans-modules-apisupport-installer.os-macosx=false
@ -30,6 +30,7 @@ modules=\
${project.org.sleuthkit.autopsy.core}:\
${project.org.sleuthkit.autopsy.corelibs}:\
${project.org.sleuthkit.autopsy.sevenzip}:\
${project.org.sleuthkit.autopsy.scalpel}:\
${project.org.sleuthkit.autopsy.timeline}
project.org.sleuthkit.autopsy.core=Core
project.org.sleuthkit.autopsy.corelibs=CoreLibs
@ -40,5 +41,6 @@ project.org.sleuthkit.autopsy.testing=Testing
project.org.sleuthkit.autopsy.thunderbirdparser=thunderbirdparser
project.org.sleuthkit.autopsy.exifparser=ExifParser
project.org.sleuthkit.autopsy.sevenzip=SevenZip
project.org.sleuthkit.autopsy.scalpel=ScalpelCarver
project.org.sleuthkit.autopsy.timeline=Timeline