Merge branch 'develop' of https://github.com/sleuthkit/autopsy into core-directorytree

This commit is contained in:
Nick Davis 2014-03-25 11:59:50 -04:00
commit 024ea401bf
138 changed files with 6000 additions and 7461 deletions

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -19,7 +19,6 @@
package org.sleuthkit.autopsy.casemodule; package org.sleuthkit.autopsy.casemodule;
import org.sleuthkit.autopsy.ingest.IngestConfigurator;
import java.awt.Component; import java.awt.Component;
import java.awt.Dialog; import java.awt.Dialog;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
@ -36,12 +35,12 @@ import org.openide.DialogDisplayer;
import org.openide.WizardDescriptor; import org.openide.WizardDescriptor;
import org.openide.util.ChangeSupport; import org.openide.util.ChangeSupport;
import org.openide.util.HelpCtx; import org.openide.util.HelpCtx;
import org.openide.util.Lookup;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction; import org.openide.util.actions.CallableSystemAction;
import org.openide.util.actions.Presenter; import org.openide.util.actions.Presenter;
import org.openide.util.lookup.ServiceProvider; import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.Image;
/** /**
@ -109,8 +108,7 @@ public final class AddImageAction extends CallableSystemAction implements Presen
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
Logger.noteAction(AddImageAction.class); Logger.noteAction(AddImageAction.class);
final IngestConfigurator ingestConfig = Lookup.getDefault().lookup(IngestConfigurator.class); if (IngestManager.getDefault().isIngestRunning()) {
if (null != ingestConfig && ingestConfig.isIngestRunning()) {
final String msg = NbBundle.getMessage(this.getClass(), "AddImageAction.ingestConfig.ongoingIngest.msg"); final String msg = NbBundle.getMessage(this.getClass(), "AddImageAction.ingestConfig.ongoingIngest.msg");
if (JOptionPane.showConfirmDialog(null, msg, if (JOptionPane.showConfirmDialog(null, msg,
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),

View File

@ -19,8 +19,8 @@
package org.sleuthkit.autopsy.casemodule; package org.sleuthkit.autopsy.casemodule;
import org.sleuthkit.autopsy.ingest.IngestJobLauncher;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.ingest.IngestConfigurator;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Window; import java.awt.Window;
@ -33,7 +33,6 @@ import javax.swing.SwingUtilities;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import org.openide.WizardDescriptor; import org.openide.WizardDescriptor;
import org.openide.util.HelpCtx; import org.openide.util.HelpCtx;
import org.openide.util.Lookup;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback; import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
@ -47,7 +46,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDescriptor> { class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDescriptor> {
private static final Logger logger = Logger.getLogger(AddImageWizardIngestConfigPanel.class.getName()); private static final Logger logger = Logger.getLogger(AddImageWizardIngestConfigPanel.class.getName());
private IngestConfigurator ingestConfig; private IngestJobLauncher ingestConfig;
/** /**
* The visual component that displays this panel. If you need to access the * The visual component that displays this panel. If you need to access the
* component from this class, just use getComponent(). * component from this class, just use getComponent().
@ -74,8 +73,8 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
this.progressPanel = proPanel; this.progressPanel = proPanel;
this.dataSourcePanel = dsPanel; this.dataSourcePanel = dsPanel;
ingestConfig = Lookup.getDefault().lookup(IngestConfigurator.class); ingestConfig = new IngestJobLauncher(AddImageWizardIngestConfigPanel.class.getCanonicalName());
List<String> messages = ingestConfig.setContext(AddImageWizardIngestConfigPanel.class.getCanonicalName()); List<String> messages = ingestConfig.getIngestJobConfigWarnings();
if (messages.isEmpty() == false) { if (messages.isEmpty() == false) {
StringBuilder warning = new StringBuilder(); StringBuilder warning = new StringBuilder();
for (String message : messages) { for (String message : messages) {
@ -96,7 +95,7 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
@Override @Override
public Component getComponent() { public Component getComponent() {
if (component == null) { if (component == null) {
component = new AddImageWizardIngestConfigVisual(ingestConfig.getIngestConfigPanel()); component = new AddImageWizardIngestConfigVisual(ingestConfig.getIngestJobConfigPanel());
} }
return component; return component;
} }
@ -188,8 +187,8 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
*/ */
@Override @Override
public void storeSettings(WizardDescriptor settings) { public void storeSettings(WizardDescriptor settings) {
//save previously selected config ingestConfig.saveIngestJobConfig();
ingestConfig.save();
// Start ingest if it hasn't already been started // Start ingest if it hasn't already been started
readyToIngest = true; readyToIngest = true;
startIngest(); startIngest();
@ -202,8 +201,7 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
private void startIngest() { private void startIngest() {
if (!newContents.isEmpty() && readyToIngest && !ingested) { if (!newContents.isEmpty() && readyToIngest && !ingested) {
ingested = true; ingested = true;
ingestConfig.setContent(newContents); ingestConfig.startIngestJobs(newContents);
ingestConfig.start();
progressPanel.setStateFinished(); progressPanel.setStateFinished();
} }

View File

@ -114,13 +114,13 @@ class DirectoryTreeFilterNode extends FilterNode {
//ingest action //ingest action
actions.add(new AbstractAction( actions.add(new AbstractAction(
NbBundle.getMessage(this.getClass(), "DirectoryTreeFilterNode.action.runIngestMods.text")) { NbBundle.getMessage(this.getClass(), "DirectoryTreeFilterNode.action.runIngestMods.text")) {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
final IngestDialog ingestDialog = new IngestDialog(); final IngestDialog ingestDialog = new IngestDialog();
ingestDialog.setContent(Collections.<Content>singletonList(content)); ingestDialog.setDataSources(Collections.<Content>singletonList(content));
ingestDialog.display(); ingestDialog.display();
} }
}); });
} }
//check if delete actions should be added //check if delete actions should be added
@ -141,7 +141,7 @@ class DirectoryTreeFilterNode extends FilterNode {
} }
private static List<Action> getDetailActions(Content c) { private static List<Action> getDetailActions(Content c) {
List<Action> actions = new ArrayList<Action>(); List<Action> actions = new ArrayList<>();
actions.addAll(ExplorerNodeActionVisitor.getActions(c)); actions.addAll(ExplorerNodeActionVisitor.getActions(c));

View File

@ -64,7 +64,7 @@ import org.sleuthkit.autopsy.datamodel.RootContentChildren;
import org.sleuthkit.autopsy.datamodel.Views; import org.sleuthkit.autopsy.datamodel.Views;
import org.sleuthkit.autopsy.datamodel.ViewsNode; import org.sleuthkit.autopsy.datamodel.ViewsNode;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent; import org.sleuthkit.autopsy.ingest.IngestManager.IngestEvent;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
@ -587,7 +587,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
// change in node selection // change in node selection
else if (changed.equals(ExplorerManager.PROP_SELECTED_NODES)) { else if (changed.equals(ExplorerManager.PROP_SELECTED_NODES)) {
respondSelection((Node[]) oldValue, (Node[]) newValue); respondSelection((Node[]) oldValue, (Node[]) newValue);
} else if (changed.equals(IngestModuleEvent.DATA.toString())) { } else if (changed.equals(IngestEvent.DATA.toString())) {
final ModuleDataEvent event = (ModuleDataEvent) oldValue; final ModuleDataEvent event = (ModuleDataEvent) oldValue;
if (event.getArtifactType() == BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO) { if (event.getArtifactType() == BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO) {
return; return;
@ -598,7 +598,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
refreshTree(event.getArtifactType()); refreshTree(event.getArtifactType());
} }
}); });
} else if (changed.equals(IngestModuleEvent.COMPLETED.toString())) { } else if (changed.equals(IngestEvent.COMPLETED.toString())) {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -606,7 +606,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
refreshTree(); refreshTree();
} }
}); });
} else if (changed.equals(IngestModuleEvent.CONTENT_CHANGED.toString())) { } else if (changed.equals(IngestEvent.CONTENT_CHANGED.toString())) {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {

View File

@ -1,33 +1,32 @@
/* /*
* Sample module in the public domain. Feel free to use this as a template * Sample module in the public domain. Feel free to use this as a template
* for your modules. * for your modules.
* *
* Contact: Brian Carrier [carrier <at> sleuthkit [dot] org] * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
* *
* This is free and unencumbered software released into the public domain. * This is free and unencumbered software released into the public domain.
* *
* Anyone is free to copy, modify, publish, use, compile, sell, or * Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a compiled * distribute this software, either in source code form or as a compiled
* binary, for any purpose, commercial or non-commercial, and by any * binary, for any purpose, commercial or non-commercial, and by any
* means. * means.
* *
* In jurisdictions that recognize copyright laws, the author or authors * In jurisdictions that recognize copyright laws, the author or authors
* of this software dedicate any and all copyright interest in the * of this software dedicate any and all copyright interest in the
* software to the public domain. We make this dedication for the benefit * software to the public domain. We make this dedication for the benefit
* of the public at large and to the detriment of our heirs and * of the public at large and to the detriment of our heirs and
* successors. We intend this dedication to be an overt act of * successors. We intend this dedication to be an overt act of
* relinquishment in perpetuity of all present and future rights to this * relinquishment in perpetuity of all present and future rights to this
* software under copyright law. * software under copyright law.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*/ */
package org.sleuthkit.autopsy.examples; package org.sleuthkit.autopsy.examples;
import java.util.List; import java.util.List;
@ -35,10 +34,10 @@ import org.apache.log4j.Logger;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.FileManager; import org.sleuthkit.autopsy.casemodule.services.FileManager;
import org.sleuthkit.autopsy.casemodule.services.Services; import org.sleuthkit.autopsy.casemodule.services.Services;
import org.sleuthkit.autopsy.ingest.IngestDataSourceWorkerController; import org.sleuthkit.autopsy.ingest.DataSourceIngestModule;
import org.sleuthkit.autopsy.ingest.IngestModuleDataSource; import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleStatusHelper;
import org.sleuthkit.autopsy.ingest.IngestModuleInit; import org.sleuthkit.autopsy.ingest.IngestModule;
import org.sleuthkit.autopsy.ingest.PipelineContext; import org.sleuthkit.autopsy.ingest.IngestModuleAdapter;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.FsContent; import org.sleuthkit.datamodel.FsContent;
@ -46,74 +45,40 @@ import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
/** /**
* Sample DataSource-level ingest module that doesn't do much at all. * Sample data source ingest module that doesn't do much. Note that the
* Just exists to show basic idea of these modules * IngestModuleAdapter abstract class could have been used as a base class to
* obtain default implementations of many of the DataSourceIngestModule methods.
*/ */
public class SampleDataSourceIngestModule extends org.sleuthkit.autopsy.ingest.IngestModuleDataSource { // RJCTODO: Remove inheritance from IngestModuleAdapter to show full implementation of interface
/* Data Source modules operate on a disk or set of logical files. They // provide better documentation, and provide more extensive demonstration of how to
* are passed in teh data source refernce and query it for things they want. // use various ingest services.
*/ class SampleDataSourceIngestModule extends IngestModuleAdapter implements DataSourceIngestModule {
@Override
public void process(PipelineContext<IngestModuleDataSource> pipelineContext, Content dataSource, IngestDataSourceWorkerController controller) {
private static final Logger logger = Logger.getLogger(SampleDataSourceIngestModule.class);
@Override
public ProcessResult process(Content dataSource, DataSourceIngestModuleStatusHelper statusHelper) {
Case case1 = Case.getCurrentCase(); Case case1 = Case.getCurrentCase();
SleuthkitCase sleuthkitCase = case1.getSleuthkitCase(); SleuthkitCase sleuthkitCase = case1.getSleuthkitCase();
Services services = new Services(sleuthkitCase); Services services = new Services(sleuthkitCase);
FileManager fm = services.getFileManager(); FileManager fileManager = services.getFileManager();
try { try {
/* you can use the findFiles method in FileManager (or similar ones in List<AbstractFile> docFiles = fileManager.findFiles(dataSource, "%.doc");
* SleuthkitCase to find files based only on their name. This
* one finds files that have a .doc extension. */
List<AbstractFile> docFiles = fm.findFiles(dataSource, "%.doc");
for (AbstractFile file : docFiles) { for (AbstractFile file : docFiles) {
// do something with each doc file // do something with each doc file
} }
/* We can also do more general queries with findFilesWhere, which long currentTime = System.currentTimeMillis() / 1000;
* allows us to make our own WHERE clause in the database. long minTime = currentTime - (14 * 24 * 60 * 60); // Go back two weeks.
*/
long currentTime = System.currentTimeMillis()/1000;
// go back 2 weeks
long minTime = currentTime - (14 * 24 * 60 * 60);
List<FsContent> otherFiles = sleuthkitCase.findFilesWhere("crtime > " + minTime); List<FsContent> otherFiles = sleuthkitCase.findFilesWhere("crtime > " + minTime);
// do something with these files... // do something with these files...
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
Logger log = Logger.getLogger(SampleDataSourceIngestModule.class); logger.fatal("Error retrieving files from database: " + ex.getLocalizedMessage());
log.fatal("Error retrieving files from database: " + ex.getLocalizedMessage()); return IngestModule.ProcessResult.OK;
} }
}
@Override return IngestModule.ProcessResult.OK;
public void init(IngestModuleInit initContext) throws IngestModuleException {
}
@Override
public void complete() {
}
@Override
public void stop() {
}
@Override
public String getName() {
return "SampleDataSourceIngestModule";
}
@Override
public String getVersion() {
return "1.0";
}
@Override
public String getDescription() {
return "Doesn't do much";
}
@Override
public boolean hasBackgroundJobsRunning() {
return false;
} }
} }

View File

@ -32,9 +32,10 @@ package org.sleuthkit.autopsy.examples;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.openide.util.Exceptions; import org.openide.util.Exceptions;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile; import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestModuleInit; import org.sleuthkit.autopsy.ingest.IngestModule;
import org.sleuthkit.autopsy.ingest.PipelineContext; import org.sleuthkit.autopsy.ingest.IngestModuleAdapter;
import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
@ -53,26 +54,15 @@ import org.sleuthkit.datamodel.TskData;
* org.sleuthkit.autopsy.examples package. Either change the package or the * org.sleuthkit.autopsy.examples package. Either change the package or the
* loading code to make this module actually run. * loading code to make this module actually run.
*/ */
public class SampleFileIngestModule extends org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile { // RJCTODO: Remove inheritance from IngestModuleAdapter to show full implementation of interface
// provide better documentation, and provide more extensive demonstration of how to
// use various ingest services.
class SampleFileIngestModule extends IngestModuleAdapter implements FileIngestModule {
private int attrId = -1; private int attrId = -1;
private static SampleFileIngestModule defaultInstance = null;
// Private to ensure Singleton status
private SampleFileIngestModule() {
}
// File-level ingest modules are currently singleton -- this is required
public static synchronized SampleFileIngestModule getDefault() {
//defaultInstance is a private static class variable
if (defaultInstance == null) {
defaultInstance = new SampleFileIngestModule();
}
return defaultInstance;
}
@Override @Override
public void init(IngestModuleInit initContext) throws IngestModuleException { public void startUp(IngestJobContext initContext) {
/* For this demo, we are going to make a private attribute to post our /* For this demo, we are going to make a private attribute to post our
* results to the blackbaord with. There are many standard blackboard artifact * results to the blackbaord with. There are many standard blackboard artifact
* and attribute types and you should first consider using one of those before * and attribute types and you should first consider using one of those before
@ -99,19 +89,18 @@ public class SampleFileIngestModule extends org.sleuthkit.autopsy.ingest.IngestM
} }
@Override @Override
public ProcessResult process(PipelineContext<IngestModuleAbstractFile> pipelineContext, AbstractFile abstractFile) { public IngestModule.ProcessResult process(AbstractFile abstractFile) {
// skip non-files // skip non-files
if ((abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) if ((abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
|| (abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)) { || (abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)) {
return ProcessResult.OK; return IngestModule.ProcessResult.OK;
} }
// skip NSRL / known files // skip NSRL / known files
if (abstractFile.getKnown() == TskData.FileKnown.KNOWN) { if (abstractFile.getKnown() == TskData.FileKnown.KNOWN) {
return ProcessResult.OK; return IngestModule.ProcessResult.OK;
} }
/* Do a non-sensical calculation of the number of 0x00 bytes /* Do a non-sensical calculation of the number of 0x00 bytes
* in the first 1024-bytes of the file. This is for demo * in the first 1024-bytes of the file. This is for demo
* purposes only. * purposes only.
@ -128,7 +117,7 @@ public class SampleFileIngestModule extends org.sleuthkit.autopsy.ingest.IngestM
if (attrId != -1) { if (attrId != -1) {
// Make an attribute using the ID for the private type that we previously created. // Make an attribute using the ID for the private type that we previously created.
BlackboardAttribute attr = new BlackboardAttribute(attrId, getName(), count); BlackboardAttribute attr = new BlackboardAttribute(attrId, "SampleFileIngestModule", count); // RJCTODO: Set up factory with static module name function as example
/* add it to the general info artifact. In real modules, you would likely have /* add it to the general info artifact. In real modules, you would likely have
* more complex data types and be making more specific artifacts. * more complex data types and be making more specific artifacts.
@ -137,38 +126,12 @@ public class SampleFileIngestModule extends org.sleuthkit.autopsy.ingest.IngestM
art.addAttribute(attr); art.addAttribute(attr);
} }
return ProcessResult.OK; return IngestModule.ProcessResult.OK;
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
Exceptions.printStackTrace(ex); Exceptions.printStackTrace(ex);
return ProcessResult.ERROR; return IngestModule.ProcessResult.ERROR;
} }
} }
@Override // RJCTODO: Add a module factory with service provider annotation (commented out)
public void complete() {
}
@Override
public void stop() {
}
@Override
public String getVersion() {
return "1.0";
}
@Override
public String getName() {
return "SampleFileIngestModule";
}
@Override
public String getDescription() {
return "Doesn't do much";
}
@Override
public boolean hasBackgroundJobsRunning() {
return false;
}
} }

View File

@ -6,7 +6,6 @@ IngestMessageDetailsPanel.viewArtifactButton.text=Go to Result
IngestMessageDetailsPanel.viewContentButton.text=Go to Directory IngestMessageDetailsPanel.viewContentButton.text=Go to Directory
IngestMessagePanel.sortByLabel.text=Sort by: IngestMessagePanel.sortByLabel.text=Sort by:
IngestMessagePanel.sortByComboBox.toolTipText=Sort messages by time (chronological order) or message priority IngestMessagePanel.sortByComboBox.toolTipText=Sort messages by time (chronological order) or message priority
IngestDialogPanel.advancedButton.text=Advanced
IngestMessageDetailsPanel.messageDetailsPane.contentType=text/html IngestMessageDetailsPanel.messageDetailsPane.contentType=text/html
IngestMessageDetailsPanel.messageDetailsPane.toolTipText= IngestMessageDetailsPanel.messageDetailsPane.toolTipText=
IngestMessagesToolbar.toolTipText= IngestMessagesToolbar.toolTipText=
@ -17,16 +16,14 @@ IngestMessagePanel.totalMessagesNameLabel.text=Total:
IngestMessagePanel.totalMessagesNameVal.text=- IngestMessagePanel.totalMessagesNameVal.text=-
IngestMessagePanel.totalUniqueMessagesNameLabel.text=Unique: IngestMessagePanel.totalUniqueMessagesNameLabel.text=Unique:
IngestMessagePanel.totalUniqueMessagesNameVal.text=- IngestMessagePanel.totalUniqueMessagesNameVal.text=-
IngestDialogPanel.processUnallocCheckbox.text=Process Unallocated Space IngestJobConfigurationPanel.processUnallocCheckbox.toolTipText=Processes unallocated space, such as deleted files. Produces more complete results, but it may take longer to process on large images.
IngestDialogPanel.processUnallocCheckbox.toolTipText=Processes unallocated space, such as deleted files. Produces more complete results, but it may take longer to process on large images. IngestJobConfigurationPanel.processUnallocCheckbox.text=Process Unallocated Space
DataSourceTask.toString.text=ScheduledTask'{'input\={0}, modules\={1}'}' IngestJobConfigurationPanel.advancedButton.text=Advanced
GeneralIngestConfigurator.modName.tbirdParser.text=Thunderbird Parser IngestJob.toString.text=ScheduledTask'{'input\={0}, modules\={1}'}'
GeneralIngestConfigurator.modName.mboxParser.text=MBox Parser IngestJobLauncher.modName.tbirdParser.text=Thunderbird Parser
GeneralIngestConfigurator.modName.emailParser.text=Email Parser IngestJobLauncher.modName.mboxParser.text=MBox Parser
GeneralIngestConfigurator.enabledMods.notFound.msg={0} was previously enabled, but could not be found IngestJobLauncher.modName.emailParser.text=Email Parser
IngestDataSourceThread.displayName.text={0} dataSource id\:{1} IngestJobLauncher.enabledMods.notFound.msg={0} was previously enabled, but could not be found
IngestDataSourceThread.progress.pending={0} (Pending...)
IngestDataSourceThread.progress.cancelling={0} (Cancelling...)
IngestDialog.title.text=Ingest Modules IngestDialog.title.text=Ingest Modules
IngestDialog.startButton.title=Start IngestDialog.startButton.title=Start
IngestDialog.closeButton.title=Close IngestDialog.closeButton.title=Close
@ -49,12 +46,15 @@ IngestManager.toHtmlStr.totalErrs.text=Total errors\: {0}
IngestManager.toHtmlStr.module.text=Module IngestManager.toHtmlStr.module.text=Module
IngestManager.toHtmlStr.time.text=Time IngestManager.toHtmlStr.time.text=Time
IngestManager.toHtmlStr.errors.text=Errors IngestManager.toHtmlStr.errors.text=Errors
IngestManager.IngestAbstractFileProcessor.displayName=File Ingest IngestManager.FileTaskWorker.displayName=File Ingest
IngestManager.IngestAbstractFileProcessor.process.cancelling={0} (Cancelling...) IngestManager.FileTaskWorker.process.cancelling={0} (Cancelling...)
IngestManager.EnqueueWorker.displayName.text=Queueing Ingest IngestManager.EnqueueWorker.displayName.text=Queueing Ingest
IngestManager.EnqueueWorker.process.cancelling={0} (Cancelling...) IngestManager.EnqueueWorker.process.cancelling={0} (Cancelling...)
IngestManager.DataSourceTaskWorker.progress.pending={0} (Pending...)
IngestManager.DataSourceTaskWorker.progress.cancelling={0} (Cancelling...)
IngestManager.datatSourceIngest.progress.text=DataSource Ingest {0} IngestManager.datatSourceIngest.progress.text=DataSource Ingest {0}
IngestManager.fileIngest.progress.text=File Ingest {0} IngestManager.fileIngest.progress.text=File Ingest {0}
IngestJob.DataSourceIngestPipeline.displayName.text={0} processing {1}
IngestMessage.toString.type.text=type\: {0} IngestMessage.toString.type.text=type\: {0}
IngestMessage.toString.source.text=\ source\: {0} IngestMessage.toString.source.text=\ source\: {0}
IngestMessage.toString.date.text=\ date\: {0} IngestMessage.toString.date.text=\ date\: {0}
@ -101,4 +101,3 @@ IngestScheduler.remove.exception.notSupported.msg=Not supported.
IngestScheduler.DataSourceScheduler.exception.next.msg=There is no data source tasks in the queue, check hasNext() IngestScheduler.DataSourceScheduler.exception.next.msg=There is no data source tasks in the queue, check hasNext()
IngestScheduler.DataSourceScheduler.exception.remove.msg=Removing of scheduled data source ingest tasks is not supported. IngestScheduler.DataSourceScheduler.exception.remove.msg=Removing of scheduled data source ingest tasks is not supported.
IngestScheduler.DataSourceScheduler.toString.size=DataSourceQueue, size\: {0} IngestScheduler.DataSourceScheduler.toString.size=DataSourceQueue, size\: {0}
PipelineContext.toString.text=pipelineContext'{'task\={0}'}'

View File

@ -0,0 +1,37 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.ingest;
import org.sleuthkit.datamodel.Content;
/**
* Interface that must be implemented by all data source ingest modules.
*/
public interface DataSourceIngestModule extends IngestModule {
/**
* Processes a data source.
*
* @param dataSource The data source to process.
* @param statusHelper A status helper to be used to report progress and
* detect ingest job cancellation.
* @return A result code indicating success or failure of the processing.
*/
ProcessResult process(Content dataSource, DataSourceIngestModuleStatusHelper statusHelper);
}

View File

@ -0,0 +1,87 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2014 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.ingest;
import javax.swing.SwingWorker;
import org.netbeans.api.progress.ProgressHandle;
import org.sleuthkit.datamodel.Content;
/**
* Used by data source ingest modules to report progress and detect data source
* ingest job cancellation.
*/
public class DataSourceIngestModuleStatusHelper {
private final SwingWorker worker;
private final ProgressHandle progress;
private final Content dataSource;
DataSourceIngestModuleStatusHelper(SwingWorker worker, ProgressHandle progress, Content dataSource) {
this.worker = worker;
this.progress = progress;
this.dataSource = dataSource;
}
/**
* Checks for ingest job cancellation. This should be polled by the module
* in its process() method. If the ingest task is canceled, the module
* should return from its process() method as quickly as possible.
*
* @return True if the task has been canceled, false otherwise.
*/
public boolean isCancelled() {
return worker.isCancelled();
}
/**
* Updates the progress bar and switches it to determinate mode. This should
* be called by the module as soon as the number of total work units
* required to process the data source is known.
*
* @param workUnits Total number of work units for the processing of the
* data source.
*/
public void switchToDeterminate(int workUnits) {
if (progress != null) {
progress.switchToDeterminate(workUnits);
}
}
/**
* Switches the progress bar to indeterminate mode. This should be called if
* the total work units to process the data source is unknown.
*/
public void switchToIndeterminate() {
if (progress != null) {
progress.switchToIndeterminate();
}
}
/**
* Updates the progress bar with the number of work units performed, if in
* the determinate mode.
*
* @param workUnits Number of work units performed so far by the module.
*/
public void progress(int workUnits) {
if (progress != null) {
progress.progress(dataSource.getName(), workUnits);
}
}
}

View File

@ -1,106 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-2014 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.ingest;
import java.util.List;
import org.openide.util.NbBundle;
import org.sleuthkit.datamodel.Content;
/**
* Represents a data source-level task to schedule and analyze.
* Children of the data will also be scheduled.
*
* @param T type of Ingest Module / Pipeline (file or data source content) associated with this task
*/
class DataSourceTask<T extends IngestModuleAbstract> {
private Content input;
private List<T> modules;
private boolean processUnallocated;
private PipelineContext<T> pipelineContext;
public DataSourceTask(Content input, List<T> modules, boolean processUnallocated) {
this.input = input;
this.modules = modules;
this.processUnallocated = processUnallocated;
pipelineContext = new PipelineContext(this);
}
public Content getContent() {
return input;
}
public PipelineContext<T> getPipelineContext() {
return pipelineContext;
}
public List<T> getModules() {
return modules;
}
/**
* Returns value of if unallocated space should be analyzed (and scheduled)
* @return True if pipeline should process unallocated space.
*/
boolean isProcessUnalloc() {
return processUnallocated;
}
// @@@ BC: I think this should go away.
void addModules(List<T> newModules) {
for (T newModule : newModules) {
if (!modules.contains(newModule)) {
modules.add(newModule);
}
}
}
@Override
public String toString() {
return NbBundle.getMessage(this.getClass(), "DataSourceTask.toString.text", input, modules);
}
/**
* Two scheduled tasks are equal when the content and modules are the same.
* This enables us not to enqueue the equal schedules tasks twice into the
* queue/set
*
* @param obj
* @return
*/
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
@SuppressWarnings("unchecked")
final DataSourceTask<T> other = (DataSourceTask<T>) obj;
if (this.input != other.input && (this.input == null || !this.input.equals(other.input))) {
return false;
}
if (this.modules != other.modules && (this.modules == null || !this.modules.equals(other.modules))) {
return false;
}
return true;
}
}

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2012 Basis Technology Corp. * Copyright 2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -18,32 +18,18 @@
*/ */
package org.sleuthkit.autopsy.ingest; package org.sleuthkit.autopsy.ingest;
import org.sleuthkit.datamodel.AbstractFile;
/** /**
* * Interface that must be implemented by all file ingest modules.
* Context passed to a module at initialization time.
* It may contain module configuration required to initialize some modules.
*/ */
public class IngestModuleInit { public interface FileIngestModule extends IngestModule {
// private String moduleArgs;
/** /**
* Get module arguments * Processes a file.
* @return module args string, used by some modules *
* @param file The file.
* @return A result code indicating success or failure of the processing.
*/ */
// public String getModuleArgs() { ProcessResult process(AbstractFile file);
// return moduleArgs;
// }
/**
* Sets module args. string (only used by module pipeline)
* @param moduleArgs arguments to set for the module
*/
// void setModuleArgs(String moduleArgs) {
// this.moduleArgs = moduleArgs;
// }
//
} }

View File

@ -1,213 +0,0 @@
/*
* 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.ingest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JPanel;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.datamodel.Content;
@ServiceProvider(service = IngestConfigurator.class)
public class GeneralIngestConfigurator implements IngestConfigurator {
public static final String ENABLED_INGEST_MODULES_KEY = "Enabled_Ingest_Modules";
public static final String DISABLED_INGEST_MODULES_KEY = "Disabled_Ingest_Modules";
public static final String PARSE_UNALLOC_SPACE_KEY = "Process_Unallocated_Space";
private List<Content> contentToIngest;
private IngestManager manager;
private IngestDialogPanel ingestDialogPanel;
private String moduleContext;
public GeneralIngestConfigurator() {
this.moduleContext = IngestManager.MODULE_PROPERTIES;
ingestDialogPanel = new IngestDialogPanel();
ingestDialogPanel.setContext(moduleContext);
manager = IngestManager.getDefault();
}
@Override
public List<String> setContext(String context) {
moduleContext = context;
ingestDialogPanel.setContext(moduleContext);
return loadSettingsForContext();
}
private List<String> loadSettingsForContext() {
List<String> messages = new ArrayList<>();
List<IngestModuleAbstract> allModules = IngestManager.getDefault().enumerateAllModules();
// If there is no enabled ingest modules setting for this user, default to enabling all
// of the ingest modules the IngestManager has loaded.
if (ModuleSettings.settingExists(moduleContext, ENABLED_INGEST_MODULES_KEY) == false) {
String defaultSetting = moduleListToCsv(allModules);
ModuleSettings.setConfigSetting(moduleContext, ENABLED_INGEST_MODULES_KEY, defaultSetting);
}
String[] enabledModuleNames = ModuleSettings.getConfigSetting(moduleContext, ENABLED_INGEST_MODULES_KEY).split(", ");
ArrayList<String> enabledList = new ArrayList<>(Arrays.asList(enabledModuleNames));
// Check for modules that are missing from the config file
String[] disabledModuleNames = null;
// Older config files won't have the disabled list, so don't assume it exists
if (ModuleSettings.settingExists(moduleContext, DISABLED_INGEST_MODULES_KEY)) {
disabledModuleNames = ModuleSettings.getConfigSetting(moduleContext, DISABLED_INGEST_MODULES_KEY).split(", ");
}
for (IngestModuleAbstract module : allModules) {
boolean found = false;
// Check enabled first
for (String moduleName : enabledModuleNames) {
if (module.getName().equals(moduleName)) {
found = true;
break;
}
}
// Then check disabled
if (!found && (disabledModuleNames != null)) {
for (String moduleName : disabledModuleNames) {
if (module.getName().equals(moduleName)) {
found = true;
break;
}
}
}
if (!found) {
enabledList.add(module.getName());
// It will get saved to file later
}
}
// Get the enabled ingest modules setting, check for missing modules, and pass the setting to
// the UI component.
List<IngestModuleAbstract> enabledModules = new ArrayList<>();
for (String moduleName : enabledList) {
if (moduleName.equals(
NbBundle.getMessage(this.getClass(), "GeneralIngestConfigurator.modName.tbirdParser.text"))
|| moduleName.equals(
NbBundle.getMessage(this.getClass(), "GeneralIngestConfigurator.modName.mboxParser.text"))) {
moduleName = NbBundle.getMessage(this.getClass(), "GeneralIngestConfigurator.modName.emailParser.text");
}
IngestModuleAbstract moduleFound = null;
for (IngestModuleAbstract module : allModules) {
if (moduleName.equals(module.getName())) {
moduleFound = module;
break;
}
}
if (moduleFound != null) {
enabledModules.add(moduleFound);
}
else {
messages.add(NbBundle.getMessage(this.getClass(), "GeneralIngestConfigurator.enabledMods.notFound.msg",
moduleName));
}
}
ingestDialogPanel.setEnabledIngestModules(enabledModules);
// If there is no process unallocated space flag setting, default it to false.
if (ModuleSettings.settingExists(moduleContext, PARSE_UNALLOC_SPACE_KEY) == false) {
ModuleSettings.setConfigSetting(moduleContext, PARSE_UNALLOC_SPACE_KEY, "false");
}
// Get the process unallocated space flag setting and pass it to the UI component.
boolean processUnalloc = Boolean.parseBoolean(ModuleSettings.getConfigSetting(moduleContext, PARSE_UNALLOC_SPACE_KEY));
ingestDialogPanel.setProcessUnallocSpaceEnabled(processUnalloc);
return messages;
}
@Override
public JPanel getIngestConfigPanel() {
// Note that this panel allows for selecting modules for the ingest process,
// specifying the process unallocated space flag, and also specifying settings
// for a selected ingest module.
return ingestDialogPanel;
}
@Override
public void save() {
// Save the user's configuration of the set of enabled ingest modules.
String enabledModulesCsvList = moduleListToCsv(ingestDialogPanel.getModulesToStart());
ModuleSettings.setConfigSetting(moduleContext, ENABLED_INGEST_MODULES_KEY, enabledModulesCsvList);
// Save the user's configuration of the set of disabled ingest modules.
String disabledModulesCsvList = moduleListToCsv(ingestDialogPanel.getDisabledModules());
ModuleSettings.setConfigSetting(moduleContext, DISABLED_INGEST_MODULES_KEY, disabledModulesCsvList);
// Save the user's setting for the process unallocated space flag.
String processUnalloc = Boolean.toString(ingestDialogPanel.processUnallocSpaceEnabled());
ModuleSettings.setConfigSetting(moduleContext, PARSE_UNALLOC_SPACE_KEY, processUnalloc);
// Save the user's configuration of the currently selected ingest module.
IngestModuleAbstract currentModule = ingestDialogPanel.getCurrentIngestModule();
if (currentModule != null && currentModule.hasSimpleConfiguration()) {
currentModule.saveSimpleConfiguration();
}
}
private static String moduleListToCsv(List<IngestModuleAbstract> lst) {
if (lst == null || lst.isEmpty()) {
return "";
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < lst.size() - 1; ++i) {
sb.append(lst.get(i).getName()).append(", ");
}
// and the last one
sb.append(lst.get(lst.size() - 1).getName());
return sb.toString();
}
@Override
public void setContent(List<Content> inputContent) {
this.contentToIngest = inputContent;
}
@Override
public void start() {
// Get the list of ingest modules selected by the user.
List<IngestModuleAbstract> modulesToStart = ingestDialogPanel.getModulesToStart();
// Get the user's selection of whether or not to process unallocated space.
manager.setProcessUnallocSpace(ingestDialogPanel.processUnallocSpaceEnabled());
if (!modulesToStart.isEmpty() && contentToIngest != null) {
// Queue the ingest process.
manager.scheduleDataSource(modulesToStart, contentToIngest);
}
}
@Override
public boolean isIngestRunning() {
return manager.isIngestRunning();
}
}

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -25,21 +25,17 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor; import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.Directory; import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.FileSystem;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.VirtualDirectory; import org.sleuthkit.datamodel.VirtualDirectory;
import org.sleuthkit.datamodel.TskException; import org.sleuthkit.datamodel.TskException;
import org.sleuthkit.datamodel.Volume; import org.sleuthkit.datamodel.Volume;
import org.sleuthkit.datamodel.VolumeSystem; import org.sleuthkit.datamodel.VolumeSystem;
import org.sleuthkit.datamodel.LayoutFile;
/** /**
* Abstract visitor for getting all the files from content * Abstract visitor for getting all the files from content.
* TODO should be moved to utility module (needs resolve cyclic deps)
*/ */
abstract class GetFilesContentVisitor implements ContentVisitor<Collection<AbstractFile>> { abstract class GetFilesContentVisitor implements ContentVisitor<Collection<AbstractFile>> {
private static final Logger logger = Logger.getLogger(GetFilesContentVisitor.class.getName()); private static final Logger logger = Logger.getLogger(GetFilesContentVisitor.class.getName());
@ -69,13 +65,14 @@ import org.sleuthkit.datamodel.LayoutFile;
} }
/** /**
* Aggregate all the matches from visiting the children Content objects of the * Aggregate all the matches from visiting the children Content objects of
* one passed * a parent Content object.
* @param parent *
* @return * @param parent A content object.
* @return The child files of the content.
*/ */
protected Collection<AbstractFile> getAllFromChildren(Content parent) { protected Collection<AbstractFile> getAllFromChildren(Content parent) {
Collection<AbstractFile> all = new ArrayList<AbstractFile>(); Collection<AbstractFile> all = new ArrayList<>();
try { try {
for (Content child : parent.getChildren()) { for (Content child : parent.getChildren()) {

View File

@ -1,84 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-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.ingest;
import java.util.List;
import javax.swing.JPanel;
import org.sleuthkit.datamodel.Content;
/**
* Instances of this class provide the following services:
* 1. A way to save and load the ingest process configuration settings for a
* given ingest process context.
* 2. A UI component for configuring ingest process settings.
* 3. A way to specify input content and start the ingest process for a
* given ingest process context.
*/
// @@@ This interface needs to be re-designed. An interface for allowing the
// authors of ingest modules to expose context sensitive module configuration
// settings needs to be provided; there also needs to be a way for users to
// configure the ingest process that uses those modules. These are separate
// concerns; likewise, kicking off an ingest process for particular content in
// a particular context is a separate concern.
public interface IngestConfigurator {
/**
* Specifies the ingest process context for the purpose of choosing, saving,
* and loading ingest process configuration settings; also determines what
* configuration settings will be in effect if the setContent() and start()
* methods are called to start the ingest process for some content specified
* using the setContent() method.
* @return A list, possibly empty, of messages describing errors that
* occurred when loading the configuration settings.
*/
public List<String> setContext(String contextName);
/**
* Provides a UI component for choosing ingest process configuration
* settings for the ingest process context specified using the setContext()
* method.
*/
JPanel getIngestConfigPanel();
/**
* Saves the ingest process configuration settings for the ingest process
* context specified using the setContext() method.
*/
void save();
/**
* Sets the input content for an ingest process prior to calling start() to
* run the process using the process configuration settings for the context
* specified using setContext().
*/
void setContent(List<Content> inputContent);
/**
* Starts (queues) the ingest process for the content specified using the
* setContent() method, using the configuration settings corresponding to
* the ingest process context specified using the setContext() method.
*/
void start();
/**
* Returns true if any ingest process is running, false otherwise.
* Note that the running process may or may not be the process started
* (queued) by an invocation of the start() method.
*/
boolean isIngestRunning();
}

View File

@ -1,188 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.ingest;
//ingester worker for DataSource queue
import java.awt.EventQueue;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.SwingWorker;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.progress.ProgressHandleFactory;
import org.openide.util.Cancellable;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.StopWatch;
import org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent;
import org.sleuthkit.autopsy.ingest.IngestModuleAbstract.IngestModuleException;
import org.sleuthkit.datamodel.Content;
/**
* Worker thread that runs a data source-level ingest module (image, file set virt dir, etc).
* Used to process only a single data-source and single module.
*/
class IngestDataSourceThread extends SwingWorker<Void, Void> {
private final Logger logger = Logger.getLogger(IngestDataSourceThread.class.getName());
private ProgressHandle progress;
private final PipelineContext<IngestModuleDataSource>pipelineContext;
private final Content dataSource;
private final IngestModuleDataSource module;
private IngestDataSourceWorkerController controller;
private final IngestManager manager;
private final IngestModuleInit init;
private boolean inited;
//current method of enqueuing data source ingest modules with locks and internal lock queue
//ensures that we init, run and complete a single data source ingest module at a time
//uses fairness policy to run them in order enqueued
//TODO use a real queue and manager to allow multiple different modules to run in parallel
private static final Lock dataSourceIngestModuleLock = new ReentrantReadWriteLock(true).writeLock();
IngestDataSourceThread(IngestManager manager, PipelineContext<IngestModuleDataSource>pipelineContext, Content dataSource, IngestModuleDataSource module, IngestModuleInit init) {
this.manager = manager;
this.pipelineContext = pipelineContext;
this.dataSource = dataSource;
this.module = module;
this.init = init;
this.inited = false;
}
PipelineContext<IngestModuleDataSource>getContext() {
return pipelineContext;
}
Content getContent() {
return pipelineContext.getDataSourceTask().getContent();
}
IngestModuleDataSource getModule() {
return module;
}
public void init() throws IngestModuleException{
logger.log(Level.INFO, "Initializing module: " + module.getName());
try {
module.init(init);
inited = true;
} catch (IngestModuleException e) {
logger.log(Level.INFO, "Failed initializing module: " + module.getName() + ", will not run.");
//will not run
inited = false;
throw e;
}
}
@Override
protected Void doInBackground() throws Exception {
logger.log(Level.INFO, "Pending module: " + module.getName());
final String displayName = NbBundle.getMessage(this.getClass(), "IngestDataSourceThread.displayName.text",
module.getName(),
dataSource.getId());
progress = ProgressHandleFactory.createHandle(
NbBundle.getMessage(this.getClass(), "IngestDataSourceThread.progress.pending", displayName), new Cancellable() {
@Override
public boolean cancel() {
logger.log(Level.INFO, "DataSource ingest module " + module.getName() + " cancelled by user.");
if (progress != null) {
progress.setDisplayName(
NbBundle.getMessage(this.getClass(), "IngestDataSourceThread.progress.cancelling", displayName));
}
return IngestDataSourceThread.this.cancel(true);
}
});
progress.start();
progress.switchToIndeterminate();
dataSourceIngestModuleLock.lock();
try {
if (this.isCancelled()) {
logger.log(Level.INFO, "Cancelled while pending, module: " + module.getName());
return Void.TYPE.newInstance();
}
logger.log(Level.INFO, "Starting module: " + module.getName());
logger.log(Level.INFO, PlatformUtil.getAllMemUsageInfo());
progress.setDisplayName(displayName);
if (inited == false) {
logger.log(Level.INFO, "Module wasn't initialized, will not run: " + module.getName());
return Void.TYPE.newInstance();
}
logger.log(Level.INFO, "Starting processing of module: " + module.getName());
controller = new IngestDataSourceWorkerController(this, progress);
if (isCancelled()) {
logger.log(Level.INFO, "Terminating DataSource ingest module " + module.getName() + " due to cancellation.");
return Void.TYPE.newInstance();
}
final StopWatch timer = new StopWatch();
timer.start();
try {
module.process(pipelineContext, dataSource, controller);
} catch (Exception e) {
logger.log(Level.WARNING, "Exception in module: " + module.getName() + " DataSource: " + dataSource.getName(), e);
} finally {
timer.stop();
logger.log(Level.INFO, "Done processing of module: " + module.getName()
+ " took " + timer.getElapsedTimeSecs() + " secs. to process()");
//cleanup queues (worker and DataSource/module)
manager.removeDataSourceIngestWorker(this);
if (!this.isCancelled()) {
logger.log(Level.INFO, "Module " + module.getName() + " completed");
try {
module.complete();
} catch (Exception e) {
logger.log(Level.INFO, "Error completing the module " + module.getName(), e);
}
IngestManager.fireModuleEvent(IngestModuleEvent.COMPLETED.toString(), module.getName());
} else {
logger.log(Level.INFO, "Module " + module.getName() + " stopped");
try {
module.stop();
} catch (Exception e) {
logger.log(Level.INFO, "Error stopping the module" + module.getName(), e);
}
IngestManager.fireModuleEvent(IngestModuleEvent.STOPPED.toString(), module.getName());
}
}
return Void.TYPE.newInstance();
} finally {
//release the lock so next module can run
dataSourceIngestModuleLock.unlock();
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
progress.finish();
}
});
logger.log(Level.INFO, "Done running module: " + module.getName());
logger.log(Level.INFO, PlatformUtil.getAllMemUsageInfo());
}
}
}

View File

@ -1,80 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.ingest;
import org.netbeans.api.progress.ProgressHandle;
/**
* Controller for DataSource level ingest modules
* Used by modules to check task status and to post progress to
*/
public class IngestDataSourceWorkerController {
private IngestDataSourceThread worker;
private ProgressHandle progress;
/**
* Instantiate the controller for the worker
* @param worker underlying DataSource ingest thread
* @param progress the progress handle
*/
IngestDataSourceWorkerController(IngestDataSourceThread worker, ProgressHandle progress) {
this.worker = worker;
this.progress = progress;
}
/**
* Check if the task has been cancelled. This should be polled by the module periodically
* And the module needs to act, i.e. break out of its processing loop and call its stop() to cleanup
*
* @return true if the task has been cancelled, false otherwise
*/
public boolean isCancelled() {
return worker.isCancelled();
}
/**
* Update the progress bar and switch to determinate mode once number of total work units is known
* @param workUnits total number of work units for the DataSource ingest task
*/
public void switchToDeterminate(int workUnits) {
if (progress != null) {
progress.switchToDeterminate(workUnits);
}
}
/**
* Update the progress bar and switch to non determinate mode if number of work units is not known
*/
public void switchToInDeterminate() {
if (progress != null) {
progress.switchToIndeterminate();
}
}
/**
* Update the progress bar with the number of work units performed, if in the determinate mode
* @param workUnits number of work units performed so far by the module
*/
public void progress(int workUnits) {
if (progress != null) {
progress.progress(worker.getContent().getName(), workUnits);
}
}
}

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2013 Basis Technology Corp. * Copyright 2013-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -25,6 +25,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.swing.BoxLayout; import javax.swing.BoxLayout;
import javax.swing.JButton; import javax.swing.JButton;
@ -32,24 +33,24 @@ import javax.swing.JDialog;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
/** /**
* Dialog box that allows ingest modules to be run on an image. * Dialog box that allows ingest modules to be run on a data source. Used
* Used outside of the wizards. * outside of the wizards.
*/ */
public class IngestDialog extends JDialog { public final class IngestDialog extends JDialog {
private static final String TITLE = NbBundle.getMessage(IngestDialog.class, "IngestDialog.title.text"); private static final String TITLE = NbBundle.getMessage(IngestDialog.class, "IngestDialog.title.text");
private static Dimension DIMENSIONS = new Dimension(500, 300); private static Dimension DIMENSIONS = new Dimension(500, 300);
private IngestConfigurator ingestConfigurator; private List<Content> dataSources = new ArrayList<>();
private IngestJobLauncher ingestJobLauncher;
public IngestDialog(JFrame frame, String title, boolean modal) { public IngestDialog(JFrame frame, String title, boolean modal) {
super(frame, title, modal); super(frame, title, modal);
ingestConfigurator = new GeneralIngestConfigurator(); ingestJobLauncher = new IngestJobLauncher(IngestDialog.class.getCanonicalName());
List<String> messages = ingestConfigurator.setContext(IngestDialog.class.getCanonicalName()); List<String> messages = ingestJobLauncher.getIngestJobConfigWarnings();
if (messages.isEmpty() == false) { if (messages.isEmpty() == false) {
StringBuilder warning = new StringBuilder(); StringBuilder warning = new StringBuilder();
for (String message : messages) { for (String message : messages) {
@ -59,7 +60,7 @@ public class IngestDialog extends JDialog {
} }
} }
public IngestDialog(){ public IngestDialog() {
this(new JFrame(TITLE), TITLE, true); this(new JFrame(TITLE), TITLE, true);
} }
@ -78,39 +79,36 @@ public class IngestDialog extends JDialog {
// set the location of the popUp Window on the center of the screen // set the location of the popUp Window on the center of the screen
setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2); setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
add(ingestConfigurator.getIngestConfigPanel(), BorderLayout.PAGE_START); add(ingestJobLauncher.getIngestJobConfigPanel(), BorderLayout.PAGE_START);
JButton startButton = new JButton(NbBundle.getMessage(this.getClass(), "IngestDialog.startButton.title")); JButton startButton = new JButton(NbBundle.getMessage(this.getClass(), "IngestDialog.startButton.title"));
JButton closeButton = new JButton(NbBundle.getMessage(this.getClass(), "IngestDialog.closeButton.title")); JButton closeButton = new JButton(NbBundle.getMessage(this.getClass(), "IngestDialog.closeButton.title"));
startButton.addActionListener(new ActionListener() { startButton.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
ingestConfigurator.save(); ingestJobLauncher.saveIngestJobConfig();
ingestConfigurator.start(); ingestJobLauncher.startIngestJobs(dataSources);
close(); close();
} }
}); });
closeButton.addActionListener(new ActionListener() { closeButton.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
ingestConfigurator.save(); ingestJobLauncher.saveIngestJobConfig();
close(); close();
} }
}); });
this.addWindowListener(new WindowAdapter() { this.addWindowListener(new WindowAdapter() {
@Override @Override
public void windowClosing(WindowEvent e) { public void windowClosing(WindowEvent e) {
ingestConfigurator.save(); ingestJobLauncher.saveIngestJobConfig();
close(); close();
} }
}); });
JPanel buttonPanel = new JPanel(); JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS)); buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10,10), new Dimension(10,10), new Dimension(10,10))); buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10)));
buttonPanel.add(startButton); buttonPanel.add(startButton);
buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10,10), new Dimension(10,10), new Dimension(10,10))); buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10)));
buttonPanel.add(closeButton); buttonPanel.add(closeButton);
add(buttonPanel, BorderLayout.LINE_START); add(buttonPanel, BorderLayout.LINE_START);
@ -119,8 +117,9 @@ public class IngestDialog extends JDialog {
setVisible(true); setVisible(true);
} }
public void setContent(List<Content> inputContent) { public void setDataSources(List<Content> inputContent) {
ingestConfigurator.setContent(inputContent); dataSources.clear();
dataSources.addAll(inputContent);
} }
/** /**

View File

@ -0,0 +1,389 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.ingest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.swing.SwingWorker;
import org.netbeans.api.progress.ProgressHandle;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
/**
* Encapsulates a data source and the ingest module pipelines to be used to
* ingest the data source.
*/
final class IngestJob {
private final long id;
private final Content dataSource;
private final List<IngestModuleTemplate> ingestModuleTemplates;
private final boolean processUnallocatedSpace;
private final HashMap<Long, FileIngestPipeline> fileIngestPipelines = new HashMap<>();
private final HashMap<Long, DataSourceIngestPipeline> dataSourceIngestPipelines = new HashMap<>();
private FileIngestPipeline initialFileIngestPipeline = null;
private DataSourceIngestPipeline initialDataSourceIngestPipeline = null;
private boolean cancelled;
IngestJob(long id, Content dataSource, List<IngestModuleTemplate> ingestModuleTemplates, boolean processUnallocatedSpace) {
this.id = id;
this.dataSource = dataSource;
this.ingestModuleTemplates = ingestModuleTemplates;
this.processUnallocatedSpace = processUnallocatedSpace;
this.cancelled = false;
}
long getId() {
return id;
}
Content getDataSource() {
return dataSource;
}
boolean shouldProcessUnallocatedSpace() {
return processUnallocatedSpace;
}
synchronized void cancel() {
cancelled = true;
}
synchronized boolean isCancelled() {
return cancelled;
}
synchronized List<IngestModuleError> startUpIngestPipelines() {
// Create a per thread instance of each pipeline type right now to make
// (reasonably) sure that the ingest modules can be started.
initialDataSourceIngestPipeline = new DataSourceIngestPipeline(this, ingestModuleTemplates);
initialFileIngestPipeline = new FileIngestPipeline(this, ingestModuleTemplates);
List<IngestModuleError> errors = new ArrayList<>();
errors.addAll(initialDataSourceIngestPipeline.startUp());
errors.addAll(initialFileIngestPipeline.startUp());
return errors;
}
synchronized DataSourceIngestPipeline getDataSourceIngestPipelineForThread(long threadId) {
DataSourceIngestPipeline pipeline;
if (initialDataSourceIngestPipeline != null) {
pipeline = initialDataSourceIngestPipeline;
initialDataSourceIngestPipeline = null;
dataSourceIngestPipelines.put(threadId, pipeline);
} else if (!dataSourceIngestPipelines.containsKey(threadId)) {
pipeline = new DataSourceIngestPipeline(this, ingestModuleTemplates);
pipeline.startUp();
dataSourceIngestPipelines.put(threadId, pipeline);
} else {
pipeline = dataSourceIngestPipelines.get(threadId);
}
return pipeline;
}
synchronized FileIngestPipeline getFileIngestPipelineForThread(long threadId) {
FileIngestPipeline pipeline;
if (initialFileIngestPipeline != null) {
pipeline = initialFileIngestPipeline;
initialFileIngestPipeline = null;
fileIngestPipelines.put(threadId, pipeline);
} else if (!fileIngestPipelines.containsKey(threadId)) {
pipeline = new FileIngestPipeline(this, ingestModuleTemplates);
pipeline.startUp();
fileIngestPipelines.put(threadId, pipeline);
} else {
pipeline = fileIngestPipelines.get(threadId);
}
return pipeline;
}
synchronized List<IngestModuleError> releaseIngestPipelinesForThread(long threadId) {
List<IngestModuleError> errors = new ArrayList<>();
DataSourceIngestPipeline dataSourceIngestPipeline = dataSourceIngestPipelines.get(threadId);
if (dataSourceIngestPipeline != null) {
errors.addAll(dataSourceIngestPipeline.shutDown(cancelled));
}
this.dataSourceIngestPipelines.remove(threadId);
FileIngestPipeline fileIngestPipeline = fileIngestPipelines.get(threadId);
if (fileIngestPipeline != null) {
errors.addAll(fileIngestPipeline.shutDown(cancelled));
}
this.fileIngestPipelines.remove(threadId);
return errors;
}
synchronized boolean areIngestPipelinesShutDown() {
return (dataSourceIngestPipelines.isEmpty() && fileIngestPipelines.isEmpty());
}
/**
* A data source ingest pipeline composed of a sequence of data source ingest
* modules constructed from ingest module templates.
*/
static final class DataSourceIngestPipeline {
private static final Logger logger = Logger.getLogger(DataSourceIngestPipeline.class.getName());
private final IngestJob task;
private final List<IngestModuleTemplate> moduleTemplates;
private List<DataSourceIngestModuleDecorator> modules = new ArrayList<>();
private DataSourceIngestPipeline(IngestJob task, List<IngestModuleTemplate> moduleTemplates) {
this.task = task;
this.moduleTemplates = moduleTemplates;
}
private List<IngestModuleError> startUp() {
List<IngestModuleError> errors = new ArrayList<>();
// Create an ingest module instance from each ingest module template
// that has an ingest module factory capable of making data source
// ingest modules. Map the module class names to the module instance
// to allow the modules to be put in the sequence indicated by the
// ingest pipelines configuration.
Map<String, DataSourceIngestModuleDecorator> modulesByClass = new HashMap<>();
for (IngestModuleTemplate template : moduleTemplates) {
if (template.isDataSourceIngestModuleTemplate()) {
DataSourceIngestModuleDecorator module = new DataSourceIngestModuleDecorator(template.createDataSourceIngestModule(), template.getModuleName());
IngestJobContext context = new IngestJobContext(task);
try {
module.startUp(context);
modulesByClass.put(module.getClassName(), module);
IngestManager.fireModuleEvent(IngestManager.IngestEvent.STARTED.toString(), module.getDisplayName());
} catch (Exception ex) {
errors.add(new IngestModuleError(module.getDisplayName(), ex));
}
}
}
// Establish the module sequence of the core ingest modules
// indicated by the ingest pipeline configuration, adding any
// additional modules found in the global lookup to the end of the
// pipeline in arbitrary order.
List<String> pipelineConfig = IngestPipelinesConfiguration.getInstance().getDataSourceIngestPipelineConfig();
for (String moduleClassName : pipelineConfig) {
if (modulesByClass.containsKey(moduleClassName)) {
modules.add(modulesByClass.remove(moduleClassName));
}
}
for (DataSourceIngestModuleDecorator module : modulesByClass.values()) {
modules.add(module);
}
return errors;
}
List<IngestModuleError> process(SwingWorker worker, ProgressHandle progress) {
List<IngestModuleError> errors = new ArrayList<>();
Content dataSource = this.task.getDataSource();
logger.log(Level.INFO, "Processing data source {0}", dataSource.getName());
for (DataSourceIngestModuleDecorator module : this.modules) {
try {
String displayName = NbBundle.getMessage(this.getClass(), "IngestJob.DataSourceIngestPipeline.displayName.text", module.getDisplayName(), dataSource.getName());
progress.setDisplayName(displayName);
module.process(dataSource, new DataSourceIngestModuleStatusHelper(worker, progress, dataSource));
} catch (Exception ex) {
errors.add(new IngestModuleError(module.getDisplayName(), ex));
}
if (task.isCancelled()) {
break;
}
}
return errors;
}
private List<IngestModuleError> shutDown(boolean ingestJobCancelled) {
List<IngestModuleError> errors = new ArrayList<>();
for (DataSourceIngestModuleDecorator module : this.modules) {
try {
module.shutDown(ingestJobCancelled);
} catch (Exception ex) {
errors.add(new IngestModuleError(module.getDisplayName(), ex));
} finally {
IngestManager.fireModuleEvent(IngestManager.IngestEvent.COMPLETED.toString(), module.getDisplayName());
}
}
return errors;
}
private static class DataSourceIngestModuleDecorator implements DataSourceIngestModule {
private final DataSourceIngestModule module;
private final String displayName;
DataSourceIngestModuleDecorator(DataSourceIngestModule module, String displayName) {
this.module = module;
this.displayName = displayName;
}
String getClassName() {
return module.getClass().getCanonicalName();
}
String getDisplayName() {
return displayName;
}
@Override
public void startUp(IngestJobContext context) throws IngestModuleException {
module.startUp(context);
}
@Override
public IngestModule.ProcessResult process(Content dataSource, DataSourceIngestModuleStatusHelper statusHelper) {
return module.process(dataSource, statusHelper);
}
@Override
public void shutDown(boolean ingestJobWasCancelled) {
module.shutDown(ingestJobWasCancelled);
}
}
}
/**
* A file ingest pipeline composed of a sequence of file ingest modules
* constructed from ingest module templates.
*/
static final class FileIngestPipeline {
private static final Logger logger = Logger.getLogger(FileIngestPipeline.class.getName());
private final IngestJob task;
private final List<IngestModuleTemplate> moduleTemplates;
private List<FileIngestModuleDecorator> modules = new ArrayList<>();
private FileIngestPipeline(IngestJob task, List<IngestModuleTemplate> moduleTemplates) {
this.task = task;
this.moduleTemplates = moduleTemplates;
}
private List<IngestModuleError> startUp() {
List<IngestModuleError> errors = new ArrayList<>();
// Create an ingest module instance from each ingest module template
// that has an ingest module factory capable of making data source
// ingest modules. Map the module class names to the module instance
// to allow the modules to be put in the sequence indicated by the
// ingest pipelines configuration.
Map<String, FileIngestModuleDecorator> modulesByClass = new HashMap<>();
for (IngestModuleTemplate template : moduleTemplates) {
if (template.isFileIngestModuleTemplate()) {
FileIngestModuleDecorator module = new FileIngestModuleDecorator(template.createFileIngestModule(), template.getModuleName());
IngestJobContext context = new IngestJobContext(task);
try {
module.startUp(context);
modulesByClass.put(module.getClassName(), module);
IngestManager.fireModuleEvent(IngestManager.IngestEvent.STARTED.toString(), template.getModuleName());
} catch (Exception ex) {
errors.add(new IngestModuleError(module.getDisplayName(), ex));
}
}
}
// Establish the module sequence of the core ingest modules
// indicated by the ingest pipeline configuration, adding any
// additional modules found in the global lookup to the end of the
// pipeline in arbitrary order.
List<String> pipelineConfig = IngestPipelinesConfiguration.getInstance().getFileIngestPipelineConfig();
for (String moduleClassName : pipelineConfig) {
if (modulesByClass.containsKey(moduleClassName)) {
modules.add(modulesByClass.remove(moduleClassName));
}
}
for (FileIngestModuleDecorator module : modulesByClass.values()) {
modules.add(module);
}
return errors;
}
List<IngestModuleError> process(AbstractFile file) {
List<IngestModuleError> errors = new ArrayList<>();
Content dataSource = this.task.getDataSource();
logger.log(Level.INFO, String.format("Processing {0} from {1}", file.getName(), dataSource.getName()));
for (FileIngestModuleDecorator module : this.modules) {
try {
module.process(file);
} catch (Exception ex) {
errors.add(new IngestModuleError(module.getDisplayName(), ex));
}
if (task.isCancelled()) {
break;
}
}
file.close();
IngestManager.fireFileDone(file.getId());
return errors;
}
private List<IngestModuleError> shutDown(boolean ingestJobCancelled) {
List<IngestModuleError> errors = new ArrayList<>();
for (FileIngestModuleDecorator module : this.modules) {
try {
module.shutDown(ingestJobCancelled);
} catch (Exception ex) {
errors.add(new IngestModuleError(module.getDisplayName(), ex));
} finally {
IngestManager.fireModuleEvent(IngestManager.IngestEvent.COMPLETED.toString(), module.getDisplayName());
}
}
return errors;
}
private static class FileIngestModuleDecorator implements FileIngestModule {
private final FileIngestModule module;
private final String displayName;
FileIngestModuleDecorator(FileIngestModule module, String displayName) {
this.module = module;
this.displayName = displayName;
}
String getClassName() {
return module.getClass().getCanonicalName();
}
String getDisplayName() {
return displayName;
}
@Override
public void startUp(IngestJobContext context) throws IngestModuleException {
module.startUp(context);
}
@Override
public IngestModule.ProcessResult process(AbstractFile file) {
return module.process(file);
}
@Override
public void shutDown(boolean ingestJobWasCancelled) {
module.shutDown(ingestJobWasCancelled);
}
}
}
}

View File

@ -134,7 +134,7 @@
<Component class="javax.swing.JButton" name="advancedButton"> <Component class="javax.swing.JButton" name="advancedButton">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestDialogPanel.advancedButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobConfigurationPanel.advancedButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="enabled" type="boolean" value="false"/> <Property name="enabled" type="boolean" value="false"/>
</Properties> </Properties>
@ -201,10 +201,10 @@
<Component class="javax.swing.JCheckBox" name="processUnallocCheckbox"> <Component class="javax.swing.JCheckBox" name="processUnallocCheckbox">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestDialogPanel.processUnallocCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobConfigurationPanel.processUnallocCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestDialogPanel.processUnallocCheckbox.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobConfigurationPanel.processUnallocCheckbox.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2013 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -23,10 +23,8 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.util.AbstractMap;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
@ -35,62 +33,56 @@ import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn; import javax.swing.table.TableColumn;
import org.sleuthkit.autopsy.corecomponents.AdvancedConfigurationDialog; import org.sleuthkit.autopsy.corecomponents.AdvancedConfigurationDialog;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
/** /**
* main configuration panel for all ingest modules, reusable JPanel component * User interface component to allow a user to set ingest module options and
* enable/disable the modules.
*/ */
class IngestDialogPanel extends javax.swing.JPanel { class IngestJobConfigurationPanel extends javax.swing.JPanel {
private IngestModuleAbstract currentModule; private List<IngestModuleModel> modules = new ArrayList<>();
private ModulesTableModel tableModel; private boolean processUnallocatedSpace = false;
private String context; private IngestModuleModel selectedModule = null;
/** IngestJobConfigurationPanel(List<IngestModuleTemplate> moduleTemplates, boolean processUnallocatedSpace) {
* Creates new form IngestDialogPanel for (IngestModuleTemplate moduleTemplate : moduleTemplates) {
*/ modules.add(new IngestModuleModel(moduleTemplate));
public IngestDialogPanel() { }
tableModel = new ModulesTableModel(); this.processUnallocatedSpace = processUnallocatedSpace;
context = ModuleSettings.DEFAULT_CONTEXT;
initComponents(); initComponents();
customizeComponents(); customizeComponents();
} }
public void setContext(String context) { List<IngestModuleTemplate> getIngestModuleTemplates() {
this.context = context; List<IngestModuleTemplate> moduleTemplates = new ArrayList<>();
for (IngestModuleModel module : modules) {
IngestModuleTemplate moduleTemplate = module.getIngestModuleTemplate();
if (module.hasModuleSettingsPanel()) {
IngestModuleIngestJobSettings settings = module.getModuleSettingsPanel().getSettings();
moduleTemplate.setModuleSettings(settings);
}
moduleTemplates.add(moduleTemplate);
}
return moduleTemplates;
} }
boolean getProcessUnallocSpace() {
public IngestModuleAbstract getCurrentIngestModule() {
return currentModule;
}
public List<IngestModuleAbstract> getModulesToStart() {
return tableModel.getSelectedModules();
}
public List<IngestModuleAbstract> getDisabledModules() {
return tableModel.getUnSelectedModules();
}
public boolean processUnallocSpaceEnabled() {
return processUnallocCheckbox.isSelected(); return processUnallocCheckbox.isSelected();
} }
private void customizeComponents() { private void customizeComponents() {
modulesTable.setModel(tableModel); modulesTable.setModel(new IngestModulesTableModel());
modulesTable.setTableHeader(null); modulesTable.setTableHeader(null);
modulesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); modulesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//custom renderer for tooltips // Set the column widths in the table model and add a custom cell
ModulesTableRenderer renderer = new ModulesTableRenderer(); // renderer that will display module descriptions from the module models
// as tooltips.
//customize column witdhs IngestModulesTableRenderer renderer = new IngestModulesTableRenderer();
final int width = modulesScrollPane.getPreferredSize().width; int width = modulesScrollPane.getPreferredSize().width;
TableColumn column = null; for (int i = 0; i < modulesTable.getColumnCount(); ++i) {
for (int i = 0; i < modulesTable.getColumnCount(); i++) { TableColumn column = modulesTable.getColumnModel().getColumn(i);
column = modulesTable.getColumnModel().getColumn(i); if (0 == i) {
if (i == 0) {
column.setPreferredWidth(((int) (width * 0.15))); column.setPreferredWidth(((int) (width * 0.15)));
} else { } else {
column.setCellRenderer(renderer); column.setCellRenderer(renderer);
@ -98,35 +90,28 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings;
} }
} }
// Add a selection listener to the table model that will display the
// ingest job options panel of the currently selected module model and
// enable or disable the resources configuration panel invocation button.
modulesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { modulesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override @Override
public void valueChanged(ListSelectionEvent e) { public void valueChanged(ListSelectionEvent e) {
ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource(); ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource();
if (!listSelectionModel.isSelectionEmpty()) { if (!listSelectionModel.isSelectionEmpty()) {
int index = listSelectionModel.getMinSelectionIndex(); int index = listSelectionModel.getMinSelectionIndex();
currentModule = tableModel.getModule(index); selectedModule = modules.get(index);
// add the module-specific configuration panel, if there is one
simplePanel.removeAll(); simplePanel.removeAll();
if (currentModule.hasSimpleConfiguration()) { if (null != selectedModule.getModuleSettingsPanel()) {
simplePanel.add(currentModule.getSimpleConfiguration(context)); simplePanel.add(selectedModule.getModuleSettingsPanel());
} }
simplePanel.revalidate(); simplePanel.revalidate();
simplePanel.repaint(); simplePanel.repaint();
advancedButton.setEnabled(currentModule.hasAdvancedConfiguration()); advancedButton.setEnabled(null != selectedModule.getGlobalSettingsPanel());
} else {
currentModule = null;
} }
} }
}); });
}
public void setProcessUnallocSpaceEnabled(final boolean enabled) { processUnallocCheckbox.setSelected(processUnallocatedSpace);
processUnallocCheckbox.setSelected(enabled);
}
public void setEnabledIngestModules(List<IngestModuleAbstract> enabledModules) {
tableModel.setSelectedModules(enabledModules);
} }
/** /**
@ -172,7 +157,7 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings;
jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(160, 160, 160))); jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(160, 160, 160)));
jPanel1.setPreferredSize(new java.awt.Dimension(338, 257)); jPanel1.setPreferredSize(new java.awt.Dimension(338, 257));
advancedButton.setText(org.openide.util.NbBundle.getMessage(IngestDialogPanel.class, "IngestDialogPanel.advancedButton.text")); // NOI18N advancedButton.setText(org.openide.util.NbBundle.getMessage(IngestJobConfigurationPanel.class, "IngestJobConfigurationPanel.advancedButton.text")); // NOI18N
advancedButton.setEnabled(false); advancedButton.setEnabled(false);
advancedButton.addActionListener(new java.awt.event.ActionListener() { advancedButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -210,8 +195,8 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings;
processUnallocPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(160, 160, 160))); processUnallocPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(160, 160, 160)));
processUnallocCheckbox.setText(org.openide.util.NbBundle.getMessage(IngestDialogPanel.class, "IngestDialogPanel.processUnallocCheckbox.text")); // NOI18N processUnallocCheckbox.setText(org.openide.util.NbBundle.getMessage(IngestJobConfigurationPanel.class, "IngestJobConfigurationPanel.processUnallocCheckbox.text")); // NOI18N
processUnallocCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(IngestDialogPanel.class, "IngestDialogPanel.processUnallocCheckbox.toolTipText")); // NOI18N processUnallocCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(IngestJobConfigurationPanel.class, "IngestJobConfigurationPanel.processUnallocCheckbox.toolTipText")); // NOI18N
processUnallocCheckbox.addActionListener(new java.awt.event.ActionListener() { processUnallocCheckbox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
processUnallocCheckboxActionPerformed(evt); processUnallocCheckboxActionPerformed(evt);
@ -264,24 +249,29 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings;
private void advancedButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_advancedButtonActionPerformed private void advancedButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_advancedButtonActionPerformed
final AdvancedConfigurationDialog dialog = new AdvancedConfigurationDialog(); final AdvancedConfigurationDialog dialog = new AdvancedConfigurationDialog();
dialog.addApplyButtonListener(new ActionListener() { dialog.addApplyButtonListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (selectedModule.hasGlobalSettingsPanel()) {
selectedModule.saveResourcesConfig();
}
dialog.close(); dialog.close();
currentModule.saveAdvancedConfiguration();
} }
}); });
dialog.addWindowListener(new WindowAdapter() { dialog.addWindowListener(new WindowAdapter() {
@Override @Override
public void windowClosing(WindowEvent e) { public void windowClosing(WindowEvent e) {
dialog.close(); dialog.close();
} }
}); });
dialog.display(currentModule.getAdvancedConfiguration(context));
dialog.display(selectedModule.getGlobalSettingsPanel());
}//GEN-LAST:event_advancedButtonActionPerformed }//GEN-LAST:event_advancedButtonActionPerformed
private void processUnallocCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_processUnallocCheckboxActionPerformed private void processUnallocCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_processUnallocCheckboxActionPerformed
// nothing to do here processUnallocatedSpace = processUnallocCheckbox.isSelected();
}//GEN-LAST:event_processUnallocCheckboxActionPerformed }//GEN-LAST:event_processUnallocCheckboxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton advancedButton; private javax.swing.JButton advancedButton;
@ -296,20 +286,77 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings;
private javax.swing.ButtonGroup timeGroup; private javax.swing.ButtonGroup timeGroup;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
private class ModulesTableModel extends AbstractTableModel { /**
* A decorator for an ingest module template that adds ingest and global
* options panels with lifetimes equal to that of the ingest configuration
* panel.
*/
static private class IngestModuleModel {
private List<Map.Entry<IngestModuleAbstract, Boolean>>moduleData = new ArrayList<>(); private final IngestModuleTemplate moduleTemplate;
private IngestModuleGlobalSetttingsPanel globalSettingsPanel = null;
private IngestModuleIngestJobSettingsPanel moduleSettingsPanel = null;
public ModulesTableModel() { IngestModuleModel(IngestModuleTemplate moduleTemplate) {
List<IngestModuleAbstract> modules = IngestManager.getDefault().enumerateAllModules(); this.moduleTemplate = moduleTemplate;
for (IngestModuleAbstract ingestModuleAbstract : modules) { if (moduleTemplate.hasModuleSettingsPanel()) {
moduleData.add(new AbstractMap.SimpleEntry<>(ingestModuleAbstract, Boolean.TRUE)); moduleSettingsPanel = moduleTemplate.getModuleSettingsPanel();
}
if (moduleTemplate.hasGlobalSettingsPanel()) {
globalSettingsPanel = moduleTemplate.getGlobalSettingsPanel();
} }
} }
IngestModuleTemplate getIngestModuleTemplate() {
return moduleTemplate;
}
String getName() {
return moduleTemplate.getModuleName();
}
String getDescription() {
return moduleTemplate.getModuleDescription();
}
void setEnabled(boolean enabled) {
moduleTemplate.setEnabled(enabled);
}
boolean isEnabled() {
return moduleTemplate.isEnabled();
}
boolean hasModuleSettingsPanel() {
return moduleTemplate.hasModuleSettingsPanel();
}
IngestModuleIngestJobSettingsPanel getModuleSettingsPanel() {
return moduleSettingsPanel;
}
boolean hasGlobalSettingsPanel() {
return moduleTemplate.hasGlobalSettingsPanel();
}
IngestModuleGlobalSetttingsPanel getGlobalSettingsPanel() {
return globalSettingsPanel;
}
void saveResourcesConfig() {
globalSettingsPanel.saveSettings();
}
}
/**
* Custom table model to display ingest module names and enable/disable
* ingest modules.
*/
private class IngestModulesTableModel extends AbstractTableModel {
@Override @Override
public int getRowCount() { public int getRowCount() {
return moduleData.size(); return modules.size();
} }
@Override @Override
@ -319,11 +366,11 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings;
@Override @Override
public Object getValueAt(int rowIndex, int columnIndex) { public Object getValueAt(int rowIndex, int columnIndex) {
Map.Entry<IngestModuleAbstract, Boolean> entry = moduleData.get(rowIndex); IngestModuleModel module = modules.get(rowIndex);
if (columnIndex == 0) { if (columnIndex == 0) {
return entry.getValue(); return module.isEnabled();
} else { } else {
return entry.getKey().getName(); return module.getName();
} }
} }
@ -335,7 +382,7 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings;
@Override @Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) { public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (columnIndex == 0) { if (columnIndex == 0) {
moduleData.get(rowIndex).setValue((Boolean)aValue); modules.get(rowIndex).setEnabled((boolean) aValue);
} }
} }
@ -343,103 +390,26 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings;
public Class<?> getColumnClass(int c) { public Class<?> getColumnClass(int c) {
return getValueAt(0, c).getClass(); return getValueAt(0, c).getClass();
} }
public List<IngestModuleAbstract> getSelectedModules() {
List<IngestModuleAbstract> selectedModules = new ArrayList<>();
for (Map.Entry<IngestModuleAbstract, Boolean> entry : moduleData) {
if (entry.getValue().booleanValue()) {
selectedModules.add(entry.getKey());
}
}
return selectedModules;
}
public List<IngestModuleAbstract> getUnSelectedModules() {
List<IngestModuleAbstract> unselectedModules = new ArrayList<>();
for (Map.Entry<IngestModuleAbstract, Boolean> entry : moduleData) {
if (!entry.getValue().booleanValue()) {
unselectedModules.add(entry.getKey());
}
}
return unselectedModules;
}
/**
* Sets the given modules as selected in the modules table
* @param selectedModules
*/
public void setSelectedModules(List<IngestModuleAbstract> selectedModules) {
// unselect all modules
for (Map.Entry<IngestModuleAbstract, Boolean> entry : moduleData) {
entry.setValue(Boolean.FALSE);
}
// select only the given modules
for (IngestModuleAbstract selectedModule : selectedModules) {
getEntryForModule(selectedModule).setValue(Boolean.TRUE);
}
// tell everyone about it
fireTableDataChanged();
}
/**
* Sets the given modules as NOT selected in the modules table
* @param selectedModules
*/
public void setUnselectedModules(List<IngestModuleAbstract> unselectedModules) {
// select all modules
for (Map.Entry<IngestModuleAbstract, Boolean> entry : moduleData) {
entry.setValue(Boolean.TRUE);
}
// unselect only the given modules
for (IngestModuleAbstract unselectedModule : unselectedModules) {
getEntryForModule(unselectedModule).setValue(Boolean.FALSE);
}
// tell everyone about it
fireTableDataChanged();
}
public IngestModuleAbstract getModule(int row) {
return moduleData.get(row).getKey();
}
private Map.Entry<IngestModuleAbstract, Boolean> getEntryForModule(IngestModuleAbstract module) {
Map.Entry<IngestModuleAbstract, Boolean> entry = null;
for (Map.Entry<IngestModuleAbstract, Boolean> anEntry : moduleData) {
if (anEntry.getKey().equals(module)) {
entry = anEntry;
break;
}
}
return entry;
}
} }
/** /**
* Custom cell renderer for tool tips with module description * Custom cell renderer to create tool tips displaying ingest module
* descriptions.
*/ */
private class ModulesTableRenderer extends DefaultTableCellRenderer { private class IngestModulesTableRenderer extends DefaultTableCellRenderer {
List<String> tooltips = new ArrayList<>(); List<String> tooltips = new ArrayList<>();
public ModulesTableRenderer() { public IngestModulesTableRenderer() {
List<IngestModuleAbstract> modules = IngestManager.getDefault().enumerateAllModules(); for (IngestModuleModel moduleTemplate : modules) {
for (IngestModuleAbstract ingestModuleAbstract : modules) { tooltips.add(moduleTemplate.getDescription());
tooltips.add(ingestModuleAbstract.getDescription());
} }
} }
@Override @Override
public Component getTableCellRendererComponent( public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (1 == column) {
if (column == 1) {
setToolTipText(tooltips.get(row)); setToolTipText(tooltips.get(row));
} }
return this; return this;

View File

@ -0,0 +1,66 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.ingest;
import java.util.List;
import org.sleuthkit.datamodel.AbstractFile;
/**
* Provides an instance of an ingest module with services specific to the ingest
* job and the ingest pipeline of which the module is a part.
*/
public final class IngestJobContext {
private final IngestJob ingestJob;
IngestJobContext(IngestJob ingestJob) {
this.ingestJob = ingestJob;
}
/**
* Gets the identifier of the ingest job associated with this context.
*
* @return The ingest job identifier.
*/
public long getJobId() {
return this.ingestJob.getId();
}
/**
* Determines whether the ingest job associated with the current context has
* been canceled.
*
* @return True if the job has been canceled, false otherwise.
*/
public boolean isJobCancelled() {
return this.ingestJob.isCancelled();
}
/**
* Adds one or more files to the files to be passed through the file ingest
* pipeline of the ingest job associated with the current context.
*
* @param files The files to be processed by the file ingest pipeline.
*/
public void addFilesToPipeline(List<AbstractFile> files) {
for (AbstractFile file : files) {
IngestManager.getDefault().scheduleFile(ingestJob.getId(), file);
}
}
}

View File

@ -0,0 +1,238 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.ingest;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import javax.swing.JPanel;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.datamodel.Content;
/**
* Provides a mechanism for creating and persisting an ingest job configuration
* for a particular context and for launching ingest jobs that process one or
* more data sources using the ingest job configuration.
*/
public final class IngestJobLauncher {
private static final String ENABLED_INGEST_MODULES_KEY = "Enabled_Ingest_Modules";
private static final String DISABLED_INGEST_MODULES_KEY = "Disabled_Ingest_Modules";
private static final String PARSE_UNALLOC_SPACE_KEY = "Process_Unallocated_Space";
private final String launcherContext;
private final List<String> warnings = new ArrayList<>();
private IngestJobConfigurationPanel ingestConfigPanel;
/**
* Constructs an ingest job launcher that creates and persists an ingest job
* configuration for a particular context and launches ingest jobs that
* process one or more data sources using the ingest job configuration.
*
* @param launcherContext The context identifier.
*/
public IngestJobLauncher(String launcherContext) {
this.launcherContext = launcherContext;
// Get the ingest module factories discovered by the ingest module
// loader.
List<IngestModuleFactory> moduleFactories = IngestModuleFactoryLoader.getInstance().getIngestModuleFactories();
HashSet<String> loadedModuleNames = new HashSet<>();
for (IngestModuleFactory moduleFactory : moduleFactories) {
loadedModuleNames.add(moduleFactory.getModuleDisplayName());
}
// Get the enabled and disabled ingest modules settings for the current
// context. Observe that the default settings make all loaded ingest
// modules enabled.
HashSet<String> enabledModuleNames = getModulesNamesFromSetting(ENABLED_INGEST_MODULES_KEY, makeCommaSeparatedList(loadedModuleNames));
HashSet<String> disabledModuleNames = getModulesNamesFromSetting(DISABLED_INGEST_MODULES_KEY, "");
// Check for missing modules.
List<String> missingModuleNames = new ArrayList<>();
for (String moduleName : enabledModuleNames) {
if (!loadedModuleNames.contains(moduleName)) {
missingModuleNames.add(moduleName);
}
}
for (String moduleName : disabledModuleNames) {
if (!loadedModuleNames.contains(moduleName)) {
missingModuleNames.add(moduleName);
}
}
for (String moduleName : missingModuleNames) {
enabledModuleNames.remove(moduleName);
disabledModuleNames.remove(moduleName);
warnings.add(String.format("Previously loaded %s module could not be found", moduleName));
}
// Create ingest module templates.
List<IngestModuleTemplate> moduleTemplates = new ArrayList<>();
for (IngestModuleFactory moduleFactory : moduleFactories) {
// NOTE: In the future, this code will be modified to get the
// module settings for the current context, if available, from
// storage; for now always use the defaults.
IngestModuleTemplate moduleTemplate = new IngestModuleTemplate(moduleFactory, moduleFactory.getDefaultModuleSettings());
String moduleName = moduleTemplate.getModuleName();
if (enabledModuleNames.contains(moduleName)) {
moduleTemplate.setEnabled(true);
} else if (disabledModuleNames.contains(moduleName)) {
moduleTemplate.setEnabled(true);
} else {
// The module factory was loaded, but the module name does not
// appear in the enabled/disabled module settings. Treat the
// module as a new module and enable it by default.
moduleTemplate.setEnabled(true);
enabledModuleNames.add(moduleName);
}
moduleTemplates.add(moduleTemplate);
}
// Update the enabled/disabled ingest module settings to reflect any
// missing modules or newly discovered modules.
ModuleSettings.setConfigSetting(launcherContext, ENABLED_INGEST_MODULES_KEY, makeCommaSeparatedList(enabledModuleNames));
ModuleSettings.setConfigSetting(launcherContext, DISABLED_INGEST_MODULES_KEY, makeCommaSeparatedList(disabledModuleNames));
// Get the process unallocated space flag setting. If the setting does
// not exist yet, default it to false.
if (ModuleSettings.settingExists(launcherContext, PARSE_UNALLOC_SPACE_KEY) == false) {
ModuleSettings.setConfigSetting(launcherContext, PARSE_UNALLOC_SPACE_KEY, "false");
}
boolean processUnallocatedSpace = Boolean.parseBoolean(ModuleSettings.getConfigSetting(launcherContext, PARSE_UNALLOC_SPACE_KEY));
// Make the configuration panel for the context.
ingestConfigPanel = new IngestJobConfigurationPanel(moduleTemplates, processUnallocatedSpace);
}
private HashSet<String> getModulesNamesFromSetting(String key, String defaultSetting) {
// Get the ingest modules setting from the user's config file.
// If there is no such setting yet, create the default setting.
if (ModuleSettings.settingExists(launcherContext, key) == false) {
ModuleSettings.setConfigSetting(launcherContext, key, defaultSetting);
}
HashSet<String> moduleNames = new HashSet<>();
String modulesSetting = ModuleSettings.getConfigSetting(launcherContext, key);
if (!modulesSetting.isEmpty()) {
String[] settingNames = modulesSetting.split(", ");
for (String name : settingNames) {
// Map some old core module names to the current core module names.
switch (name) {
case "Thunderbird Parser":
case "MBox Parser":
moduleNames.add("Email Parser");
break;
case "File Extension Mismatch Detection":
moduleNames.add("Extension Mismatch Detector");
break;
case "EWF Verify":
case "E01 Verify":
moduleNames.add("E01 Verifier");
break;
default:
moduleNames.add(name);
}
}
}
return moduleNames;
}
/**
* Gets any warnings generated when the persisted ingest job configuration
* for the specified context is retrieved and loaded.
*
* @return A collection of warning messages.
*/
public List<String> getIngestJobConfigWarnings() {
return warnings;
}
/**
* Gets the user interface panel the launcher uses to obtain the user's
* ingest job configuration for the specified context.
*
* @return A JPanel with components that can be used to create an ingest job
* configuration.
*/
public JPanel getIngestJobConfigPanel() {
return ingestConfigPanel;
}
/**
* Persists the ingest job configuration for the specified context.
*/
public void saveIngestJobConfig() {
List<IngestModuleTemplate> moduleTemplates = ingestConfigPanel.getIngestModuleTemplates();
// Save the enabled/disabled ingest module settings for the current context.
HashSet<String> enabledModuleNames = new HashSet<>();
HashSet<String> disabledModuleNames = new HashSet<>();
for (IngestModuleTemplate moduleTemplate : moduleTemplates) {
String moduleName = moduleTemplate.getModuleName();
if (moduleTemplate.isEnabled()) {
enabledModuleNames.add(moduleName);
} else {
disabledModuleNames.add(moduleName);
}
}
ModuleSettings.setConfigSetting(launcherContext, ENABLED_INGEST_MODULES_KEY, makeCommaSeparatedList(enabledModuleNames));
ModuleSettings.setConfigSetting(launcherContext, DISABLED_INGEST_MODULES_KEY, makeCommaSeparatedList(disabledModuleNames));
// Save the process unallocated space setting for the current context.
String processUnalloc = Boolean.toString(ingestConfigPanel.getProcessUnallocSpace());
ModuleSettings.setConfigSetting(launcherContext, PARSE_UNALLOC_SPACE_KEY, processUnalloc);
// NOTE: In the future, this code will be modified to persist the ingest
// options for each ingest module for the current launch context.
}
private static String makeCommaSeparatedList(HashSet<String> input) {
if (input == null || input.isEmpty()) {
return "";
}
ArrayList<String> list = new ArrayList<>();
list.addAll(input);
StringBuilder csvList = new StringBuilder();
for (int i = 0; i < list.size() - 1; ++i) {
csvList.append(list.get(i)).append(", ");
}
csvList.append(list.get(list.size() - 1));
return csvList.toString();
}
/**
* Launches ingest jobs for one or more data sources using the ingest job
* configuration for the selected context.
*
* @param dataSources The data sources to ingest.
*/
public void startIngestJobs(List<Content> dataSources) {
// Filter out the disabled ingest module templates.
List<IngestModuleTemplate> enabledModuleTemplates = new ArrayList<>();
List<IngestModuleTemplate> moduleTemplates = ingestConfigPanel.getIngestModuleTemplates();
for (IngestModuleTemplate moduleTemplate : moduleTemplates) {
if (moduleTemplate.isEnabled()) {
enabledModuleTemplates.add(moduleTemplate);
}
}
if ((!enabledModuleTemplates.isEmpty()) && (dataSources != null) && (!dataSources.isEmpty())) {
IngestManager.getDefault().scheduleDataSourceTasks(dataSources, enabledModuleTemplates, ingestConfigPanel.getProcessUnallocSpace());
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.ingest;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
@ -41,7 +40,7 @@ public class IngestMessage {
private long ID; private long ID;
private MessageType messageType; private MessageType messageType;
private IngestModuleAbstract source; private String source;
private String subject; private String subject;
private String detailsHtml; private String detailsHtml;
private String uniqueKey; private String uniqueKey;
@ -53,7 +52,7 @@ public class IngestMessage {
/** /**
* Private constructor used by factory methods * Private constructor used by factory methods
*/ */
private IngestMessage(long ID, MessageType messageType, IngestModuleAbstract source, String subject, String detailsHtml, String uniqueKey) { private IngestMessage(long ID, MessageType messageType, String source, String subject, String detailsHtml, String uniqueKey) {
this.ID = ID; this.ID = ID;
this.source = source; this.source = source;
this.messageType = messageType; this.messageType = messageType;
@ -70,7 +69,7 @@ public class IngestMessage {
return ID; return ID;
} }
public IngestModuleAbstract getSource() { public String getSource() {
return source; return source;
} }
@ -105,7 +104,7 @@ public class IngestMessage {
sb.append(NbBundle.getMessage(this.getClass(), "IngestMessage.toString.type.text", messageType.name())); sb.append(NbBundle.getMessage(this.getClass(), "IngestMessage.toString.type.text", messageType.name()));
if (source != null) //can be null for manager messages if (source != null) //can be null for manager messages
{ {
sb.append(NbBundle.getMessage(this.getClass(), "IngestMessage.toString.source.text", source.getName())); sb.append(source);
} }
sb.append( sb.append(
NbBundle.getMessage(this.getClass(), "IngestMessage.toString.date.text", dateFormat.format(datePosted))); NbBundle.getMessage(this.getClass(), "IngestMessage.toString.date.text", dateFormat.format(datePosted)));
@ -176,7 +175,7 @@ public class IngestMessage {
* @param detailsHtml html formatted detailed message (without leading and closing &lt;html&gt; tags), for instance, a human-readable representation of the data. Or null. * @param detailsHtml html formatted detailed message (without leading and closing &lt;html&gt; tags), for instance, a human-readable representation of the data. Or null.
* @return * @return
*/ */
public static IngestMessage createMessage(long ID, MessageType messageType, IngestModuleAbstract source, String subject, String detailsHtml) { public static IngestMessage createMessage(long ID, MessageType messageType, String source, String subject, String detailsHtml) {
if (messageType == null || source == null || subject == null) { if (messageType == null || source == null || subject == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
NbBundle.getMessage(IngestMessage.class, "IngestMessage.exception.typeSrcSubjNotNull.msg")); NbBundle.getMessage(IngestMessage.class, "IngestMessage.exception.typeSrcSubjNotNull.msg"));
@ -192,7 +191,7 @@ public class IngestMessage {
* @param subject message subject to be displayed * @param subject message subject to be displayed
* @return * @return
*/ */
public static IngestMessage createMessage(long ID, MessageType messageType, IngestModuleAbstract source, String subject) { public static IngestMessage createMessage(long ID, MessageType messageType, String source, String subject) {
return createMessage(ID, messageType, source, subject, null); return createMessage(ID, messageType, source, subject, null);
} }
@ -205,7 +204,7 @@ public class IngestMessage {
* @param detailsHtml html formatted detailed message (without leading and closing &lt;html&gt; tags), for instance, a human-readable representation of the data. Or null * @param detailsHtml html formatted detailed message (without leading and closing &lt;html&gt; tags), for instance, a human-readable representation of the data. Or null
* @return * @return
*/ */
public static IngestMessage createErrorMessage(long ID, IngestModuleAbstract source, String subject, String detailsHtml) { public static IngestMessage createErrorMessage(long ID, String source, String subject, String detailsHtml) {
if (source == null || subject == null) { if (source == null || subject == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
NbBundle.getMessage(IngestMessage.class, "IngestMessage.exception.srcSubjNotNull.msg")); NbBundle.getMessage(IngestMessage.class, "IngestMessage.exception.srcSubjNotNull.msg"));
@ -221,7 +220,7 @@ public class IngestMessage {
* @param detailsHtml html formatted detailed message (without leading and closing &lt;html&gt; tags), for instance, a human-readable representation of the data. Or null * @param detailsHtml html formatted detailed message (without leading and closing &lt;html&gt; tags), for instance, a human-readable representation of the data. Or null
* @return * @return
*/ */
public static IngestMessage createWarningMessage(long ID, IngestModuleAbstract source, String subject, String detailsHtml) { public static IngestMessage createWarningMessage(long ID, String source, String subject, String detailsHtml) {
if (source == null || subject == null) { if (source == null || subject == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
NbBundle.getMessage(IngestMessage.class, "IngestMessage.exception.srcSubjNotNull.msg")); NbBundle.getMessage(IngestMessage.class, "IngestMessage.exception.srcSubjNotNull.msg"));
@ -239,7 +238,7 @@ public class IngestMessage {
* @param data blackboard artifact associated with the message, the same as fired in ModuleDataEvent by the module * @param data blackboard artifact associated with the message, the same as fired in ModuleDataEvent by the module
* @return * @return
*/ */
public static IngestMessage createDataMessage(long ID, IngestModuleAbstract source, String subject, String detailsHtml, String uniqueKey, BlackboardArtifact data) { public static IngestMessage createDataMessage(long ID, String source, String subject, String detailsHtml, String uniqueKey, BlackboardArtifact data) {
if (source == null || subject == null || detailsHtml == null || data == null) { if (source == null || subject == null || detailsHtml == null || data == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
NbBundle.getMessage(IngestMessage.class, "IngestMessage.exception.srcSubjDetailsDataNotNull.msg")); NbBundle.getMessage(IngestMessage.class, "IngestMessage.exception.srcSubjDetailsDataNotNull.msg"));

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -35,10 +35,8 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Level;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.JTable; import javax.swing.JTable;
@ -54,6 +52,7 @@ import javax.swing.table.TableCellRenderer;
import org.sleuthkit.autopsy.ingest.IngestMessage.*; import org.sleuthkit.autopsy.ingest.IngestMessage.*;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import java.util.logging.Level;
/** /**
* Notification window showing messages from modules to user * Notification window showing messages from modules to user
@ -260,7 +259,6 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
//this should be done at the end to make it easy to initialize before events are handled //this should be done at the end to make it easy to initialize before events are handled
tableModel.addTableModelListener(this); tableModel.addTableModelListener(this);
} }
@Override @Override
@ -285,16 +283,13 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
} }
} }
public synchronized void addMessage(IngestMessage m) { public synchronized void addMessage(IngestMessage m) {
//final int origMsgUnreadUnique = tableModel.getNumberUnreadGroups();
tableModel.addMessage(m); tableModel.addMessage(m);
//update total individual messages count //update total individual messages count
++totalMessages; ++totalMessages;
final int newMsgUnreadUnique = tableModel.getNumberUnreadGroups(); final int newMsgUnreadUnique = tableModel.getNumberUnreadGroups();
try { try {
messagePcs.firePropertyChange(TOTAL_NUM_MESSAGES_CHANGED, 0, newMsgUnreadUnique); messagePcs.firePropertyChange(TOTAL_NUM_MESSAGES_CHANGED, 0, newMsgUnreadUnique);
} }
@ -310,10 +305,6 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
this.totalMessagesNameVal.setText(Long.toString(totalMessages)); this.totalMessagesNameVal.setText(Long.toString(totalMessages));
final int totalMessagesUnique = tableModel.getNumberGroups(); final int totalMessagesUnique = tableModel.getNumberGroups();
this.totalUniqueMessagesNameVal.setText(Integer.toString(totalMessagesUnique)); this.totalUniqueMessagesNameVal.setText(Integer.toString(totalMessagesUnique));
//this.unreadLabelVal.setText(Integer.toString(newMsgUnreadUnique));
//autoscroll
//messageTable.scrollRectToVisible(messageTable.getCellRect(messageTable.getRowCount() - 1, messageTable.getColumnCount(), true));
} }
public synchronized void clearMessages() { public synchronized void clearMessages() {
@ -342,7 +333,6 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
private synchronized void setVisited(int rowNumber) { private synchronized void setVisited(int rowNumber) {
final int origMsgGroups = tableModel.getNumberUnreadGroups(); final int origMsgGroups = tableModel.getNumberUnreadGroups();
tableModel.setVisited(rowNumber); tableModel.setVisited(rowNumber);
//renderer.setSelected(rowNumber);
lastRowSelected = rowNumber; lastRowSelected = rowNumber;
try { try {
@ -381,9 +371,9 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
NbBundle.getMessage(this.getClass(), "IngestMessagePanel.MsgTableMod.colNames.new"), NbBundle.getMessage(this.getClass(), "IngestMessagePanel.MsgTableMod.colNames.new"),
NbBundle.getMessage(this.getClass(), "IngestMessagePanel.MsgTableMod.colNames.subject"), NbBundle.getMessage(this.getClass(), "IngestMessagePanel.MsgTableMod.colNames.subject"),
NbBundle.getMessage(this.getClass(), "IngestMessagePanel.MsgTableMod.colNames.timestamp")}; NbBundle.getMessage(this.getClass(), "IngestMessagePanel.MsgTableMod.colNames.timestamp")};
private List<TableEntry> messageData = new ArrayList<TableEntry>(); private List<TableEntry> messageData = new ArrayList<>();
//for keeping track of messages to group, per module, by uniqness //for keeping track of messages to group, per module, by uniqness
private Map<IngestModuleAbstract, Map<String, List<IngestMessageGroup>>> groupings = new HashMap<IngestModuleAbstract, Map<String, List<IngestMessageGroup>>>(); private Map<String, Map<String, List<IngestMessageGroup>>> groupings = new HashMap<>();
private boolean chronoSort = true; //chronological sort default private boolean chronoSort = true; //chronological sort default
private static final int MESSAGE_GROUP_THRESH = 3; //group messages after 3 messages per module with same uniqness private static final int MESSAGE_GROUP_THRESH = 3; //group messages after 3 messages per module with same uniqness
private Logger logger = Logger.getLogger(MessageTableModel.class.getName()); private Logger logger = Logger.getLogger(MessageTableModel.class.getName());
@ -393,19 +383,12 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
} }
private void init() { private void init() {
final IngestManager manager = IngestManager.getDefault(); List<IngestModuleFactory> moduleFactories = IngestModuleFactoryLoader.getInstance().getIngestModuleFactories();
//initialize groupings map with modules for (IngestModuleFactory factory : moduleFactories) {
for (IngestModuleAbstract module : manager.enumerateAbstractFileModules()) { groupings.put(factory.getModuleDisplayName(), new HashMap<String, List<IngestMessageGroup>>());
groupings.put(module, new HashMap<String, List<IngestMessageGroup>>());
}
for (IngestModuleAbstract module : manager.enumerateDataSourceModules()) {
groupings.put(module, new HashMap<String, List<IngestMessageGroup>>());
} }
} }
@Override @Override
public int getColumnCount() { public int getColumnCount() {
return columnNames.length; return columnNames.length;
@ -486,8 +469,7 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
switch (columnIndex) { switch (columnIndex) {
case 0: case 0:
Object module = entry.messageGroup.getSource(); ret = entry.messageGroup.getSource();
ret = module == null ? "" : entry.messageGroup.getSource().getName();
break; break;
case 1: case 1:
ret = entry.messageGroup.getCount(); ret = entry.messageGroup.getCount();
@ -502,7 +484,7 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
ret = entry.messageGroup.getDatePosted(); ret = entry.messageGroup.getDatePosted();
break; break;
default: default:
logger.log(Level.SEVERE, "Invalid table column index: " + columnIndex); logger.log(Level.SEVERE, "Invalid table column index: {0}", columnIndex);
break; break;
} }
return ret; return ret;
@ -534,17 +516,17 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
synchronized public void addMessage(IngestMessage m) { synchronized public void addMessage(IngestMessage m) {
//check how many messages per module with the same uniqness //check how many messages per module with the same uniqness
//and add to existing group or create a new group //and add to existing group or create a new group
IngestModuleAbstract module = m.getSource(); String moduleName = m.getSource();
IngestMessageGroup messageGroup = null; IngestMessageGroup messageGroup = null;
if (module != null && m.getMessageType() == IngestMessage.MessageType.DATA) { if (moduleName != null && m.getMessageType() == IngestMessage.MessageType.DATA) {
//not a manager message, a data message, then group //not a manager message, a data message, then group
final Map<String, List<IngestMessageGroup>> groups = groupings.get(module); final Map<String, List<IngestMessageGroup>> groups = groupings.get(moduleName);
//groups for this uniqueness //groups for this uniqueness
final String uniqueness = m.getUniqueKey(); final String uniqueness = m.getUniqueKey();
List<IngestMessageGroup> uniqGroups = groups.get(uniqueness); List<IngestMessageGroup> uniqGroups = groups.get(uniqueness);
if (uniqGroups == null) { if (uniqGroups == null) {
//first one with this uniqueness //first one with this uniqueness
uniqGroups = new ArrayList<IngestMessageGroup>(); uniqGroups = new ArrayList<>();
messageGroup = new IngestMessageGroup(m); messageGroup = new IngestMessageGroup(m);
uniqGroups.add(messageGroup); uniqGroups.add(messageGroup);
groups.put(uniqueness, uniqGroups); groups.put(uniqueness, uniqGroups);
@ -565,7 +547,7 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
uniqGroups.add(messageGroup); uniqGroups.add(messageGroup);
//remove all rows with this uniquness, new merged row will be added to the bottom //remove all rows with this uniquness, new merged row will be added to the bottom
int toRemove = 0; int toRemove;
while ((toRemove = getTableEntryIndex(uniqueness)) != -1) { while ((toRemove = getTableEntryIndex(uniqueness)) != -1) {
messageData.remove(toRemove); messageData.remove(toRemove);
//remove the row, will be added to the bottom //remove the row, will be added to the bottom
@ -715,7 +697,7 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
private List<IngestMessage> messages; private List<IngestMessage> messages;
IngestMessageGroup(IngestMessage message) { IngestMessageGroup(IngestMessage message) {
messages = new ArrayList<IngestMessage>(); messages = new ArrayList<>();
messages.add(message); messages.add(message);
} }
@ -768,7 +750,6 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
} else { } else {
return LOW_PRI_COLOR; return LOW_PRI_COLOR;
} }
} }
/** /**
@ -798,7 +779,7 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
/* /*
* return source module, should be the same for all msgs * return source module, should be the same for all msgs
*/ */
IngestModuleAbstract getSource() { String getSource() {
return messages.get(0).getSource(); return messages.get(0).getSource();
} }
@ -889,7 +870,6 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
return cell; return cell;
} }
} }
/** /**
@ -965,7 +945,6 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
return cell; return cell;
} }
} }
/** /**
@ -973,8 +952,6 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
*/ */
private class MessageVisitedSelection implements ListSelectionListener { private class MessageVisitedSelection implements ListSelectionListener {
private Logger logger = Logger.getLogger(MessageVisitedSelection.class.getName());
@Override @Override
public void valueChanged(ListSelectionEvent e) { public void valueChanged(ListSelectionEvent e) {
ListSelectionModel selModel = (ListSelectionModel) e.getSource(); ListSelectionModel selModel = (ListSelectionModel) e.getSource();
@ -1003,7 +980,6 @@ class IngestMessagePanel extends JPanel implements TableModelListener {
} }
messageTable.setCursor(null); messageTable.setCursor(null);
} }
} }
} }
} }

View File

@ -0,0 +1,47 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.ingest;
/**
* The interface that must be implemented by all ingest modules.
*/
public interface IngestModule {
public enum ProcessResult {
OK,
ERROR
};
public class IngestModuleException extends Exception {
public IngestModuleException(String message) {
super(message);
}
}
// RJCTODO: Write header comment, make sure to mention "one module instance per thread"
/**
* Invoked by the ingest frame
* @param context
* @throws org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException
*/
void startUp(IngestJobContext context) throws IngestModuleException;
// RJCTODO: Write header comment, make sure to mention "one module instance per thread"
void shutDown(boolean ingestJobWasCancelled);
}

View File

@ -1,191 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2012 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.ingest;
/**
* Base interface for ingest modules
*/
public abstract class IngestModuleAbstract {
private String args;
/**
* Possible module types for the implementing classes
*/
public enum ModuleType {
/**
* DataSource type module
*/
DataSource,
/**
* AbstractFile type module
*/
AbstractFile
};
public class IngestModuleException extends Exception {
public IngestModuleException(String msg) {
super(msg);
}
}
/**
* Invoked every time an ingest session is started by the framework.
* A module should support multiple invocations of init() throughout the application life-cycle.
* In this method, the module should reinitialize its internal objects and resources and get them ready
* for a brand new ingest processing.
*
* Here are some things you may do in this method if you'll need them later.
* - Get a handle to the ingest services using org.sleuthkit.autopsy.ingest.IngestServices.getDefault().
* - Get the current case using org.sleuthkit.autopsy.ingest.IngestServices.getCurrentSleuthkitCaseDb().
*
* NEVER initialize IngestServices handle in the member declaration, because it might result
* in multiple instances of the singleton -- different class loaders are used in different modules.
* @param initContext context used to initialize some modules
*
* @throws IngestModuleException if a critical error occurs in initializing the module.
*/
abstract public void init(IngestModuleInit initContext) throws IngestModuleException;
/**
* Invoked when an ingest session completes.
* The module should perform any resource (files, handles, caches)
* cleanup in this method and submit final results and post a final ingest inbox message.
*/
abstract public void complete();
/**
* Invoked on a module when an ingest session is interrupted by the user or system.
* The method implementation should be similar to complete() in that the
* module should perform any cleanup work.
* If there is pending data to be processed or pending results to be reported by the module
* then the results should be rejected and ignored and the method should return as early as possible.
* It should ensure it is in a defined state so that ingest can be rerun later.
*/
abstract public void stop();
/**
* Returns unique name of the module. Should not have collisions.
* @return unique module name
*/
abstract public String getName();
/**
* Gets the module version
* @return module version string
*/
abstract public String getVersion();
/**
* Gets user-friendly description of the module
* @return module description
*/
abstract public String getDescription();
/**
* Returns type of the module (data source-level or file-level)
* @return module type
*/
abstract public ModuleType getType();
/**
* A module can manage and use additional threads to perform some work in the background.
* This method provides insight to the manager if the module has truly completed its work or not.
*
*
* @return true if any background threads/workers managed by this module are still running or are pending to be run,
* false if all work has been done, or if background threads are not used/managed by this module
*/
abstract public boolean hasBackgroundJobsRunning();
/**
* Used to determine if a module has implemented a simple (run-time)
* configuration panel that is displayed by the ingest manager.
*
* @return true if this module has a simple (run-time) configuration
*/
public boolean hasSimpleConfiguration() {
return false;
}
/**
* Used to determine if a module has implemented an advanced (general)
* configuration that can be used for more in-depth module configuration.
*
* @return true if this module has an advanced configuration
*/
public boolean hasAdvancedConfiguration() {
return false;
}
/**
* Called by the ingest manager if the simple (run-time) configuration
* panel should save its current state so that the settings can be used
* during the ingest.
*/
public void saveSimpleConfiguration() {}
/**
* If module implements advanced configuration panel
* it should read its current state and make it persistent / save it in this method
* so that the new configuration will be in effect during the ingest.
*/
public void saveAdvancedConfiguration() {}
/**
* 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 panel for more
* in-depth interfaces. 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(String context) {
return null;
}
/**
* 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(String context) {
return null;
}
}

View File

@ -1,52 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.ingest;
import org.sleuthkit.datamodel.AbstractFile;
/**
* Ingest module interface that will be called for every file in the data source Content
*/
public abstract class IngestModuleAbstractFile extends IngestModuleAbstract {
/**
* Return value resulting from processing AbstractFile
* If ERROR, can be used subsequent module
* in the pipeline as a hint to stop processing the file
*/
public enum ProcessResult {
OK, ///< Indicates that processing was successful (including if the file was largely ignored by the module)
ERROR, ///< Indicates that an error was encountered while processing the file, hint for later modules that depend on this module to skip processing the file due to error condition (such as file could not be read)
UNKNOWN ///< Indicates that a return value for the module is not known. This should not be returned directly by modules, but is used to indicate the module has not set its return value (e.g. it never ran)
};
@Override
public ModuleType getType() {
return ModuleType.AbstractFile;
}
/**
* Entry point to process file / directory by the module.
*
* @param pipelineContext the context in which the ingest runs (with its own settings, modules, etc)
* @param abstractFile file to process
* @return ProcessResult result of the processing that can be used in the pipeline as a hint whether to further process this file
*/
abstract public ProcessResult process(PipelineContext<IngestModuleAbstractFile>pipelineContext, AbstractFile abstractFile);
}

View File

@ -0,0 +1,34 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.ingest;
/**
* An adapter that provides a default implementation of the IngestModule
* interface.
*/
public abstract class IngestModuleAdapter implements IngestModule {
@Override
public void startUp(IngestJobContext context) throws IngestModuleException {
}
@Override
public void shutDown(boolean ingestJobCancelled) {
}
}

View File

@ -1,52 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.ingest;
import org.sleuthkit.datamodel.Content;
/**
* Ingest module that acts on entire image or set of logical files.
* These modules are for analysis tasks that do not operate on all files in the disk image or set of logical files.
* A new instance of this module will be created for each data source that is added.
* Therefore, data source-level modules can assume that the process() method will be called at most once after init() is called.
*/
public abstract class IngestModuleDataSource extends IngestModuleAbstract {
@Override
public ModuleType getType() {
return ModuleType.DataSource;
}
/**
* Called with the data source Content object to analyze.
*
* Modules typically use FileManager to get specific files to analyze.
*
* Results should be posted to the blackboard.
* The module should also send messages to the ingest inbox with interesting events (data, errors, warnings, infos).
* The module notifies data viewers by firing events using IngestManagerProxy.fireModuleDataEvent
*
* The module will have its own progress bar while it is running and it should update it with the IngestDataSourceWorkerController object.
*
* @param pipelineContext Context in which the ingest pipeline is running (Settings, modules, etc)
* @param dataSource data source to process (such as Image, VirtualDirectory for logical files etc, etc)
* @param controller Used to update progress bar and to check if the task has been canceled.
*/
abstract public void process(PipelineContext<IngestModuleDataSource>pipelineContext, Content dataSource, IngestDataSourceWorkerController controller);
}

View File

@ -0,0 +1,41 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.ingest;
/**
* Encapsulates an exception thrown by an ingest module during an operation such
* as startup or shut down with an exception object for the error that occurred.
*/
final class IngestModuleError {
private final String moduleDisplayName;
private final Exception error;
IngestModuleError(String moduleDisplayName, Exception error) {
this.moduleDisplayName = moduleDisplayName;
this.error = error;
}
String getModuleDisplayName() {
return this.moduleDisplayName;
}
Exception getModuleError() {
return this.error;
}
}

View File

@ -0,0 +1,216 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.ingest;
/**
* An interface that must be implemented by all providers of ingest modules. An
* ingest module factory will be used to create instances of a type of data
* source ingest module, a type of file ingest module, or both.
* <P>
* IMPORTANT: The factory should be stateless to support context-sensitive use
* of the factory. The ingest framework is responsible for managing context
* switching and the persistence of resource configurations and per ingest job
* options.
* <p>
* IMPORTANT: The ingest framework will create one or more instances of each
* module type for each ingest job it performs. The ingest framework may use
* multiple threads to complete an ingest job, but it is guaranteed that there
* will be no more than one module instance per thread. However, if these
* instances must share resources, the modules are responsible for synchronizing
* access to the shared resources and doing reference counting as required to
* release those resources correctly.
* <p>
* IMPORTANT: To be discovered at runtime by the ingest framework,
* IngestModuleFactory implementations must be marked with the following
* NetBeans Service provider annotation:
*
* @ServiceProvider(service=IngestModuleFactory.class)
*/
public interface IngestModuleFactory {
/**
* Gets the display name that identifies the family of ingest modules the
* factory creates.
*
* @return The module family display name.
*/
String getModuleDisplayName();
/**
* Gets a brief, user-friendly description of the family of ingest modules
* the factory creates.
*
* @return The module family description.
*/
String getModuleDescription();
/**
* Gets the version number of the family of ingest modules the factory
* creates.
*
* @return The module family version number.
*/
String getModuleVersionNumber();
/**
* Queries the factory to determine if it provides user interface panels to
* configure resources to be used by instances of the family of ingest
* modules the factory creates. For example, the core hash lookup ingest
* module factory provides resource configuration panels to import and
* create hash databases. The hash databases are then enabled or disabled
* per ingest job using ingest job options panels. If the module family does
* not have a resources configuration, the factory should extend
* IngestModuleFactoryAdapter to get an implementation of this method that
* returns false.
*
* @return True if the factory provides resource configuration panels.
*/
boolean hasGlobalSettingsPanel();
/**
* Gets a user interface panel that can be used to configure resources for
* instances of the family of ingest modules the factory creates. For
* example, the core hash lookup ingest module factory provides a resource
* configuration panel to import and create hash databases. The imported
* hash databases are then enabled or disabled per ingest job using ingest
* options panels. If the module family does not have a resources
* configuration, the factory should extend IngestModuleFactoryAdapter to
* get an implementation of this method that throws an
* UnsupportedOperationException.
* <p>
* IMPORTANT: The ingest framework assumes that ingest module factories are
* stateless to support context-sensitive use of the factory, with the
* ingest framework managing context switching and the persistence of
* resource configurations and per ingest job options. A factory should not
* retain references to the resources configuration panels it creates.
*
* @param resourcesConfig A resources configuration with which to initialize
* the panel.
* @return A user interface panel for configuring ingest module resources.
*/
IngestModuleGlobalSetttingsPanel getGlobalSettingsPanel();
/**
* Gets the default per ingest job options for instances of the family of
* ingest modules the factory creates. For example, the core hash lookup
* ingest modules family has a resources configuration consisting of hash
* databases, all of which are enabled by default for an ingest job. If the
* module family does not have per ingest job options, the factory should
* extend IngestModuleFactoryAdapter to get an implementation of this method
* that returns an instance of the NoIngestJobOptions class.
*
* @return The ingest options.
*/
IngestModuleIngestJobSettings getDefaultModuleSettings();
/**
* Queries the factory to determine if it provides user interface panels to
* set per ingest job options for instances of the family of ingest modules
* the factory creates. For example, the core hash lookup ingest module
* factory provides ingest options panels to enable or disable hash
* databases per ingest job. If the module family does not have per ingest
* job options, the factory should extend IngestModuleFactoryAdapter to get
* an implementation of this method that returns false.
*
* @return True if the factory provides ingest job options panels.
*/
boolean hasModuleSettingsPanel();
/**
* Gets a user interface panel that can be used to set per ingest job
* options for instances of the family of ingest modules the factory
* creates. For example, the core hash lookup ingest module factory provides
* ingest options panels to enable or disable hash databases per ingest job.
* If the module family does not have ingest job options, the factory should
* extend IngestModuleFactoryAdapter to get an implementation of this method
* that throws an UnsupportedOperationException.
* <p>
* IMPORTANT: The ingest framework assumes that ingest module factories are
* stateless to support context-sensitive use of the factory. The ingest
* framework is responsible for managing context switching and the
* persistence of resource configurations and per ingest job options. A
* factory should not retain references to the ingest job options panels it
* creates.
*
* @param resourcesConfig
* @param ingestOptions Per ingest job options to initialize the panel.
* @return A user interface panel.
*/
IngestModuleIngestJobSettingsPanel getModuleSettingsPanel(IngestModuleIngestJobSettings settings);
/**
* Queries the factory to determine if it is capable of creating file ingest
* modules.
*
* @return True if the factory can create file ingest modules.
*/
boolean isDataSourceIngestModuleFactory();
/**
* Creates a data source ingest module instance.
* <p>
* IMPORTANT: The factory should be stateless to support context-sensitive
* use of the factory. The ingest framework is responsible for managing
* context switching and the persistence of resource configurations and per
* ingest job options. A factory should not retain references to the data
* source ingest module instances it creates.
* <p>
* IMPORTANT: The ingest framework will create one or more data source
* ingest module instances for each ingest job it performs. The ingest
* framework may use multiple threads to complete an ingest job, but it is
* guaranteed that there will be no more than one module instance per
* thread. However, if these instances must share resources, the modules are
* responsible for synchronizing access to the shared resources and doing
* reference counting as required to release those resources correctly.
*
* @param ingestOptions The ingest options for the module instance.
* @return A data source ingest module instance.
*/
DataSourceIngestModule createDataSourceIngestModule(IngestModuleIngestJobSettings settings);
/**
* Queries the factory to determine if it is capable of creating file ingest
* module instances.
*
* @return True if the factory can create file ingest module instances.
*/
boolean isFileIngestModuleFactory();
/**
* Creates a file ingest module instance.
* <p>
* IMPORTANT: The factory should be stateless to support context-sensitive
* use of the factory. The ingest framework is responsible for managing
* context switching and the persistence of resource configurations and per
* ingest job options. A factory should not retain references to the file
* ingest module instances it creates.
* <p>
* IMPORTANT: The ingest framework will create one or more file ingest
* module instances for each ingest job it performs. The ingest framework
* may use multiple threads to complete an ingest job, but it is guaranteed
* that there will be no more than one module instance per thread. However,
* if these instances must share resources, the modules are responsible for
* synchronizing access to the shared resources and doing reference counting
* as required to release those resources correctly.
*
* @param ingestOptions The ingest options for the module instance.
* @return A file ingest module instance.
*/
FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings);
}

View File

@ -0,0 +1,80 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.ingest;
/**
* An adapter that provides no-op implementations of various IngestModuleFactory
* methods.
*/
public abstract class IngestModuleFactoryAdapter implements IngestModuleFactory {
@Override
public abstract String getModuleDisplayName();
@Override
public abstract String getModuleDescription();
@Override
public abstract String getModuleVersionNumber();
@Override
public boolean hasGlobalSettingsPanel() {
return false;
}
@Override
public IngestModuleGlobalSetttingsPanel getGlobalSettingsPanel() {
throw new UnsupportedOperationException();
}
@Override
public IngestModuleIngestJobSettings getDefaultModuleSettings() {
return new NoIngestModuleSettings();
}
@Override
public boolean hasModuleSettingsPanel() {
return false;
}
@Override
public IngestModuleIngestJobSettingsPanel getModuleSettingsPanel(IngestModuleIngestJobSettings ingestOptions) {
throw new UnsupportedOperationException();
}
@Override
public boolean isDataSourceIngestModuleFactory() {
return false;
}
@Override
public DataSourceIngestModule createDataSourceIngestModule(IngestModuleIngestJobSettings ingestOptions) {
throw new UnsupportedOperationException();
}
@Override
public boolean isFileIngestModuleFactory() {
return false;
}
@Override
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings ingestOptions) {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,62 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.ingest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.Lookup;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Looks up loaded ingest module factories using the NetBean global lookup.
*/
final class IngestModuleFactoryLoader {
private static final Logger logger = Logger.getLogger(IngestModuleFactoryLoader.class.getName());
private static IngestModuleFactoryLoader instance;
private IngestModuleFactoryLoader() {
}
synchronized static IngestModuleFactoryLoader getInstance() {
if (instance == null) {
instance = new IngestModuleFactoryLoader();
}
return instance;
}
synchronized List<IngestModuleFactory> getIngestModuleFactories() {
List<IngestModuleFactory> moduleFactories = new ArrayList<>();
HashSet<String> moduleDisplayNames = new HashSet<>();
Collection<? extends IngestModuleFactory> factories = Lookup.getDefault().lookupAll(IngestModuleFactory.class);
for (IngestModuleFactory factory : factories) {
logger.log(Level.INFO, "Found ingest module factory: name = {0}, version = {1}", new Object[]{factory.getModuleDisplayName(), factory.getModuleVersionNumber()});
if (!moduleDisplayNames.contains(factory.getModuleDisplayName())) {
moduleFactories.add(factory);
moduleDisplayNames.add(factory.getModuleDisplayName());
} else {
logger.log(Level.SEVERE, "Found duplicate ingest module display name, discarding ingest module factory (name = {0}", new Object[]{factory.getModuleDisplayName(), factory.getModuleVersionNumber()});
}
}
return new ArrayList<>(moduleFactories);
}
}

View File

@ -0,0 +1,29 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.ingest;
import javax.swing.JPanel;
/**
* Base class for ingest module resources configuration panels.
*/
public abstract class IngestModuleGlobalSetttingsPanel extends JPanel {
public abstract void saveSettings();
}

View File

@ -0,0 +1,29 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.ingest;
import java.io.Serializable;
/**
* Interface for per ingest job settings for ingest modules. The settings are
* serializable to support persistence of settings for different contexts and
* between invocations of the application.
*/
public interface IngestModuleIngestJobSettings extends Serializable {
}

View File

@ -0,0 +1,35 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.ingest;
import javax.swing.JPanel;
/**
* Abstract base class for panels that allow users to specify per ingest job
* settings for ingest modules.
*/
public abstract class IngestModuleIngestJobSettingsPanel extends JPanel {
/**
* Gets the ingest job settings for an ingest module.
*
* @return The ingest settings.
*/
public abstract IngestModuleIngestJobSettings getSettings();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,91 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.ingest;
/**
* Combines an ingest module factory with ingest module settings and an enabled
* flag to create a template for creating fully configured ingest modules.
*/
final class IngestModuleTemplate {
private final IngestModuleFactory moduleFactory;
private IngestModuleIngestJobSettings settings = null;
private boolean enabled = true;
IngestModuleTemplate(IngestModuleFactory moduleFactory, IngestModuleIngestJobSettings settings) {
this.moduleFactory = moduleFactory;
this.settings = settings;
}
String getModuleName() {
return moduleFactory.getModuleDisplayName();
}
String getModuleDescription() {
return moduleFactory.getModuleDescription();
}
IngestModuleIngestJobSettings getModuleSettings() {
return settings;
}
void setModuleSettings(IngestModuleIngestJobSettings settings) {
this.settings = settings;
}
boolean hasModuleSettingsPanel() {
return moduleFactory.hasModuleSettingsPanel();
}
IngestModuleIngestJobSettingsPanel getModuleSettingsPanel() {
return moduleFactory.getModuleSettingsPanel(settings);
}
boolean hasGlobalSettingsPanel() {
return moduleFactory.hasGlobalSettingsPanel();
}
IngestModuleGlobalSetttingsPanel getGlobalSettingsPanel() {
return moduleFactory.getGlobalSettingsPanel();
}
boolean isDataSourceIngestModuleTemplate() {
return moduleFactory.isDataSourceIngestModuleFactory();
}
DataSourceIngestModule createDataSourceIngestModule() {
return moduleFactory.createDataSourceIngestModule(settings);
}
boolean isFileIngestModuleTemplate() {
return moduleFactory.isFileIngestModuleFactory();
}
FileIngestModule createFileIngestModule() {
return moduleFactory.createFileIngestModule(settings);
}
void setEnabled(boolean enabled) {
this.enabled = enabled;
}
boolean isEnabled() {
return enabled;
}
}

View File

@ -38,14 +38,14 @@ import org.sleuthkit.autopsy.coreutils.PlatformUtil;
/** /**
* Monitor health of the system and stop ingest if necessary * Monitor health of the system and stop ingest if necessary
*/ */
public class IngestMonitor { public final class IngestMonitor {
public static final int DISK_FREE_SPACE_UNKNOWN = -1;
private static final int INITIAL_INTERVAL_MS = 60000; //1 min. private static final int INITIAL_INTERVAL_MS = 60000; //1 min.
private final Logger logger = Logger.getLogger(IngestMonitor.class.getName()); private final Logger logger = Logger.getLogger(IngestMonitor.class.getName());
private Timer timer; private Timer timer;
private static final java.util.logging.Logger MONITOR_LOGGER = java.util.logging.Logger.getLogger("monitor"); private static final java.util.logging.Logger MONITOR_LOGGER = java.util.logging.Logger.getLogger("monitor");
private MonitorAction monitor; private MonitorAction monitor;
public static final int DISK_FREE_SPACE_UNKNOWN = -1;
IngestMonitor() { IngestMonitor() {
@ -166,7 +166,7 @@ import org.sleuthkit.autopsy.coreutils.PlatformUtil;
MONITOR_LOGGER.log(Level.SEVERE, "Stopping ingest due to low disk space on disk " + diskPath); MONITOR_LOGGER.log(Level.SEVERE, "Stopping ingest due to low disk space on disk " + diskPath);
logger.log(Level.SEVERE, "Stopping ingest due to low disk space on disk " + diskPath); logger.log(Level.SEVERE, "Stopping ingest due to low disk space on disk " + diskPath);
manager.stopAll(); manager.stopAll();
manager.postMessage(IngestMessage.createManagerErrorMessage( IngestServices.getDefault().postMessage(IngestMessage.createManagerErrorMessage(
NbBundle.getMessage(this.getClass(), "IngestMonitor.mgrErrMsg.lowDiskSpace.title", diskPath), NbBundle.getMessage(this.getClass(), "IngestMonitor.mgrErrMsg.lowDiskSpace.title", diskPath),
NbBundle.getMessage(this.getClass(), "IngestMonitor.mgrErrMsg.lowDiskSpace.msg", diskPath))); NbBundle.getMessage(this.getClass(), "IngestMonitor.mgrErrMsg.lowDiskSpace.msg", diskPath)));
} }

View File

@ -0,0 +1,137 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012-2014 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.ingest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.XMLUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* Provides data source and file ingest pipeline configurations as ordered lists
* of ingest module class names. The order of the module class names indicates
* the desired sequence of ingest module instances in an ingest modules
* pipeline.
*/
final class IngestPipelinesConfiguration {
private static final Logger logger = Logger.getLogger(IngestPipelinesConfiguration.class.getName());
private final static String PIPELINES_CONFIG_FILE = "pipeline_config.xml";
private final static String PIPELINES_CONFIG_FILE_XSD = "PipelineConfigSchema.xsd";
private static final String XML_PIPELINE_ELEM = "PIPELINE";
private static final String XML_PIPELINE_TYPE_ATTR = "type";
private final static String DATA_SOURCE_INGEST_PIPELINE_TYPE = "ImageAnalysis";
private final static String FILE_INGEST_PIPELINE_TYPE = "FileAnalysis";
private static final String XML_MODULE_ELEM = "MODULE";
private static final String XML_MODULE_CLASS_NAME_ATTR = "location";
private static IngestPipelinesConfiguration instance;
private final List<String> dataSourceIngestPipelineConfig = new ArrayList<>();
private final List<String> fileIngestPipelineConfig = new ArrayList<>();
private IngestPipelinesConfiguration() {
readPipelinesConfigurationFile();
}
synchronized static IngestPipelinesConfiguration getInstance() {
if (instance == null) {
Logger.getLogger(IngestPipelinesConfiguration.class.getName()).log(Level.INFO, "Creating ingest module loader instance");
instance = new IngestPipelinesConfiguration();
}
return instance;
}
List<String> getDataSourceIngestPipelineConfig() {
return new ArrayList<>(dataSourceIngestPipelineConfig);
}
List<String> getFileIngestPipelineConfig() {
return new ArrayList<>(fileIngestPipelineConfig);
}
private void readPipelinesConfigurationFile() {
try {
PlatformUtil.extractResourceToUserConfigDir(IngestPipelinesConfiguration.class, PIPELINES_CONFIG_FILE);
} catch (IOException ex) {
logger.log(Level.SEVERE, "Error copying default pipeline configuration to user dir", ex);
return;
}
String configFilePath = PlatformUtil.getUserConfigDirectory() + File.separator + PIPELINES_CONFIG_FILE;
Document doc = XMLUtil.loadDoc(IngestPipelinesConfiguration.class, configFilePath, PIPELINES_CONFIG_FILE_XSD);
if (doc == null) {
return;
}
Element rootElement = doc.getDocumentElement();
if (rootElement == null) {
logger.log(Level.SEVERE, "Invalid pipelines config file");
return;
}
NodeList pipelineElements = rootElement.getElementsByTagName(XML_PIPELINE_ELEM);
int numPipelines = pipelineElements.getLength();
if (numPipelines < 1 || numPipelines > 2) {
logger.log(Level.SEVERE, "Invalid pipelines config file");
return;
}
List<String> pipelineConfig = null;
for (int pipelineNum = 0; pipelineNum < numPipelines; ++pipelineNum) {
Element pipelineElement = (Element) pipelineElements.item(pipelineNum);
String pipelineTypeAttr = pipelineElement.getAttribute(XML_PIPELINE_TYPE_ATTR);
if (pipelineTypeAttr != null) {
switch (pipelineTypeAttr) {
case DATA_SOURCE_INGEST_PIPELINE_TYPE:
pipelineConfig = dataSourceIngestPipelineConfig;
break;
case FILE_INGEST_PIPELINE_TYPE:
pipelineConfig = fileIngestPipelineConfig;
break;
default:
logger.log(Level.SEVERE, "Invalid pipelines config file");
return;
}
}
// Create an ordered list of class names. The sequence of class
// names defines the sequence of modules in the pipeline.
if (pipelineConfig != null) {
NodeList modulesElems = pipelineElement.getElementsByTagName(XML_MODULE_ELEM);
int numModules = modulesElems.getLength();
if (numModules == 0) {
break;
}
for (int moduleNum = 0; moduleNum < numModules; ++moduleNum) {
Element moduleElement = (Element) modulesElems.item(moduleNum);
final String moduleClassName = moduleElement.getAttribute(XML_MODULE_CLASS_NAME_ATTR);
if (moduleClassName != null) {
pipelineConfig.add(moduleClassName);
}
}
}
}
}
}

View File

@ -31,9 +31,8 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.ingest.IngestScheduler.FileScheduler.FileTask;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor; import org.sleuthkit.datamodel.ContentVisitor;
@ -51,16 +50,16 @@ import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
import org.sleuthkit.datamodel.TskData.TSK_FS_META_TYPE_ENUM; import org.sleuthkit.datamodel.TskData.TSK_FS_META_TYPE_ENUM;
/** /**
* Schedules data source (images, file-sets, etc) and files with their associated modules for ingest, and * Schedules data source (images, file-sets, etc) and files with their
* manage queues of the scheduled tasks. * associated modules for ingest, and manage queues of the scheduled tasks.
* *
* Currently a singleton object only (as there is one pipeline at a time) * Currently a singleton object only (as there is one pipeline at a time)
* *
* Contains internal schedulers for content objects into data source and and file ingest * Contains internal schedulers for content objects into data source and and
* pipelines. * file ingest pipelines.
* *
*/ */
class IngestScheduler { final class IngestScheduler {
private static IngestScheduler instance; private static IngestScheduler instance;
private static final Logger logger = Logger.getLogger(IngestScheduler.class.getName()); private static final Logger logger = Logger.getLogger(IngestScheduler.class.getName());
private final DataSourceScheduler dataSourceScheduler = new DataSourceScheduler(); private final DataSourceScheduler dataSourceScheduler = new DataSourceScheduler();
@ -102,28 +101,27 @@ class IngestScheduler {
* *
*/ */
static class FileScheduler implements Iterator<FileScheduler.FileTask> { static class FileScheduler implements Iterator<FileScheduler.FileTask> {
//root folders enqueued //root folders enqueued
private TreeSet<FileTask> rootProcessTasks; private TreeSet<FileTask> rootDirectoryTasks;
//stack of current dirs to be processed recursively //stack of current dirs to be processed recursively
private List<FileTask> curDirProcessTasks; private List<FileTask> directoryTasks;
//list of files being processed in the currently processed directory //list of files being processed in the currently processed directory
private LinkedList<FileTask> curFileProcessTasks; //need to add to start and end quickly private LinkedList<FileTask> fileTasks; //need to add to start and end quickly
//estimated total files to be enqueued for currently scheduled content objects //estimated total files to be enqueued for currently scheduled content objects
private int filesEnqueuedEst; private int filesEnqueuedEst = 0;
private int filesDequeued; private int filesDequeued = 0;
private final static int FAT_NTFS_FLAGS = private final static int FAT_NTFS_FLAGS = TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_FAT12.getValue()
TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_FAT12.getValue()
| TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_FAT16.getValue() | TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_FAT16.getValue()
| TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_FAT32.getValue() | TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_FAT32.getValue()
| TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_NTFS.getValue(); | TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_NTFS.getValue();
private FileScheduler() { private FileScheduler() {
rootProcessTasks = new TreeSet<>(new RootTaskComparator()); rootDirectoryTasks = new TreeSet<>(new RootTaskComparator());
curDirProcessTasks = new ArrayList<>(); directoryTasks = new ArrayList<>();
curFileProcessTasks = new LinkedList<>(); fileTasks = new LinkedList<>();
resetCounters(); resetCounters();
} }
@ -135,31 +133,93 @@ class IngestScheduler {
@Override @Override
public synchronized String toString() { public synchronized String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(NbBundle.getMessage(this.getClass(), "IngestScheduler.FileSched.toString.rootDirs.text", sb.append("\nRootDirs(sorted), size: ").append(rootDirectoryTasks.size());
rootProcessTasks.size())); for (FileTask task : rootDirectoryTasks) {
for (FileTask task : rootProcessTasks) {
sb.append(task.toString()).append(" "); sb.append(task.toString()).append(" ");
} }
sb.append(NbBundle.getMessage(this.getClass(), "IngestScheduler.FileSched.toString.curDirs.text", sb.append("\nCurDirs(stack), size: ").append(directoryTasks.size());
curDirProcessTasks.size())); for (FileTask task : directoryTasks) {
for (FileTask task : curDirProcessTasks) {
sb.append(task.toString()).append(" "); sb.append(task.toString()).append(" ");
} }
sb.append(NbBundle.getMessage(this.getClass(), "IngestScheduler.FileSched.toString.curFiles.text", sb.append("\nCurFiles, size: ").append(fileTasks.size());
curFileProcessTasks.size())); for (FileTask task : fileTasks) {
for (FileTask task : curFileProcessTasks) {
sb.append(task.toString()).append(" "); sb.append(task.toString()).append(" ");
} }
return sb.toString(); return sb.toString();
} }
synchronized void scheduleIngestOfFiles(IngestJob dataSourceTask) {
Content dataSource = dataSourceTask.getDataSource();
Collection<AbstractFile> rootObjects = dataSource.accept(new GetRootDirVisitor());
List<AbstractFile> firstLevelFiles = new ArrayList<>();
if (rootObjects.isEmpty() && dataSource instanceof AbstractFile) {
// The data source is file.
firstLevelFiles.add((AbstractFile)dataSource);
}
else {
for (AbstractFile root : rootObjects) {
List<Content> children;
try {
children = root.getChildren();
if (children.isEmpty()) {
//add the root itself, could be unalloc file, child of volume or image
firstLevelFiles.add(root);
}
else {
//root for fs root dir, schedule children dirs/files
for (Content child : children) {
if (child instanceof AbstractFile) {
firstLevelFiles.add((AbstractFile) child);
}
}
}
}
catch (TskCoreException ex) {
logger.log(Level.WARNING, "Could not get children of root to enqueue: " + root.getId() + ": " + root.getName(), ex);
}
}
}
for (AbstractFile firstLevelFile : firstLevelFiles) {
FileTask fileTask = new FileTask(firstLevelFile, dataSourceTask);
if (shouldEnqueueTask(fileTask)) {
rootDirectoryTasks.add(fileTask);
}
}
// Update approx count of files to process in queues
filesEnqueuedEst = queryNumFilesinEnqueuedContents();
// Reshuffle/update the dir and file level queues if needed
updateQueues();
}
/**
* Schedule a file to the file ingest, with associated modules. This
* will add the file to beginning of the file queue. The method is
* intended for rescheduling a file that is a derivative of another
* content object that has already ingested and produced this file. As a
* result, the derivative file will be scheduled with the same priority
* as the parent origin file.
*
* @param file file to be scheduled
* @param originalContext original content schedule context that was used
* to schedule the parent origin content, with the modules, settings, etc.
*/
synchronized void scheduleFile(IngestJob ingestJob, AbstractFile file) {
FileTask fileTask = new FileTask(file, ingestJob);
if (shouldEnqueueTask(fileTask)) {
fileTasks.addFirst(fileTask);
fileTasks.add(fileTask);
++filesEnqueuedEst;
}
}
float getPercentageDone() { float getPercentageDone() {
if (filesEnqueuedEst == 0) { if (filesEnqueuedEst == 0) {
return 0; return 0;
} }
return ((100.f) * filesDequeued) / filesEnqueuedEst; return ((100.f) * filesDequeued) / filesEnqueuedEst;
} }
/** /**
@ -204,229 +264,11 @@ class IngestScheduler {
return filesDequeued; return filesDequeued;
} }
/**
* Task for a specific file to process. More specific than the
* higher-level DataSourceTask.
*/
static class FileTask {
private final AbstractFile file;
private final DataSourceTask dataSourceTask;
public FileTask(AbstractFile file, DataSourceTask dataSourceTask) {
this.file = file;
this.dataSourceTask = dataSourceTask;
}
public DataSourceTask getDataSourceTask() {
return dataSourceTask;
}
public AbstractFile getFile() {
return file;
}
@Override
public String toString() {
try {
return NbBundle.getMessage(this.getClass(), "IngestScheduler.fileTask.toString.long", file.getId(),
file.getUniquePath()); // + ", dataSourceTask=" + dataSourceTask + '}';
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Cound not get unique path of file in queue, ", ex);
}
return NbBundle.getMessage(this.getClass(), "IngestScheduler.fileTask.toString.short", file.getId(),
file.getName());
}
/**
* two process tasks are equal when the file/dir and modules are the
* same this enables are not to queue up the same file/dir, modules
* tuples into the root dir set
*
* @param obj
* @return
*/
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final FileTask other = (FileTask) obj;
if (this.file != other.file && (this.file == null || !this.file.equals(other.file))) {
return false;
}
DataSourceTask<IngestModuleAbstractFile> thisTask = this.getDataSourceTask();
DataSourceTask<IngestModuleAbstractFile> otherTask = other.getDataSourceTask();
if (thisTask != otherTask
&& (thisTask == null || !thisTask.equals(otherTask))) {
return false;
}
return true;
}
/**
* Create 1 or more ProcessTasks for each root dir in the Content from
* the context supplied
*
* @param context the original ingest context
* @return
*/
private static List<FileTask> createFromScheduledTask(DataSourceTask<IngestModuleAbstractFile> scheduledTask) {
final Content scheduledContent = scheduledTask.getContent();
Collection<AbstractFile> rootObjects = scheduledContent.accept(new GetRootDirVisitor());
List<AbstractFile> firstLevelFiles = new ArrayList<>();
if (rootObjects.isEmpty() && scheduledContent instanceof AbstractFile) {
//add the root, which is a leaf itself
firstLevelFiles.add((AbstractFile) scheduledContent);
} else {
for (AbstractFile root : rootObjects) {
//TODO the type-specific AbstractFile getChildren() method
List<Content> children;
try {
children = root.getChildren();
if (children.isEmpty()) {
//add the root itself, could be unalloc file, child of volume or image
firstLevelFiles.add(root);
} else {
//root for fs root dir, schedule children dirs/files
for (Content child : children) {
if (child instanceof AbstractFile) {
firstLevelFiles.add((AbstractFile) child);
}
}
}
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Could not get children of root to enqueue: "
+ root.getId() + ": " + root.getName(), ex);
}
}
}
List<FileTask> processTasks = new ArrayList<>();
for (AbstractFile firstLevelFile : firstLevelFiles) {
FileTask newTask = new FileTask(firstLevelFile, scheduledTask);
if (shouldEnqueueTask(newTask)) {
processTasks.add(newTask);
}
}
return processTasks;
}
}
/**
* Remove duplicated tasks from previous ingest enqueue currently it
* removes all previous tasks scheduled in queues for this Content
*
* @param task tasks similar to this one should be removed
*/
private void removeDupTasks(DataSourceTask task) {
final Content inputContent = task.getContent();
//remove from root queue
List<FileTask> toRemove = new ArrayList<>();
for (FileTask pt : rootProcessTasks) {
if (pt.getDataSourceTask().getContent().equals(inputContent)) {
toRemove.add(pt);
}
}
rootProcessTasks.removeAll(toRemove);
//remove from dir stack
toRemove = new ArrayList<>();
for (FileTask pt : curDirProcessTasks) {
if (pt.getDataSourceTask().getContent().equals(inputContent)) {
toRemove.add(pt);
}
}
curDirProcessTasks.removeAll(toRemove);
//remove from file queue
toRemove = new ArrayList<>();
for (FileTask pt : curFileProcessTasks) {
if (pt.getDataSourceTask().getContent().equals(inputContent)) {
toRemove.add(pt);
}
}
curFileProcessTasks.removeAll(toRemove);
}
/**
* Schedule a file to the file ingest, with associated modules. This
* will add the file to beginning of the file queue. The method is
* intended for rescheduling a file that is a derivative of another
* content object that has already ingested and produced this file. As a
* result, the derivative file will be scheduled with the same priority
* as the parent origin file.
*
* @param file file to be scheduled
* @param originalContext original content schedule context that was used
* to schedule the parent origin content, with the modules, settings, etc.
*/
synchronized void schedule(AbstractFile file, PipelineContext<IngestModuleAbstractFile> originalContext) {
DataSourceTask<IngestModuleAbstractFile> originalTask = originalContext.getDataSourceTask();
//skip if task contains no modules
if (originalTask.getModules().isEmpty()) {
return;
}
FileTask fileTask = new FileTask(file, originalContext.getDataSourceTask());
if (shouldEnqueueTask(fileTask)) {
this.curFileProcessTasks.addFirst(fileTask);
++filesEnqueuedEst;
}
}
/**
* Schedule new Content object for a file ingest with associated
* modules.
*
* @param context context to schedule, with scheduled task containing content to process and modules
*/
synchronized void schedule(DataSourceTask<IngestModuleAbstractFile> task) {
//skip if task contains no modules
if (task.getModules().isEmpty()) {
return;
}
final Content contentToSchedule = task.getContent();
if (getSourceContent().contains(contentToSchedule)) {
//reset counters if the same content enqueued twice
//Note, not very accurate, because we may have processed some files from
//another content
this.filesDequeued = 0;
}
//remove duplicate scheduled tasks still in queues for this content if enqueued previously
removeDupTasks(task);
List<FileTask> rootTasks = FileTask.createFromScheduledTask(task);
//adds and resorts the tasks
this.rootProcessTasks.addAll(rootTasks);
//update approx count of files to process in queues
this.filesEnqueuedEst = this.queryNumFilesinEnqueuedContents();
//reshuffle/update the dir and file level queues if needed
updateQueues();
}
@Override @Override
public synchronized boolean hasNext() { public synchronized boolean hasNext() {
if (curFileProcessTasks.isEmpty()) { if (fileTasks.isEmpty()) {
resetCounters(); filesEnqueuedEst = 0;
filesDequeued = 0;
return false; return false;
} }
return true; return true;
@ -435,12 +277,11 @@ class IngestScheduler {
@Override @Override
public synchronized FileTask next() { public synchronized FileTask next() {
if (!hasNext()) { if (!hasNext()) {
throw new IllegalStateException( throw new IllegalStateException("No next ProcessTask, check hasNext() first!");
NbBundle.getMessage(this.getClass(), "IngestScheduler.FileTask.next.exception.msg"));
} }
//dequeue the last in the list //dequeue the last in the list
final FileTask task = curFileProcessTasks.pollLast(); final FileTask task = fileTasks.pollLast();
filesDequeued++; filesDequeued++;
updateQueues(); updateQueues();
@ -457,28 +298,28 @@ class IngestScheduler {
// that do not get enqueued // that do not get enqueued
while (true) { while (true) {
// There are files in the queue, we're done // There are files in the queue, we're done
if (this.curFileProcessTasks.isEmpty() == false) { if (this.fileTasks.isEmpty() == false) {
return; return;
} }
// fill in the directory queue if it is empty. // fill in the directory queue if it is empty.
if (this.curDirProcessTasks.isEmpty()) { if (this.directoryTasks.isEmpty()) {
// bail out if root is also empty -- we are done // bail out if root is also empty -- we are done
if (rootProcessTasks.isEmpty()) { if (rootDirectoryTasks.isEmpty()) {
return; return;
} }
FileTask rootTask = this.rootProcessTasks.pollFirst(); FileTask rootTask = this.rootDirectoryTasks.pollFirst();
curDirProcessTasks.add(rootTask); directoryTasks.add(rootTask);
} }
//pop and push AbstractFile directory children if any //pop and push AbstractFile directory children if any
//add the popped and its leaf children onto cur file list //add the popped and its leaf children onto cur file list
FileTask parentTask = curDirProcessTasks.remove(curDirProcessTasks.size() - 1); FileTask parentTask = directoryTasks.remove(directoryTasks.size() - 1);
final AbstractFile parentFile = parentTask.file; final AbstractFile parentFile = parentTask.file;
// add itself to the file list // add itself to the file list
if (shouldEnqueueTask(parentTask)) { if (shouldEnqueueTask(parentTask)) {
this.curFileProcessTasks.addLast(parentTask); this.fileTasks.addLast(parentTask);
} }
// add its children to the file and directory lists // add its children to the file and directory lists
@ -487,13 +328,13 @@ class IngestScheduler {
for (Content c : children) { for (Content c : children) {
if (c instanceof AbstractFile) { if (c instanceof AbstractFile) {
AbstractFile childFile = (AbstractFile) c; AbstractFile childFile = (AbstractFile) c;
FileTask childTask = new FileTask(childFile, parentTask.getDataSourceTask()); FileTask childTask = new FileTask(childFile, parentTask.getJob());
if (childFile.hasChildren()) { if (childFile.hasChildren()) {
this.curDirProcessTasks.add(childTask); this.directoryTasks.add(childTask);
} }
else if (shouldEnqueueTask(childTask)) { else if (shouldEnqueueTask(childTask)) {
this.curFileProcessTasks.addLast(childTask); this.fileTasks.addLast(childTask);
} }
} }
} }
@ -506,8 +347,7 @@ class IngestScheduler {
@Override @Override
public void remove() { public void remove() {
throw new UnsupportedOperationException( throw new UnsupportedOperationException("Not supported.");
NbBundle.getMessage(this.getClass(), "IngestScheduler.remove.exception.notSupported.msg"));
} }
/** /**
@ -520,61 +360,25 @@ class IngestScheduler {
* enqueued * enqueued
*/ */
synchronized List<Content> getSourceContent() { synchronized List<Content> getSourceContent() {
final Set<Content> contentSet = new HashSet<Content>(); final Set<Content> contentSet = new HashSet<>();
for (FileTask task : rootProcessTasks) { for (FileTask task : rootDirectoryTasks) {
contentSet.add(task.getDataSourceTask().getContent()); contentSet.add(task.getJob().getDataSource());
} }
for (FileTask task : curDirProcessTasks) { for (FileTask task : directoryTasks) {
contentSet.add(task.getDataSourceTask().getContent()); contentSet.add(task.getJob().getDataSource());
} }
for (FileTask task : curFileProcessTasks) { for (FileTask task : fileTasks) {
contentSet.add(task.getDataSourceTask().getContent()); contentSet.add(task.getJob().getDataSource());
} }
return new ArrayList<Content>(contentSet); return new ArrayList<>(contentSet);
}
/**
* Determine if a module is in a pipeline in the queue.
* @param module
* @return true if it is in the queue.
*/
synchronized boolean hasModuleEnqueued(IngestModuleAbstractFile module) {
for (FileTask task : rootProcessTasks) {
List<IngestModuleAbstractFile> modules = task.getDataSourceTask().getModules();
for (IngestModuleAbstractFile m : modules) {
if (m.getName().equals(module.getName())) {
return true;
}
}
}
for (FileTask task : curDirProcessTasks) {
List<IngestModuleAbstractFile> modules = task.getDataSourceTask().getModules();
for (IngestModuleAbstractFile m : modules) {
if (m.getName().equals(module.getName())) {
return true;
}
}
}
for (FileTask task : curFileProcessTasks) {
List<IngestModuleAbstractFile> modules = task.getDataSourceTask().getModules();
for (IngestModuleAbstractFile m : modules) {
if (m.getName().equals(module.getName())) {
return true;
}
}
}
return false;
} }
synchronized void empty() { synchronized void empty() {
this.rootProcessTasks.clear(); this.rootDirectoryTasks.clear();
this.curDirProcessTasks.clear(); this.directoryTasks.clear();
this.curFileProcessTasks.clear(); this.fileTasks.clear();
} }
/** /**
@ -588,7 +392,7 @@ class IngestScheduler {
final AbstractFile aFile = processTask.file; final AbstractFile aFile = processTask.file;
//if it's unalloc file, skip if so scheduled //if it's unalloc file, skip if so scheduled
if (processTask.getDataSourceTask().isProcessUnalloc() == false if (processTask.getJob().shouldProcessUnallocatedSpace() == false
&& aFile.getType().equals(TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS //unalloc files && aFile.getType().equals(TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS //unalloc files
)) { )) {
return false; return false;
@ -642,6 +446,70 @@ class IngestScheduler {
return true; return true;
} }
/**
* Task for a specific file to process. More specific than the
* higher-level DataSourceTask.
*/
static class FileTask {
private final AbstractFile file;
private final IngestJob task;
public FileTask(AbstractFile file, IngestJob task) {
this.file = file;
this.task = task;
}
public IngestJob getJob() {
return task;
}
public AbstractFile getFile() {
return file;
}
@Override
public String toString() {
try {
return "ProcessTask{" + "file=" + file.getId() + ": "
+ file.getUniquePath() + "}"; // + ", dataSourceTask=" + dataSourceTask + '}';
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Cound not get unique path of file in queue, ", ex);
}
return "ProcessTask{" + "file=" + file.getId() + ": "
+ file.getName() + '}';
}
/**
* two process tasks are equal when the file/dir and modules are the
* same this enables are not to queue up the same file/dir, modules
* tuples into the root dir set
*
* @param obj
* @return
*/
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final FileTask other = (FileTask) obj;
if (this.file != other.file && (this.file == null || !this.file.equals(other.file))) {
return false;
}
IngestJob thisTask = this.getJob();
IngestJob otherTask = other.getJob();
if (thisTask != otherTask
&& (thisTask == null || !thisTask.equals(otherTask))) {
return false;
}
return true;
}
}
/** /**
* Root dir sorter * Root dir sorter
*/ */
@ -888,61 +756,36 @@ class IngestScheduler {
/** /**
* DataSourceScheduler ingest scheduler * DataSourceScheduler ingest scheduler
*/ */
static class DataSourceScheduler implements Iterator<DataSourceTask<IngestModuleDataSource>> { static class DataSourceScheduler implements Iterator<IngestJob> {
private LinkedList<DataSourceTask<IngestModuleDataSource>> tasks; private LinkedList<IngestJob> tasks;
DataSourceScheduler() { DataSourceScheduler() {
tasks = new LinkedList<DataSourceTask<IngestModuleDataSource>>(); tasks = new LinkedList<>();
} }
synchronized void schedule(DataSourceTask<IngestModuleDataSource> task) { synchronized void schedule(IngestJob task) {
//skip if task contains no modules
if (task.getModules().isEmpty()) {
return;
}
try { try {
if (task.getContent().getParent() != null) { if (task.getDataSource().getParent() != null) {
//only accepting parent-less content objects (Image, parentless VirtualDirectory) //only accepting parent-less content objects (Image, parentless VirtualDirectory)
logger.log(Level.SEVERE, "Only parent-less Content (data sources) can be scheduled for DataSource ingest, skipping: " + task.getContent()); logger.log(Level.SEVERE, "Only parent-less Content (data sources) can be scheduled for DataSource ingest, skipping: {0}", task.getDataSource());
return; return;
} }
} catch (TskCoreException e) { } catch (TskCoreException e) {
logger.log(Level.SEVERE, "Error validating data source to be scheduled for DataSource ingest" + task.getContent(), e); logger.log(Level.SEVERE, "Error validating data source to be scheduled for DataSource ingest" + task.getDataSource(), e);
return; return;
} }
// see if we already have a task for this data source tasks.addLast(task);
DataSourceTask<IngestModuleDataSource> existTask = null;
for (DataSourceTask<IngestModuleDataSource> curTask : tasks) {
if (curTask.getContent().equals(task.getContent())) {
existTask = curTask;
break;
}
}
// add these modules to the existing task for the data source
// @@@ BC: I'm not sure I like this and it will probably break a more formal pipeline structure
// @@@ TODO: Verify that if this is called mid-way during ingest that all of the already ingested files get scheduled with the new modules...
if (existTask != null) {
//merge modules for the data source task
existTask.addModules(task.getModules());
} else {
//enqueue a new task
tasks.addLast(task);
}
} }
@Override @Override
public synchronized DataSourceTask<IngestModuleDataSource> next() throws IllegalStateException { public synchronized IngestJob next() throws IllegalStateException {
if (!hasNext()) { if (!hasNext()) {
throw new IllegalStateException( throw new IllegalStateException("There is no data source tasks in the queue, check hasNext()");
NbBundle.getMessage(this.getClass(), "IngestScheduler.DataSourceScheduler.exception.next.msg"));
} }
final DataSourceTask<IngestModuleDataSource> ret = tasks.pollFirst(); final IngestJob ret = tasks.pollFirst();
return ret; return ret;
} }
@ -953,8 +796,8 @@ class IngestScheduler {
*/ */
synchronized List<org.sleuthkit.datamodel.Content> getContents() { synchronized List<org.sleuthkit.datamodel.Content> getContents() {
List<org.sleuthkit.datamodel.Content> contents = new ArrayList<org.sleuthkit.datamodel.Content>(); List<org.sleuthkit.datamodel.Content> contents = new ArrayList<org.sleuthkit.datamodel.Content>();
for (DataSourceTask<IngestModuleDataSource> task : tasks) { for (IngestJob task : tasks) {
contents.add(task.getContent()); contents.add(task.getDataSource());
} }
return contents; return contents;
} }
@ -966,8 +809,7 @@ class IngestScheduler {
@Override @Override
public void remove() { public void remove() {
throw new UnsupportedOperationException( throw new UnsupportedOperationException("Removing of scheduled data source ingest tasks is not supported. ");
NbBundle.getMessage(this.getClass(), "IngestScheduler.DataSourceScheduler.exception.remove.msg"));
} }
synchronized void empty() { synchronized void empty() {
@ -981,9 +823,8 @@ class IngestScheduler {
@Override @Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(NbBundle.getMessage(this.getClass(), "IngestScheduler.DataSourceScheduler.toString.size", sb.append("DataSourceQueue, size: ").append(getCount());
getCount())); for (IngestJob task : tasks) {
for (DataSourceTask<IngestModuleDataSource> task : tasks) {
sb.append(task.toString()).append(" "); sb.append(task.toString()).append(" ");
} }
return sb.toString(); return sb.toString();

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2013 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -16,8 +16,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.sleuthkit.autopsy.ingest; package org.sleuthkit.autopsy.ingest;
import java.util.Map; import java.util.Map;
@ -28,18 +26,15 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
/** /**
* Singleton class that provides services for ingest modules. * Singleton class that provides services for ingest modules. These exist to
* These exist to make it easier to write modules. Use the getDefault() * make it easier to write modules. Use the getDefault() method to get the
* method to get the singleton instance. * singleton instance.
*/ */
public class IngestServices { public final class IngestServices {
private static final Logger logger = Logger.getLogger(IngestServices.class.getName());
private IngestManager manager; private IngestManager manager;
private Logger logger = Logger.getLogger(IngestServices.class.getName());
private static IngestServices instance; private static IngestServices instance;
private IngestServices() { private IngestServices() {
@ -47,8 +42,9 @@ public class IngestServices {
} }
/** /**
* Get handle to singletone module services * Get the ingest services.
* @return the services handle *
* @return The ingest services singleton.
*/ */
public static synchronized IngestServices getDefault() { public static synchronized IngestServices getDefault() {
if (instance == null) { if (instance == null) {
@ -58,93 +54,80 @@ public class IngestServices {
} }
/** /**
* Get access to the current Case handle. * Get the current Autopsy case.
* Note: When storing the Case database handle as a member variable in a module,
* this method needs to be called within the module's init() method and the
* member variable needs to be updated at each init(),
* to ensure the correct Case handle is being used if the Case is changed.
* *
* @return current Case * @return The current case.
*/ */
public Case getCurrentCase() { public Case getCurrentCase() {
return Case.getCurrentCase(); return Case.getCurrentCase();
} }
/** /**
* Get access to the current Case database handle. Like storing * Get the current SleuthKit case. The SleuthKit case is the case database.
* the Case handle, call this method and update member variables for each
* call to the module's init() method to ensure it is correct.
* *
* @return current Case database * @return The current case database.
*/ */
public SleuthkitCase getCurrentSleuthkitCaseDb() { public SleuthkitCase getCurrentSleuthkitCaseDb() {
return Case.getCurrentCase().getSleuthkitCase(); return Case.getCurrentCase().getSleuthkitCase();
} }
/** /**
* Get a logger to be used by the module to log messages to log files. * Get a logger that incorporates the display name of an ingest module in
* @param module module to get the logger for * messages written to the Autopsy log files.
* @return logger object *
* @param moduleClassName The display name of the ingest module.
* @return The custom logger for the ingest module.
*/ */
public Logger getLogger(IngestModuleAbstract module) { public Logger getLogger(String moduleDisplayName) {
return Logger.getLogger(module.getName()); return Logger.getLogger(moduleDisplayName);
} }
/** /**
* Post ingest message to the inbox. This should be done for * Post message to the ingest messages in box.
* analysis messages. *
* @param message ingest message to be posted by ingest module * @param message An ingest message
*/ */
public void postMessage(final IngestMessage message) { public void postMessage(final IngestMessage message) {
manager.postMessage(message); manager.postIngestMessage(message);
} }
/** /**
* Fire module event to notify registered module event listeners * Fire module event to notify registered module event listeners
* @param eventType the event type, defined in IngestManager.IngestManagerEvents *
* @param eventType the event type, defined in
* IngestManager.IngestManagerEvents
* @param moduleName the module name * @param moduleName the module name
*/ */
public void fireModuleEvent(String eventType, String moduleName) { public void fireModuleEvent(String eventType, String moduleName) {
IngestManager.fireModuleEvent(eventType, moduleName); IngestManager.fireModuleEvent(eventType, moduleName);
} }
/** /**
* Fire module data event to notify registered module data event listeners that there * Fire module data event to notify registered module data event listeners
* is new data of a given type from a module * that there is new data of a given type from a module
* @param moduleDataEvent module data event, encapsulating blackboard artifact data *
* @param moduleDataEvent module data event, encapsulating blackboard
* artifact data
*/ */
public void fireModuleDataEvent(ModuleDataEvent moduleDataEvent) { public void fireModuleDataEvent(ModuleDataEvent moduleDataEvent) {
IngestManager.fireModuleDataEvent(moduleDataEvent); IngestManager.fireModuleDataEvent(moduleDataEvent);
} }
/**
/** * Fire module content event to notify registered module content event
* Fire module content event to notify registered module content event listeners * listeners that there is new content (from ZIP file contents, carving,
* that there is new content (from ZIP file contents, carving, etc.) * etc.)
* @param moduleContentEvent module content event, encapsulating content changed *
* @param moduleContentEvent module content event, encapsulating content
* changed
*/ */
public void fireModuleContentEvent(ModuleContentEvent moduleContentEvent) { public void fireModuleContentEvent(ModuleContentEvent moduleContentEvent) {
IngestManager.fireModuleContentEvent(moduleContentEvent); IngestManager.fireModuleContentEvent(moduleContentEvent);
} }
/** /**
* Schedule a new file for ingest with the same settings as the file * Get free disk space of a drive where ingest data are written to That
* being analyzed. This is used, for example, when opening an archive file. * drive is being monitored by IngestMonitor thread when ingest is running.
* File needs to have already been added to the database.
*
* @param file file to be scheduled
* @param pipelineContext the ingest context for the file ingest pipeline
*/
public void scheduleFile(AbstractFile file, PipelineContext<IngestModuleAbstractFile> pipelineContext) {
logger.log(Level.INFO, "Scheduling file: " + file.getName());
manager.scheduleFile(file, pipelineContext);
}
/**
* Get free disk space of a drive where ingest data are written to
* That drive is being monitored by IngestMonitor thread when ingest is running.
* *
* @return amount of disk space, -1 if unknown * @return amount of disk space, -1 if unknown
*/ */
@ -152,21 +135,7 @@ public class IngestServices {
return manager.getFreeDiskSpace(); return manager.getFreeDiskSpace();
} }
/**
/**
* Facility for a file ingest module to check a return value from a previously run file ingest module
* that executed for the same file.
* The module return value can be used as a guideline to skip processing the file
*
* @param moduleName registered module name of the module to check the return value of
* @return the return value of the previously executed module for the currently processed file in the file ingest pipeline
*/
public IngestModuleAbstractFile.ProcessResult getAbstractFileModuleResult(String moduleName) {
return manager.getAbstractFileModuleResult(moduleName);
}
/**
* Gets a specific name/value configuration setting for a module * Gets a specific name/value configuration setting for a module
* @param moduleName moduleName identifier unique to that module * @param moduleName moduleName identifier unique to that module
* @param settingName setting name to retrieve * @param settingName setting name to retrieve

View File

@ -51,7 +51,7 @@ public class Installer extends ModuleInstall {
@Override @Override
public void run() { public void run() {
//at this point UI top component is present for sure, ensure manager has it //at this point UI top component is present for sure, ensure manager has it
manager.initUI(); manager.initIngestMessageInbox();
//force ingest inbox closed, even if previous state was open //force ingest inbox closed, even if previous state was open
//IngestMessageTopComponent.findInstance().close(); //IngestMessageTopComponent.findInstance().close();
} }

View File

@ -43,7 +43,4 @@ public class ModuleContentEvent extends ChangeEvent {
public String getModuleName() { public String getModuleName() {
return moduleName; return moduleName;
} }
} }

View File

@ -0,0 +1,38 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.ingest;
/**
* Implementation of the IngestModuleOptions interface for use by ingest modules
* that do not have per ingest job options.
*/
public final class NoIngestModuleSettings implements IngestModuleIngestJobSettings {
private final String setting = "None";
/**
* Gets the string used as an ingest options placeholder for serialization
* purposes.
*
* @return The string "None"
*/
String getSetting() {
return setting;
}
}

View File

@ -1,77 +0,0 @@
/*
* 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.ingest;
import org.openide.util.NbBundle;
import java.util.Objects;
/**
* Stores information about a given pipeline, which is a series of modules.
* This is passed into modules for their reference.
*
* @param T type of the ingest associated with the context (file or data source Content)
*
*/
public class PipelineContext <T extends IngestModuleAbstract> {
private final DataSourceTask<T> task;
PipelineContext(DataSourceTask<T> task) {
this.task = task;
}
/**
* Returns the currently scheduled task.
* @return
*/
DataSourceTask<T> getDataSourceTask() {
return task;
}
@Override
public String toString() {
return NbBundle.getMessage(this.getClass(), "PipelineContext.toString.text", task);
}
@Override
public int hashCode() {
int hash = 5;
hash = 53 * hash + Objects.hashCode(this.task);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
@SuppressWarnings("unchecked")
final PipelineContext<T> other = (PipelineContext<T>) obj;
if (!Objects.equals(this.task, other.task)) {
return false;
}
return true;
}
}

View File

@ -963,7 +963,7 @@ import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
StringBuilder summary = new StringBuilder(); StringBuilder summary = new StringBuilder();
boolean running = false; boolean running = false;
if (IngestManager.getDefault().isIngestRunning() || IngestManager.getDefault().areModulesRunning()) { if (IngestManager.getDefault().isIngestRunning() || IngestManager.getDefault().isIngestRunning()) {
running = true; running = true;
} }

View File

@ -11,7 +11,15 @@
<build-prerequisite/> <build-prerequisite/>
<compile-dependency/> <compile-dependency/>
<run-dependency> <run-dependency>
<specification-version>8.25.1</specification-version> <specification-version>8.29.3</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.util.lookup</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.19.1</specification-version>
</run-dependency> </run-dependency>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2013 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -33,15 +33,11 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.logging.Level; import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.ImageUtils; import org.sleuthkit.autopsy.coreutils.ImageUtils;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.ingest.IngestModuleAdapter;
import org.sleuthkit.autopsy.ingest.PipelineContext; import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestServices; import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile;
import org.sleuthkit.autopsy.ingest.IngestModuleInit;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
@ -57,59 +53,44 @@ import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
* files. Ingests an image file and, if available, adds it's date, latitude, * files. Ingests an image file and, if available, adds it's date, latitude,
* longitude, altitude, device model, and device make to a blackboard artifact. * longitude, altitude, device model, and device make to a blackboard artifact.
*/ */
public final class ExifParserFileIngestModule extends IngestModuleAbstractFile { public final class ExifParserFileIngestModule extends IngestModuleAdapter implements FileIngestModule {
private IngestServices services;
final public static String MODULE_NAME = NbBundle.getMessage(ExifParserFileIngestModule.class,
"ExifParserFileIngestModule.moduleName.text");
final public static String MODULE_VERSION = Version.getVersion();
private static final Logger logger = Logger.getLogger(ExifParserFileIngestModule.class.getName()); private static final Logger logger = Logger.getLogger(ExifParserFileIngestModule.class.getName());
private static ExifParserFileIngestModule defaultInstance = null; private final IngestServices services = IngestServices.getDefault();
private int filesProcessed = 0; private int filesProcessed = 0;
private boolean filesToFire = false; private boolean filesToFire = false;
//file ingest modules require a private constructor ExifParserFileIngestModule() {
//to ensure singleton instances
private ExifParserFileIngestModule() {
}
//default instance used for module registration
public static synchronized ExifParserFileIngestModule getDefault() {
if (defaultInstance == null) {
defaultInstance = new ExifParserFileIngestModule();
}
return defaultInstance;
} }
@Override @Override
public IngestModuleAbstractFile.ProcessResult process(PipelineContext<IngestModuleAbstractFile> pipelineContext, AbstractFile content) { public ProcessResult process(AbstractFile content) {
//skip unalloc //skip unalloc
if (content.getType().equals(TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)) { if (content.getType().equals(TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)) {
return IngestModuleAbstractFile.ProcessResult.OK; return ProcessResult.OK;
} }
// skip known // skip known
if (content.getKnown().equals(TskData.FileKnown.KNOWN)) { if (content.getKnown().equals(TskData.FileKnown.KNOWN)) {
return IngestModuleAbstractFile.ProcessResult.OK; return ProcessResult.OK;
} }
// update the tree every 1000 files if we have EXIF data that is not being being displayed // update the tree every 1000 files if we have EXIF data that is not being being displayed
filesProcessed++; filesProcessed++;
if ((filesToFire) && (filesProcessed % 1000 == 0)) { if ((filesToFire) && (filesProcessed % 1000 == 0)) {
services.fireModuleDataEvent(new ModuleDataEvent(MODULE_NAME, BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF)); services.fireModuleDataEvent(new ModuleDataEvent(ExifParserModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF));
filesToFire = false; filesToFire = false;
} }
//skip unsupported //skip unsupported
if (!parsableFormat(content)) { if (!parsableFormat(content)) {
return IngestModuleAbstractFile.ProcessResult.OK; return ProcessResult.OK;
} }
return processFile(content); return processFile(content);
} }
public IngestModuleAbstractFile.ProcessResult processFile(AbstractFile f) { ProcessResult processFile(AbstractFile f) {
InputStream in = null; InputStream in = null;
BufferedInputStream bin = null; BufferedInputStream bin = null;
@ -117,7 +98,7 @@ public final class ExifParserFileIngestModule extends IngestModuleAbstractFile {
in = new ReadContentInputStream(f); in = new ReadContentInputStream(f);
bin = new BufferedInputStream(in); bin = new BufferedInputStream(in);
Collection<BlackboardAttribute> attributes = new ArrayList<BlackboardAttribute>(); Collection<BlackboardAttribute> attributes = new ArrayList<>();
Metadata metadata = ImageMetadataReader.readMetadata(bin, true); Metadata metadata = ImageMetadataReader.readMetadata(bin, true);
// Date // Date
@ -125,7 +106,7 @@ public final class ExifParserFileIngestModule extends IngestModuleAbstractFile {
if (exifDir != null) { if (exifDir != null) {
Date date = exifDir.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL); Date date = exifDir.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL);
if (date != null) { if (date != null) {
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID(), MODULE_NAME, date.getTime() / 1000)); attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID(), ExifParserModuleFactory.getModuleName(), date.getTime() / 1000));
} }
} }
@ -136,13 +117,13 @@ public final class ExifParserFileIngestModule extends IngestModuleAbstractFile {
if (loc != null) { if (loc != null) {
double latitude = loc.getLatitude(); double latitude = loc.getLatitude();
double longitude = loc.getLongitude(); double longitude = loc.getLongitude();
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID(), MODULE_NAME, latitude)); attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID(), ExifParserModuleFactory.getModuleName(), latitude));
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID(), MODULE_NAME, longitude)); attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID(), ExifParserModuleFactory.getModuleName(), longitude));
} }
Rational altitude = gpsDir.getRational(GpsDirectory.TAG_GPS_ALTITUDE); Rational altitude = gpsDir.getRational(GpsDirectory.TAG_GPS_ALTITUDE);
if (altitude != null) { if (altitude != null) {
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE.getTypeID(), MODULE_NAME, altitude.doubleValue())); attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE.getTypeID(), ExifParserModuleFactory.getModuleName(), altitude.doubleValue()));
} }
} }
@ -151,12 +132,12 @@ public final class ExifParserFileIngestModule extends IngestModuleAbstractFile {
if (devDir != null) { if (devDir != null) {
String model = devDir.getString(ExifIFD0Directory.TAG_MODEL); String model = devDir.getString(ExifIFD0Directory.TAG_MODEL);
if (model != null && !model.isEmpty()) { if (model != null && !model.isEmpty()) {
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID(), MODULE_NAME, model)); attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID(), ExifParserModuleFactory.getModuleName(), model));
} }
String make = devDir.getString(ExifIFD0Directory.TAG_MAKE); String make = devDir.getString(ExifIFD0Directory.TAG_MAKE);
if (make != null && !make.isEmpty()) { if (make != null && !make.isEmpty()) {
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE.getTypeID(), MODULE_NAME, make)); attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE.getTypeID(), ExifParserModuleFactory.getModuleName(), make));
} }
} }
@ -167,14 +148,16 @@ public final class ExifParserFileIngestModule extends IngestModuleAbstractFile {
filesToFire = true; filesToFire = true;
} }
return IngestModuleAbstractFile.ProcessResult.OK; return ProcessResult.OK;
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.WARNING, "Failed to create blackboard artifact for exif metadata (" + ex.getLocalizedMessage() + ")."); logger.log(Level.WARNING, "Failed to create blackboard artifact for exif metadata ({0}).", ex.getLocalizedMessage());
return ProcessResult.ERROR;
} catch (ImageProcessingException ex) { } catch (ImageProcessingException ex) {
logger.log(Level.WARNING, "Failed to process the image file: " + f.getParentPath() + "/" + f.getName() + "(" + ex.getLocalizedMessage() + ")"); logger.log(Level.WARNING, "Failed to process the image file: {0}/{1}({2})", new Object[]{f.getParentPath(), f.getName(), ex.getLocalizedMessage()});
return ProcessResult.ERROR;
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.WARNING, "IOException when parsing image file: " + f.getParentPath() + "/" + f.getName(), ex); logger.log(Level.WARNING, "IOException when parsing image file: " + f.getParentPath() + "/" + f.getName(), ex);
return ProcessResult.ERROR;
} finally { } finally {
try { try {
if (in != null) { if (in != null) {
@ -185,11 +168,9 @@ public final class ExifParserFileIngestModule extends IngestModuleAbstractFile {
} }
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.WARNING, "Failed to close InputStream.", ex); logger.log(Level.WARNING, "Failed to close InputStream.", ex);
return ProcessResult.ERROR;
} }
} }
// If we got here, there was an error
return IngestModuleAbstractFile.ProcessResult.ERROR;
} }
/** /**
@ -205,44 +186,10 @@ public final class ExifParserFileIngestModule extends IngestModuleAbstractFile {
} }
@Override @Override
public void complete() { public void shutDown(boolean ingestJobCancelled) {
logger.log(Level.INFO, "completed exif parsing " + this.toString());
if (filesToFire) { if (filesToFire) {
//send the final new data event //send the final new data event
services.fireModuleDataEvent(new ModuleDataEvent(MODULE_NAME, BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF)); services.fireModuleDataEvent(new ModuleDataEvent(ExifParserModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF));
} }
} }
@Override
public String getVersion() {
return MODULE_VERSION;
}
@Override
public String getName() {
return NbBundle.getMessage(this.getClass(), "ExifParserFileIngestModule.getName.text");
}
@Override
public String getDescription() {
return NbBundle.getMessage(this.getClass(), "ExifParserFileIngestModule.getDesc.text");
}
@Override
public void init(IngestModuleInit initContext) throws IngestModuleException {
services = IngestServices.getDefault();
logger.log(Level.INFO, "init() " + this.toString());
filesProcessed = 0;
filesToFire = false;
}
@Override
public void stop() {
}
@Override
public boolean hasBackgroundJobsRunning() {
return false;
}
} }

View File

@ -0,0 +1,66 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.exifparser;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter;
import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestModuleFactory;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
import org.openide.util.NbBundle;
/**
* An factory that creates file ingest modules that parse EXIF meta data
* associated with media files (e.g., JPEG format files).
*/
@ServiceProvider(service = IngestModuleFactory.class)
public class ExifParserModuleFactory extends IngestModuleFactoryAdapter {
@Override
public String getModuleDisplayName() {
return getModuleName();
}
static String getModuleName() {
return NbBundle.getMessage(ExifParserFileIngestModule.class,
"ExifParserFileIngestModule.moduleName.text");
}
@Override
public String getModuleDescription() {
return NbBundle.getMessage(ExifParserFileIngestModule.class,
"ExifParserFileIngestModule.getDesc.text");
}
@Override
public String getModuleVersionNumber() {
return Version.getVersion();
}
@Override
public boolean isFileIngestModuleFactory() {
return true;
}
@Override
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings ingestOptions) {
return new ExifParserFileIngestModule();
}
}

View File

@ -16,12 +16,9 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.sleuthkit.autopsy.fileextmismatch; package org.sleuthkit.autopsy.fileextmismatch;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -30,10 +27,11 @@ import javax.swing.AbstractAction;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
/** /**
* Do the context menu action for adding a new filename extension to * Do the context menu action for adding a new filename extension to the
* the mismatch list for the MIME type of the selected node. * mismatch list for the MIME type of the selected node.
*/ */
class AddFileExtensionAction extends AbstractAction { class AddFileExtensionAction extends AbstractAction {
private String extStr; private String extStr;
private String mimeTypeStr; private String mimeTypeStr;
@ -55,11 +53,9 @@ class AddFileExtensionAction extends AbstractAction {
if (!FileExtMismatchXML.getDefault().save(editableMap)) { if (!FileExtMismatchXML.getDefault().save(editableMap)) {
//error //error
JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(), "AddFileExtensionAction.msgDlg.msg"), NbBundle.getMessage(this.getClass(), "AddFileExtensionAction.msgDlg.msg"),
NbBundle.getMessage(this.getClass(), "AddFileExtensionAction.msgDlg.title"), NbBundle.getMessage(this.getClass(), "AddFileExtensionAction.msgDlg.title"),
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
} // else //in the future we might want to update the statusbar to give feedback to the user } // else //in the future we might want to update the statusbar to give feedback to the user
} }
} }

View File

@ -1,22 +1,6 @@
OpenIDE-Module-Name=FileExtMismatch OpenIDE-Module-Name=FileExtMismatch
OptionsCategory_Name_FileExtMismatchOptions=File Extension Mismatch OptionsCategory_Name_FileExtMismatchOptions=File Extension Mismatch
OptionsCategory_FileExtMismatch=File Extension Mismatch OptionsCategory_FileExtMismatch=File Extension Mismatch
FileExtMismatchConfigPanel.extHeaderLabel.text=Allowed Extensions:
FileExtMismatchConfigPanel.userExtTextField.text=
FileExtMismatchConfigPanel.addExtButton.text=Add Extension
FileExtMismatchConfigPanel.removeExtButton.text=Remove Selected Extension
FileExtMismatchConfigPanel.saveButton.text=Save Configuration
FileExtMismatchConfigPanel.jLabel1.text=File Types:
FileExtMismatchConfigPanel.removeTypeButton.text=Remove Selected Type
FileExtMismatchConfigPanel.addTypeButton.text=Add Type
FileExtMismatchConfigPanel.userTypeTextField.text=
FileExtMismatchConfigPanel.extErrorLabel.text=\
FileExtMismatchConfigPanel.mimeErrLabel.text=\
FileExtMismatchConfigPanel.mimeRemoveErrLabel.text=\
FileExtMismatchConfigPanel.extRemoveErrLabel.text=\
FileExtMismatchConfigPanel.saveMsgLabel.text=\
FileExtMismatchSimpleConfigPanel.skipNoExtCheckBox.text=Skip files without extensions
FileExtMismatchSimpleConfigPanel.skipTextPlain.text=Skip text files
AddFileExtensionAction.msgDlg.msg=Writing XML configuration file failed. AddFileExtensionAction.msgDlg.msg=Writing XML configuration file failed.
AddFileExtensionAction.msgDlg.title=Add Mismatch Extension Error AddFileExtensionAction.msgDlg.title=Add Mismatch Extension Error
AddFileExtensionAction.extHeaderLbl.text=Allowed Extensions for AddFileExtensionAction.extHeaderLbl.text=Allowed Extensions for
@ -50,3 +34,20 @@ FileExtMismatchIngestModule.complete.totalFiles=Total Files Processed
FileExtMismatchIngestModule.complete.svcMsg.text=File Extension Mismatch Results FileExtMismatchIngestModule.complete.svcMsg.text=File Extension Mismatch Results
FileExtMismatchOptionsPanelController.moduleErr=Module Error FileExtMismatchOptionsPanelController.moduleErr=Module Error
FileExtMismatchOptionsPanelController.moduleErr.msg=A module caused an error listening to FileExtMismatchOptionsPanelController updates. See log to determine which module. Some data could be incomplete. FileExtMismatchOptionsPanelController.moduleErr.msg=A module caused an error listening to FileExtMismatchOptionsPanelController updates. See log to determine which module. Some data could be incomplete.
FileExtMismatchModuleSettingsPanel.skipKnownFilesCheckbox.text=Skip known files (NSRL)
FileExtMismatchModuleSettingsPanel.skipTextPlain.text=Skip text files
FileExtMismatchModuleSettingsPanel.skipNoExtCheckBox.text=Skip files without extensions
FileExtMismatchSettingsPanel.addTypeButton.text=Add Type
FileExtMismatchSettingsPanel.extErrorLabel.text=\
FileExtMismatchSettingsPanel.extHeaderLabel.text=Allowed Extensions:
FileExtMismatchSettingsPanel.saveMsgLabel.text=\
FileExtMismatchSettingsPanel.mimeRemoveErrLabel.text=\
FileExtMismatchSettingsPanel.extRemoveErrLabel.text=\
FileExtMismatchSettingsPanel.mimeErrLabel.text=\
FileExtMismatchSettingsPanel.removeTypeButton.text=Remove Selected Type
FileExtMismatchSettingsPanel.saveButton.text=Save Configuration
FileExtMismatchSettingsPanel.jLabel1.text=File Types:
FileExtMismatchSettingsPanel.userExtTextField.text=
FileExtMismatchSettingsPanel.addExtButton.text=Add Extension
FileExtMismatchSettingsPanel.removeExtButton.text=Remove Selected Extension
FileExtMismatchSettingsPanel.userTypeTextField.text=

View File

@ -1,45 +1,46 @@
OpenIDE-Module-Name=\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u5B50\u4E0D\u4E00\u81F4 OpenIDE-Module-Name=\u30d5\u30a1\u30a4\u30eb\u62e1\u5f35\u5b50\u4e0d\u4e00\u81f4
OptionsCategory_Name_FileExtMismatchOptions=\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u5B50\u4E0D\u4E00\u81F4 OptionsCategory_Name_FileExtMismatchOptions=\u30d5\u30a1\u30a4\u30eb\u62e1\u5f35\u5b50\u4e0d\u4e00\u81f4
OptionsCategory_FileExtMismatch=\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u5B50\u4E0D\u4E00\u81F4 OptionsCategory_FileExtMismatch=\u30d5\u30a1\u30a4\u30eb\u62e1\u5f35\u5b50\u4e0d\u4e00\u81f4
FileExtMismatchConfigPanel.extHeaderLabel.text=\u8A31\u53EF\u3055\u308C\u305F\u62E1\u5F35\u5B50\uFF1A AddFileExtensionAction.msgDlg.msg=XML\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u66f8\u304f\u306e\u3092\u5931\u6557\u3057\u307e\u3057\u305f\u3002
FileExtMismatchConfigPanel.addExtButton.text=\u62E1\u5F35\u5B50\u3092\u8FFD\u52A0 AddFileExtensionAction.msgDlg.title=\u4e0d\u4e00\u81f4\u62e1\u5f35\u5b50\u306e\u8ffd\u52a0\u30a8\u30e9\u30fc
FileExtMismatchConfigPanel.removeExtButton.text=\u9078\u629E\u3057\u305F\u62E1\u5F35\u5B50\u3092\u524A\u9664 FileExtMismatchConfigPanel.name.text=\u30a2\u30c9\u30d0\u30f3\u30b9\u30d5\u30a1\u30a4\u30eb\u62e1\u5f35\u5b50\u4e0d\u4e00\u81f4\u8a2d\u5b9a
FileExtMismatchConfigPanel.saveButton.text=\u8A2D\u5B9A\u3092\u4FDD\u5B58 FileExtMismatchConfigPanel.addExtButton.errLabel.empty=\u62e1\u5f35\u5b50\u30c6\u30ad\u30b9\u30c8\u304c\u7a7a\u767d\u3067\u3059\uff01
FileExtMismatchConfigPanel.jLabel1.text=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\uFF1A FileExtMismatchConfigPanel.addExtButton.errLabel.noMimeType=MIME\u30bf\u30a4\u30d7\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093\uff01
FileExtMismatchConfigPanel.removeTypeButton.text=\u9078\u629E\u3057\u305F\u30BF\u30A4\u30D7\u3092\u524A\u9664 FileExtMismatchConfigPanel.addExtButton.errLabel.extExists=\u62e1\u5f35\u5b50\u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059\uff01
FileExtMismatchConfigPanel.addTypeButton.text=\u30BF\u30A4\u30D7\u3092\u8FFD\u52A0 FileExtMismatchConfigPanel.addExtButton.errLabel.extAdded=\u62e1\u5f35\u5b50{0}\u306f\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\u3002
FileExtMismatchSimpleConfigPanel.skipNoExtCheckBox.text=\u62E1\u5F35\u5B50\u306E\u7121\u3044\u30D5\u30A1\u30A4\u30EB\u306F\u30B9\u30AD\u30C3\u30D7 FileExtMismatchConfigPanel.addTypeButton.empty=MIME\u30bf\u30a4\u30d7\u30c6\u30ad\u30b9\u30c8\u304c\u7a7a\u767d\u3067\u3059\uff01
FileExtMismatchSimpleConfigPanel.skipTextPlain.text=\u30C6\u30AD\u30B9\u30C8\u30D5\u30A1\u30A4\u30EB\u306F\u30B9\u30AD\u30C3\u30D7 FileExtMismatchConfigPanel.addTypeButton.mimeTypeNotSupported=MIME\u30bf\u30a4\u30d7\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\uff01
AddFileExtensionAction.msgDlg.msg=XML\u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304F\u306E\u3092\u5931\u6557\u3057\u307E\u3057\u305F\u3002 FileExtMismatchConfigPanel.addTypeButton.mimeTypeExists=MIME\u30bf\u30a4\u30d7\u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059\uff01
AddFileExtensionAction.msgDlg.title=\u4E0D\u4E00\u81F4\u62E1\u5F35\u5B50\u306E\u8FFD\u52A0\u30A8\u30E9\u30FC FileExtMismatchConfigPanel.addTypeButton.mimeTypeNotDetectable=MIME\u30bf\u30a4\u30d7\u306f\u3053\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u3067\u306f\u691c\u51fa\u3067\u304d\u307e\u305b\u3093\u3002
FileExtMismatchConfigPanel.name.text=\u30A2\u30C9\u30D0\u30F3\u30B9\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u5B50\u4E0D\u4E00\u81F4\u8A2D\u5B9A FileExtMismatchConfigPanel.addTypeButton.mimeTypeAdded=MIME\u30bf\u30a4\u30d7{0}\u306f\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\u3002
FileExtMismatchConfigPanel.addExtButton.errLabel.empty=\u62E1\u5F35\u5B50\u30C6\u30AD\u30B9\u30C8\u304C\u7A7A\u767D\u3067\u3059\uFF01 FileExtMismatchConfigPanel.removeTypeButton.noneSelected=MIME\u30bf\u30a4\u30d7\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093\uff01
FileExtMismatchConfigPanel.addExtButton.errLabel.noMimeType=MIME\u30BF\u30A4\u30D7\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093\uFF01 FileExtMismatchConfigPanel.remoteTypeButton.deleted=MIME\u30bf\u30a4\u30d7{0}\u306f\u524a\u9664\u3055\u308c\u307e\u3057\u305f\u3002
FileExtMismatchConfigPanel.addExtButton.errLabel.extExists=\u62E1\u5F35\u5B50\u306F\u3059\u3067\u306B\u5B58\u5728\u3057\u307E\u3059\uFF01 FileExtMismatchConfigPanel.removeExtButton.noneSelected=\u62e1\u5f35\u5b50\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093\uff01
FileExtMismatchConfigPanel.addExtButton.errLabel.extAdded=\u62E1\u5F35\u5B50{0}\u306F\u8FFD\u52A0\u3055\u308C\u307E\u3057\u305F\u3002 FileExtMismatchConfigPanel.removeExtButton.noMimeTypeSelected=MIME\u30bf\u30a4\u30d7\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093\uff01
FileExtMismatchConfigPanel.addTypeButton.empty=MIME\u30BF\u30A4\u30D7\u30C6\u30AD\u30B9\u30C8\u304C\u7A7A\u767D\u3067\u3059\uFF01 FileExtMismatchConfigPanel.removeExtButton.deleted=\u62e1\u5f35\u5b50{0}\u306f\u524a\u9664\u3055\u308c\u307e\u3057\u305f\u3002
FileExtMismatchConfigPanel.addTypeButton.mimeTypeNotSupported=MIME\u30BF\u30A4\u30D7\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\uFF01 FileExtMismatchConfigPanel.store.msg=\u4fdd\u5b58\u3055\u308c\u307e\u3057\u305f\u3002
FileExtMismatchConfigPanel.addTypeButton.mimeTypeExists=MIME\u30BF\u30A4\u30D7\u306F\u3059\u3067\u306B\u5B58\u5728\u3057\u307E\u3059\uFF01 FileExtMismatchConfigPanel.store.msgDlg.msg=XML\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u66f8\u304f\u306e\u3092\u5931\u6557\u3057\u307e\u3057\u305f\u3002
FileExtMismatchConfigPanel.addTypeButton.mimeTypeNotDetectable=MIME\u30BF\u30A4\u30D7\u306F\u3053\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3067\u306F\u691C\u51FA\u3067\u304D\u307E\u305B\u3093\u3002 FileExtMismatchConfigPanel.save.msgDlg.title=\u4fdd\u5b58\u30a8\u30e9\u30fc
FileExtMismatchConfigPanel.addTypeButton.mimeTypeAdded=MIME\u30BF\u30A4\u30D7{0}\u306F\u8FFD\u52A0\u3055\u308C\u307E\u3057\u305F\u3002 FileExtMismatchConfigPanel.ok.confDlg.msg=\u8a2d\u5b9a\u5909\u66f4\u3092\u4fdd\u5b58\u3057\u307e\u3059\u304b\uff1f
FileExtMismatchConfigPanel.removeTypeButton.noneSelected=MIME\u30BF\u30A4\u30D7\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093\uFF01 FileExtMismatchConfigPanel.confDlg.title=\u4fdd\u5b58\u3055\u308c\u3066\u3044\u306a\u3044\u5909\u66f4
FileExtMismatchConfigPanel.remoteTypeButton.deleted=MIME\u30BF\u30A4\u30D7{0}\u306F\u524A\u9664\u3055\u308C\u307E\u3057\u305F\u3002 FileExtMismatchConfigPanel.mimeTableModel.colName=MIME\u30bf\u30a4\u30d7
FileExtMismatchConfigPanel.removeExtButton.noneSelected=\u62E1\u5F35\u5B50\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093\uFF01 FileExtMismatchConfigPanel.extTableModel.colName=\u62e1\u5f35\u5b50
FileExtMismatchConfigPanel.removeExtButton.noMimeTypeSelected=MIME\u30BF\u30A4\u30D7\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093\uFF01 FileExtMismatchContextMenuActionsProvider.menuItemStr=\u62e1\u5f35\u5b50{0}\u3092MIME\u30bf\u30a4\u30d7{1}\u306e\u4e00\u81f4\u3068\u3057\u3066\u8ffd\u52a0
FileExtMismatchConfigPanel.removeExtButton.deleted=\u62E1\u5F35\u5B50{0}\u306F\u524A\u9664\u3055\u308C\u307E\u3057\u305F\u3002 FileExtMismatchIngestModule.moduleName=\u62e1\u5f35\u5b50\u4e0d\u4e00\u81f4\u30c7\u30a3\u30c6\u30af\u30bf\u30fc
FileExtMismatchConfigPanel.store.msg=\u4FDD\u5B58\u3055\u308C\u307E\u3057\u305F\u3002 FileExtMismatchIngestModule.moduleDesc.text=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u306b\u57fa\u3065\u3044\u3066\u3001\u6a19\u6e96\u7684\u3067\u306f\u306a\u3044\u62e1\u5f35\u5b50\u3092\u6301\u3064\u30d5\u30a1\u30a4\u30eb\u3092\u30d5\u30e9\u30b0\u4ed8\u3051\u3057\u307e\u3059\u3002d
FileExtMismatchConfigPanel.store.msgDlg.msg=XML\u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304F\u306E\u3092\u5931\u6557\u3057\u307E\u3057\u305F\u3002 FileExtMismatchIngestModule.complete.totalProcTime=\u5408\u8a08\u51e6\u7406\u6642\u9593
FileExtMismatchConfigPanel.save.msgDlg.title=\u4FDD\u5B58\u30A8\u30E9\u30FC FileExtMismatchIngestModule.complete.totalFiles=\u5408\u8a08\u51e6\u7406\u30d5\u30a1\u30a4\u30eb\u6570
FileExtMismatchConfigPanel.ok.confDlg.msg=\u8A2D\u5B9A\u5909\u66F4\u3092\u4FDD\u5B58\u3057\u307E\u3059\u304B\uFF1F FileExtMismatchIngestModule.complete.svcMsg.text=\u30d5\u30a1\u30a4\u30eb\u62e1\u5f35\u5b50\u4e0d\u4e00\u81f4\u7d50\u679c
FileExtMismatchConfigPanel.confDlg.title=\u4FDD\u5B58\u3055\u308C\u3066\u3044\u306A\u3044\u5909\u66F4 FileExtMismatchOptionsPanelController.moduleErr=\u30e2\u30b8\u30e5\u30fc\u30eb\u30a8\u30e9\u30fc
FileExtMismatchConfigPanel.mimeTableModel.colName=MIME\u30BF\u30A4\u30D7 FileExtMismatchOptionsPanelController.moduleErr.msg=FileExtMismatchOptionsPanelController\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u306e\u78ba\u8a8d\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u8d77\u3053\u3057\u307e\u3057\u305f\u3002\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304b\u30ed\u30b0\u3067\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u4e0d\u5b8c\u5168\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002
FileExtMismatchConfigPanel.extTableModel.colName=\u62E1\u5F35\u5B50 AddFileExtensionAction.extHeaderLbl.text=\u4e0b\u8a18\u7528\u306b\u8a31\u53ef\u3055\u308c\u305f\u62e1\u5f35\u5b50
FileExtMismatchContextMenuActionsProvider.menuItemStr=\u62E1\u5F35\u5B50{0}\u3092MIME\u30BF\u30A4\u30D7{1}\u306E\u4E00\u81F4\u3068\u3057\u3066\u8FFD\u52A0 FileExtMismatchModuleSettingsPanel.skipTextPlain.text=\u30c6\u30ad\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u306f\u30b9\u30ad\u30c3\u30d7
FileExtMismatchIngestModule.moduleName=\u62E1\u5F35\u5B50\u4E0D\u4E00\u81F4\u30C7\u30A3\u30C6\u30AF\u30BF\u30FC
FileExtMismatchIngestModule.moduleDesc.text=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u306B\u57FA\u3065\u3044\u3066\u3001\u6A19\u6E96\u7684\u3067\u306F\u306A\u3044\u62E1\u5F35\u5B50\u3092\u6301\u3064\u30D5\u30A1\u30A4\u30EB\u3092\u30D5\u30E9\u30B0\u4ED8\u3051\u3057\u307E\u3059\u3002d FileExtMismatchModuleSettingsPanel.skipNoExtCheckBox.text=\u62e1\u5f35\u5b50\u306e\u7121\u3044\u30d5\u30a1\u30a4\u30eb\u306f\u30b9\u30ad\u30c3\u30d7
FileExtMismatchIngestModule.complete.totalProcTime=\u5408\u8A08\u51E6\u7406\u6642\u9593 FileExtMismatchSettingsPanel.addTypeButton.text=\u30bf\u30a4\u30d7\u3092\u8ffd\u52a0
FileExtMismatchIngestModule.complete.totalFiles=\u5408\u8A08\u51E6\u7406\u30D5\u30A1\u30A4\u30EB\u6570 FileExtMismatchSettingsPanel.extHeaderLabel.text=\u8a31\u53ef\u3055\u308c\u305f\u62e1\u5f35\u5b50\uff1a
FileExtMismatchIngestModule.complete.svcMsg.text=\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u5B50\u4E0D\u4E00\u81F4\u7D50\u679C FileExtMismatchSettingsPanel.removeTypeButton.text=\u9078\u629e\u3057\u305f\u30bf\u30a4\u30d7\u3092\u524a\u9664
FileExtMismatchOptionsPanelController.moduleErr=\u30E2\u30B8\u30E5\u30FC\u30EB\u30A8\u30E9\u30FC FileExtMismatchSettingsPanel.saveButton.text=\u8a2d\u5b9a\u3092\u4fdd\u5b58
FileExtMismatchOptionsPanelController.moduleErr.msg=FileExtMismatchOptionsPanelController\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u306E\u78BA\u8A8D\u4E2D\u306B\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u30A8\u30E9\u30FC\u3092\u8D77\u3053\u3057\u307E\u3057\u305F\u3002\u3069\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u304B\u30ED\u30B0\u3067\u78BA\u8A8D\u3057\u3066\u4E0B\u3055\u3044\u3002\u4E00\u90E8\u306E\u30C7\u30FC\u30BF\u304C\u4E0D\u5B8C\u5168\u304B\u3082\u3057\u308C\u307E\u305B\u3093\u3002 FileExtMismatchSettingsPanel.jLabel1.text=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\uff1a
AddFileExtensionAction.extHeaderLbl.text=\u4E0B\u8A18\u7528\u306B\u8A31\u53EF\u3055\u308C\u305F\u62E1\u5F35\u5B50 FileExtMismatchSettingsPanel.addExtButton.text=\u62e1\u5f35\u5b50\u3092\u8ffd\u52a0
FileExtMismatchSettingsPanel.removeExtButton.text=\u9078\u629e\u3057\u305f\u62e1\u5f35\u5b50\u3092\u524a\u9664

View File

@ -27,14 +27,13 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.Action; import javax.swing.Action;
import org.openide.util.Exceptions;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.Utilities; import org.openide.util.Utilities;
import org.openide.util.lookup.ServiceProvider; import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.corecomponentinterfaces.ContextMenuActionsProvider; import org.sleuthkit.autopsy.corecomponentinterfaces.ContextMenuActionsProvider;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestConfigurator; import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
@ -51,8 +50,7 @@ public class FileExtMismatchContextMenuActionsProvider implements ContextMenuAct
ArrayList<Action> actions = new ArrayList<>(); ArrayList<Action> actions = new ArrayList<>();
// Ignore if file ingest is in progress. // Ignore if file ingest is in progress.
IngestConfigurator ingestConfigurator = Lookup.getDefault().lookup(IngestConfigurator.class); if (!IngestManager.getDefault().isIngestRunning()) {
if (ingestConfigurator != null && !ingestConfigurator.isIngestRunning()) {
final Collection<? extends BlackboardArtifact> selectedArts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class); final Collection<? extends BlackboardArtifact> selectedArts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class);

View File

@ -0,0 +1,104 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.fileextmismatch;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter;
import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestModuleFactory;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSetttingsPanel;
/**
* An factory that creates file ingest modules that detect mismatches between
* the types of files and their extensions.
*/
@ServiceProvider(service = IngestModuleFactory.class)
public class FileExtMismatchDetectorModuleFactory extends IngestModuleFactoryAdapter {
static String getModuleName() {
return NbBundle.getMessage(FileExtMismatchIngestModule.class,
"FileExtMismatchIngestModule.moduleName");
}
@Override
public String getModuleDisplayName() {
return getModuleName();
}
@Override
public String getModuleDescription() {
return NbBundle.getMessage(FileExtMismatchIngestModule.class,
"FileExtMismatchIngestModule.moduleDesc.text");
}
@Override
public String getModuleVersionNumber() {
return Version.getVersion();
}
@Override
public IngestModuleIngestJobSettings getDefaultModuleSettings() {
return new FileExtMismatchDetectorModuleSettings();
}
@Override
public boolean hasModuleSettingsPanel() {
return true;
}
@Override
public IngestModuleIngestJobSettingsPanel getModuleSettingsPanel(IngestModuleIngestJobSettings settings) {
assert settings instanceof FileExtMismatchDetectorModuleSettings;
if (!(settings instanceof FileExtMismatchDetectorModuleSettings)) {
throw new IllegalArgumentException("Expected settings argument to be instanceof FileExtMismatchDetectorModuleSettings");
}
FileExtMismatchModuleSettingsPanel settingsPanel = new FileExtMismatchModuleSettingsPanel((FileExtMismatchDetectorModuleSettings) settings);
return settingsPanel;
}
@Override
public boolean hasGlobalSettingsPanel() {
return true;
}
@Override
public IngestModuleGlobalSetttingsPanel getGlobalSettingsPanel() {
FileExtMismatchSettingsPanel globalOptionsPanel = new FileExtMismatchSettingsPanel();
globalOptionsPanel.load();
return globalOptionsPanel;
}
@Override
public boolean isFileIngestModuleFactory() {
return true;
}
@Override
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) {
assert settings instanceof FileExtMismatchDetectorModuleSettings;
if (!(settings instanceof FileExtMismatchDetectorModuleSettings)) {
throw new IllegalArgumentException("Expected settings argument to be instanceof FileExtMismatchDetectorModuleSettings");
}
return new FileExtMismatchIngestModule((FileExtMismatchDetectorModuleSettings) settings);
}
}

View File

@ -0,0 +1,64 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.fileextmismatch;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
/**
* Ingest options for the file extension mismatch detector ingest module.
*/
final class FileExtMismatchDetectorModuleSettings implements IngestModuleIngestJobSettings {
private boolean skipKnownFiles = false;
private boolean skipFilesWithNoExtension = true;
private boolean skipFilesWithTextPlainMimeType = false;
FileExtMismatchDetectorModuleSettings() {
}
FileExtMismatchDetectorModuleSettings(boolean skipKnownFiles, boolean skipFilesWithNoExtension, boolean skipFilesWithTextPlainMimeType) {
this.skipKnownFiles = skipKnownFiles;
this.skipFilesWithNoExtension = skipFilesWithNoExtension;
this.skipFilesWithTextPlainMimeType = skipFilesWithTextPlainMimeType;
}
void setSkipKnownFiles(boolean enabled) {
skipKnownFiles = enabled;
}
boolean skipKnownFiles() {
return skipKnownFiles;
}
void setSkipFilesWithNoExtension(boolean enabled) {
skipFilesWithNoExtension = enabled;
}
boolean skipFilesWithNoExtension() {
return skipFilesWithNoExtension;
}
void setSkipFilesWithTextPlainMimeType(boolean enabled) {
skipFilesWithTextPlainMimeType = enabled;
}
boolean skipFilesWithTextPlainMimeType() {
return skipFilesWithTextPlainMimeType;
}
}

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 - 2013 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -16,8 +16,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.sleuthkit.autopsy.fileextmismatch; package org.sleuthkit.autopsy.fileextmismatch;
import java.util.ArrayList; import java.util.ArrayList;
@ -26,16 +24,14 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.ingest.IngestModuleAdapter;
import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.autopsy.ingest.IngestMessage; import org.sleuthkit.autopsy.ingest.IngestMessage;
import org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile;
import org.sleuthkit.autopsy.ingest.IngestModuleInit;
import org.sleuthkit.autopsy.ingest.IngestServices; import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.autopsy.ingest.PipelineContext;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
@ -48,74 +44,45 @@ import org.sleuthkit.datamodel.TskException;
/** /**
* Flags mismatched filename extensions based on file signature. * Flags mismatched filename extensions based on file signature.
*/ */
public class FileExtMismatchIngestModule extends org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile { public class FileExtMismatchIngestModule extends IngestModuleAdapter implements FileIngestModule {
private static FileExtMismatchIngestModule defaultInstance = null;
private static final Logger logger = Logger.getLogger(FileExtMismatchIngestModule.class.getName()); private static final Logger logger = Logger.getLogger(FileExtMismatchIngestModule.class.getName());
public static final String MODULE_NAME = NbBundle.getMessage(FileExtMismatchIngestModule.class, private static int messageId = 0; // RJCTODO: This is not thread safe
"FileExtMismatchIngestModule.moduleName"); private final IngestServices services = IngestServices.getDefault();
public static final String MODULE_DESCRIPTION = NbBundle.getMessage(FileExtMismatchIngestModule.class, private final FileExtMismatchDetectorModuleSettings settings;
"FileExtMismatchIngestModule.moduleDesc.text");
public static final String MODULE_VERSION = Version.getVersion();
private static long processTime = 0;
private static int messageId = 0;
private static long numFiles = 0;
// note: because of current design, these values must be in sync with default GUI values
// they only get updated when the user changes from the default UI values
private static boolean skipNoExt = true;
private static boolean skipTextPlain = true;
private FileExtMismatchSimpleConfigPanel simpleConfigPanel;
private FileExtMismatchConfigPanel advancedConfigPanel;
private IngestServices services;
private HashMap<String, String[]> SigTypeToExtMap = new HashMap<>(); private HashMap<String, String[]> SigTypeToExtMap = new HashMap<>();
private long processTime = 0;
private long numFiles = 0;
FileExtMismatchIngestModule(FileExtMismatchDetectorModuleSettings settings) {
// Private to ensure Singleton status this.settings = settings;
private FileExtMismatchIngestModule() {
} }
// File-level ingest modules are currently singleton -- this is required
public static synchronized FileExtMismatchIngestModule getDefault() {
//defaultInstance is a private static class variable
if (defaultInstance == null) {
defaultInstance = new FileExtMismatchIngestModule();
}
return defaultInstance;
}
@Override @Override
public void init(IngestModuleInit initContext) throws IngestModuleException { public void startUp(IngestJobContext context) throws IngestModuleException {
services = IngestServices.getDefault();
// Load mapping
FileExtMismatchXML xmlLoader = FileExtMismatchXML.getDefault(); FileExtMismatchXML xmlLoader = FileExtMismatchXML.getDefault();
SigTypeToExtMap = xmlLoader.load(); SigTypeToExtMap = xmlLoader.load();
} }
@Override @Override
public ProcessResult process(PipelineContext<IngestModuleAbstractFile> pipelineContext, AbstractFile abstractFile) { public ProcessResult process(AbstractFile abstractFile) {
// skip non-files // skip non-files
if ((abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) || if ((abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
(abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)) { || (abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)) {
return ProcessResult.OK; return ProcessResult.OK;
} }
// deleted files often have content that was not theirs and therefor causes mismatch // deleted files often have content that was not theirs and therefor causes mismatch
if ((abstractFile.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC)) || if ((abstractFile.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC))
(abstractFile.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC))) { || (abstractFile.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC))) {
return ProcessResult.OK; return ProcessResult.OK;
} }
if (abstractFile.getKnown() == FileKnown.KNOWN) { if (settings.skipKnownFiles() && (abstractFile.getKnown() == FileKnown.KNOWN)) {
return ProcessResult.OK; return ProcessResult.OK;
} }
try try {
{
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
boolean mismatchDetected = compareSigTypeToExt(abstractFile); boolean mismatchDetected = compareSigTypeToExt(abstractFile);
@ -127,7 +94,7 @@ public class FileExtMismatchIngestModule extends org.sleuthkit.autopsy.ingest.In
// add artifact // add artifact
BlackboardArtifact bart = abstractFile.newArtifact(ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED); BlackboardArtifact bart = abstractFile.newArtifact(ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED);
services.fireModuleDataEvent(new ModuleDataEvent(MODULE_NAME, ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED, Collections.singletonList(bart))); services.fireModuleDataEvent(new ModuleDataEvent(FileExtMismatchDetectorModuleFactory.getModuleName(), ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED, Collections.singletonList(bart)));
} }
return ProcessResult.OK; return ProcessResult.OK;
} catch (TskException ex) { } catch (TskException ex) {
@ -138,15 +105,16 @@ public class FileExtMismatchIngestModule extends org.sleuthkit.autopsy.ingest.In
/** /**
* Compare file type for file and extension. * Compare file type for file and extension.
*
* @param abstractFile * @param abstractFile
* @return false if the two match. True if there is a mismatch. * @return false if the two match. True if there is a mismatch.
*/ */
private boolean compareSigTypeToExt(AbstractFile abstractFile) { private boolean compareSigTypeToExt(AbstractFile abstractFile) {
try { try {
String currActualExt = abstractFile.getNameExtension(); String currActualExt = abstractFile.getNameExtension();
// If we are skipping names with no extension // If we are skipping names with no extension
if (skipNoExt && currActualExt.isEmpty()) { if (settings.skipFilesWithNoExtension() && currActualExt.isEmpty()) {
return false; return false;
} }
@ -155,7 +123,7 @@ public class FileExtMismatchIngestModule extends org.sleuthkit.autopsy.ingest.In
ArrayList<BlackboardAttribute> attributes = abstractFile.getGenInfoAttributes(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG); ArrayList<BlackboardAttribute> attributes = abstractFile.getGenInfoAttributes(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG);
for (BlackboardAttribute attribute : attributes) { for (BlackboardAttribute attribute : attributes) {
String currActualSigType = attribute.getValueString(); String currActualSigType = attribute.getValueString();
if (skipTextPlain) { if (settings.skipFilesWithTextPlainMimeType()) {
if (!currActualExt.isEmpty() && currActualSigType.equals("text/plain")) { if (!currActualExt.isEmpty() && currActualSigType.equals("text/plain")) {
return false; return false;
} }
@ -185,95 +153,20 @@ public class FileExtMismatchIngestModule extends org.sleuthkit.autopsy.ingest.In
} }
@Override @Override
public void complete() { public void shutDown(boolean ingestJobCancelled) {
StringBuilder detailsSb = new StringBuilder(); StringBuilder detailsSb = new StringBuilder();
//details
detailsSb.append("<table border='0' cellpadding='4' width='280'>"); detailsSb.append("<table border='0' cellpadding='4' width='280'>");
detailsSb.append("<tr><td>").append(FileExtMismatchDetectorModuleFactory.getModuleName()).append("</td></tr>");
detailsSb.append("<tr><td>"+MODULE_DESCRIPTION+"</td></tr>");
detailsSb.append("<tr><td>").append( detailsSb.append("<tr><td>").append(
NbBundle.getMessage(this.getClass(), "FileExtMismatchIngestModule.complete.totalProcTime")) NbBundle.getMessage(this.getClass(), "FileExtMismatchIngestModule.complete.totalProcTime"))
.append("</td><td>").append(processTime).append("</td></tr>\n"); .append("</td><td>").append(processTime).append("</td></tr>\n");
detailsSb.append("<tr><td>").append( detailsSb.append("<tr><td>").append(
NbBundle.getMessage(this.getClass(), "FileExtMismatchIngestModule.complete.totalFiles")) NbBundle.getMessage(this.getClass(), "FileExtMismatchIngestModule.complete.totalFiles"))
.append("</td><td>").append(numFiles).append("</td></tr>\n"); .append("</td><td>").append(numFiles).append("</td></tr>\n");
detailsSb.append("</table>"); detailsSb.append("</table>");
services.postMessage(IngestMessage.createMessage(++messageId, IngestMessage.MessageType.INFO, FileExtMismatchDetectorModuleFactory.getModuleName(),
services.postMessage(IngestMessage.createMessage(++messageId, IngestMessage.MessageType.INFO, this, NbBundle.getMessage(this.getClass(),
NbBundle.getMessage(this.getClass(), "FileExtMismatchIngestModule.complete.svcMsg.text"),
"FileExtMismatchIngestModule.complete.svcMsg.text"), detailsSb.toString()));
detailsSb.toString()));
}
@Override
public void stop() {
//do nothing
}
@Override
public String getName() {
return MODULE_NAME;
}
@Override
public String getDescription() {
return MODULE_DESCRIPTION;
}
@Override
public String getVersion() {
return MODULE_VERSION;
}
@Override
public boolean hasSimpleConfiguration() {
return true;
}
@Override
public boolean hasAdvancedConfiguration() {
return true;
}
@Override
public javax.swing.JPanel getSimpleConfiguration(String context) {
if (simpleConfigPanel == null) {
simpleConfigPanel = new FileExtMismatchSimpleConfigPanel();
}
return simpleConfigPanel;
}
@Override
public javax.swing.JPanel getAdvancedConfiguration(String context) {
getPanel().load();
return getPanel();
}
private FileExtMismatchConfigPanel getPanel() {
if (advancedConfigPanel == null) {
advancedConfigPanel = new FileExtMismatchConfigPanel();
}
return advancedConfigPanel;
}
@Override
public void saveAdvancedConfiguration() {
getPanel().store();
}
@Override
public boolean hasBackgroundJobsRunning() {
// we're single threaded...
return false;
}
protected static void setSkipNoExt(boolean flag) {
skipNoExt = flag;
}
protected static void setSkipTextPlain(boolean flag) {
skipTextPlain = flag;
} }
} }

View File

@ -21,6 +21,7 @@
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="skipTextPlain" min="-2" max="-2" attributes="0"/> <Component id="skipTextPlain" min="-2" max="-2" attributes="0"/>
<Component id="skipNoExtCheckBox" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="skipNoExtCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="skipKnownFilesCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="0" pref="138" max="32767" attributes="0"/> <EmptySpace min="0" pref="138" max="32767" attributes="0"/>
</Group> </Group>
@ -32,7 +33,9 @@
<Component id="skipNoExtCheckBox" min="-2" max="-2" attributes="0"/> <Component id="skipNoExtCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="skipTextPlain" min="-2" max="-2" attributes="0"/> <Component id="skipTextPlain" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="51" max="32767" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="skipKnownFilesCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="28" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -42,7 +45,7 @@
<Properties> <Properties>
<Property name="selected" type="boolean" value="true"/> <Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSimpleConfigPanel.skipNoExtCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchModuleSettingsPanel.skipNoExtCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>
@ -52,7 +55,7 @@
<Component class="javax.swing.JCheckBox" name="skipTextPlain"> <Component class="javax.swing.JCheckBox" name="skipTextPlain">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSimpleConfigPanel.skipTextPlain.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchModuleSettingsPanel.skipTextPlain.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>
@ -62,5 +65,15 @@
<AuxValue name="JavaCodeGenerator_InitCodePost" type="java.lang.String" value="skipTextPlain.setSelected(true);"/> <AuxValue name="JavaCodeGenerator_InitCodePost" type="java.lang.String" value="skipTextPlain.setSelected(true);"/>
</AuxValues> </AuxValues>
</Component> </Component>
<Component class="javax.swing.JCheckBox" name="skipKnownFilesCheckbox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchModuleSettingsPanel.skipKnownFilesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="skipKnownFilesCheckboxActionPerformed"/>
</Events>
</Component>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 - 2013 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -18,26 +18,38 @@
*/ */
package org.sleuthkit.autopsy.fileextmismatch; package org.sleuthkit.autopsy.fileextmismatch;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
/** /**
* Instances of this class provide a simplified UI for managing the hash sets configuration. * UI component used to set ingest job options for file extension mismatch
* detector ingest modules.
*/ */
class FileExtMismatchSimpleConfigPanel extends javax.swing.JPanel { final class FileExtMismatchModuleSettingsPanel extends IngestModuleIngestJobSettingsPanel {
public FileExtMismatchSimpleConfigPanel() { private final FileExtMismatchDetectorModuleSettings settings;
FileExtMismatchModuleSettingsPanel(FileExtMismatchDetectorModuleSettings settings) {
this.settings = settings;
initComponents(); initComponents();
customizeComponents(); customizeComponents();
} }
private void customizeComponents() { private void customizeComponents() {
skipNoExtCheckBox.setSelected(settings.skipFilesWithNoExtension());
skipTextPlain.setSelected(settings.skipFilesWithTextPlainMimeType());
skipKnownFilesCheckbox.setSelected(settings.skipKnownFiles());
} }
@Override
public IngestModuleIngestJobSettings getSettings() {
return settings;
}
/** This method is called from within the constructor to /**
* initialize the form. * This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is * WARNING: Do NOT modify this code. The content of this method is always
* always regenerated by the Form Editor. * regenerated by the Form Editor.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
@ -45,16 +57,17 @@ class FileExtMismatchSimpleConfigPanel extends javax.swing.JPanel {
skipNoExtCheckBox = new javax.swing.JCheckBox(); skipNoExtCheckBox = new javax.swing.JCheckBox();
skipTextPlain = new javax.swing.JCheckBox(); skipTextPlain = new javax.swing.JCheckBox();
skipKnownFilesCheckbox = new javax.swing.JCheckBox();
skipNoExtCheckBox.setSelected(true); skipNoExtCheckBox.setSelected(true);
skipNoExtCheckBox.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSimpleConfigPanel.class, "FileExtMismatchSimpleConfigPanel.skipNoExtCheckBox.text")); // NOI18N skipNoExtCheckBox.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchModuleSettingsPanel.class, "FileExtMismatchModuleSettingsPanel.skipNoExtCheckBox.text")); // NOI18N
skipNoExtCheckBox.addActionListener(new java.awt.event.ActionListener() { skipNoExtCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
skipNoExtCheckBoxActionPerformed(evt); skipNoExtCheckBoxActionPerformed(evt);
} }
}); });
skipTextPlain.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSimpleConfigPanel.class, "FileExtMismatchSimpleConfigPanel.skipTextPlain.text")); // NOI18N skipTextPlain.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchModuleSettingsPanel.class, "FileExtMismatchModuleSettingsPanel.skipTextPlain.text")); // NOI18N
skipTextPlain.setSelected(true); skipTextPlain.setSelected(true);
skipTextPlain.addActionListener(new java.awt.event.ActionListener() { skipTextPlain.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -62,6 +75,13 @@ class FileExtMismatchSimpleConfigPanel extends javax.swing.JPanel {
} }
}); });
skipKnownFilesCheckbox.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchModuleSettingsPanel.class, "FileExtMismatchModuleSettingsPanel.skipKnownFilesCheckbox.text")); // NOI18N
skipKnownFilesCheckbox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
skipKnownFilesCheckboxActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
@ -70,7 +90,8 @@ class FileExtMismatchSimpleConfigPanel extends javax.swing.JPanel {
.addContainerGap() .addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(skipTextPlain) .addComponent(skipTextPlain)
.addComponent(skipNoExtCheckBox)) .addComponent(skipNoExtCheckBox)
.addComponent(skipKnownFilesCheckbox))
.addGap(0, 138, Short.MAX_VALUE)) .addGap(0, 138, Short.MAX_VALUE))
); );
layout.setVerticalGroup( layout.setVerticalGroup(
@ -79,20 +100,26 @@ class FileExtMismatchSimpleConfigPanel extends javax.swing.JPanel {
.addComponent(skipNoExtCheckBox) .addComponent(skipNoExtCheckBox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(skipTextPlain) .addComponent(skipTextPlain)
.addContainerGap(51, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(skipKnownFilesCheckbox)
.addContainerGap(28, Short.MAX_VALUE))
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void skipNoExtCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_skipNoExtCheckBoxActionPerformed private void skipNoExtCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_skipNoExtCheckBoxActionPerformed
FileExtMismatchIngestModule.setSkipNoExt(skipNoExtCheckBox.isSelected()); settings.setSkipFilesWithNoExtension(skipNoExtCheckBox.isSelected());
}//GEN-LAST:event_skipNoExtCheckBoxActionPerformed }//GEN-LAST:event_skipNoExtCheckBoxActionPerformed
private void skipTextPlainActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_skipTextPlainActionPerformed private void skipTextPlainActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_skipTextPlainActionPerformed
FileExtMismatchIngestModule.setSkipTextPlain(skipTextPlain.isSelected()); settings.setSkipFilesWithTextPlainMimeType(skipTextPlain.isSelected());
}//GEN-LAST:event_skipTextPlainActionPerformed }//GEN-LAST:event_skipTextPlainActionPerformed
private void skipKnownFilesCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_skipKnownFilesCheckboxActionPerformed
settings.setSkipKnownFiles(skipKnownFilesCheckbox.isSelected());
}//GEN-LAST:event_skipKnownFilesCheckboxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox skipKnownFilesCheckbox;
private javax.swing.JCheckBox skipNoExtCheckBox; private javax.swing.JCheckBox skipNoExtCheckBox;
private javax.swing.JCheckBox skipTextPlain; private javax.swing.JCheckBox skipTextPlain;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables

View File

@ -16,19 +16,18 @@ import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
@OptionsPanelController.TopLevelRegistration( @OptionsPanelController.TopLevelRegistration(
categoryName = "#OptionsCategory_Name_FileExtMismatchOptions", categoryName = "#OptionsCategory_Name_FileExtMismatchOptions",
iconBase = "org/sleuthkit/autopsy/fileextmismatch/options-icon.png", iconBase = "org/sleuthkit/autopsy/fileextmismatch/options-icon.png",
position = 4, position = 4,
keywords = "#OptionsCategory_FileExtMismatch", keywords = "#OptionsCategory_FileExtMismatch",
keywordsCategory = "KeywordSearchOptions") keywordsCategory = "KeywordSearchOptions")
// migrated to Bundle
//@org.openide.util.NbBundle.Messages({"OptionsCategory_Name_FileExtMismatchOptions=File Ext Mismatch", "OptionsCategory_FileExtMismatch=File Ext Mismatch"})
public final class FileExtMismatchOptionsPanelController extends OptionsPanelController { public final class FileExtMismatchOptionsPanelController extends OptionsPanelController {
private FileExtMismatchConfigPanel panel; private FileExtMismatchSettingsPanel panel;
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private boolean changed; private boolean changed;
private static final Logger logger = Logger.getLogger(FileExtMismatchOptionsPanelController.class.getName()); private static final Logger logger = Logger.getLogger(FileExtMismatchOptionsPanelController.class.getName());
@Override @Override
public void update() { public void update() {
getPanel().load(); getPanel().load();
@ -77,9 +76,9 @@ public final class FileExtMismatchOptionsPanelController extends OptionsPanelCon
pcs.removePropertyChangeListener(l); pcs.removePropertyChangeListener(l);
} }
private FileExtMismatchConfigPanel getPanel() { private FileExtMismatchSettingsPanel getPanel() {
if (panel == null) { if (panel == null) {
panel = new FileExtMismatchConfigPanel(); panel = new FileExtMismatchSettingsPanel();
} }
return panel; return panel;
} }
@ -90,8 +89,7 @@ public final class FileExtMismatchOptionsPanelController extends OptionsPanelCon
try { try {
pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true); pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);
} } catch (Exception e) {
catch (Exception e) {
logger.log(Level.SEVERE, "FileExtMismatchOptionsPanelController listener threw exception", e); logger.log(Level.SEVERE, "FileExtMismatchOptionsPanelController listener threw exception", e);
MessageNotifyUtil.Notify.show( MessageNotifyUtil.Notify.show(
NbBundle.getMessage(this.getClass(), "FileExtMismatchOptionsPanelController.moduleErr"), NbBundle.getMessage(this.getClass(), "FileExtMismatchOptionsPanelController.moduleErr"),
@ -100,15 +98,14 @@ public final class FileExtMismatchOptionsPanelController extends OptionsPanelCon
} }
} }
try { try {
pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null); pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
} } catch (Exception e) {
catch (Exception e) { logger.log(Level.SEVERE, "FileExtMismatchOptionsPanelController listener threw exception", e);
logger.log(Level.SEVERE, "FileExtMismatchOptionsPanelController listener threw exception", e); MessageNotifyUtil.Notify.show(
MessageNotifyUtil.Notify.show( NbBundle.getMessage(this.getClass(), "FileExtMismatchOptionsPanelController.moduleErr"),
NbBundle.getMessage(this.getClass(), "FileExtMismatchOptionsPanelController.moduleErr"), NbBundle.getMessage(this.getClass(), "FileExtMismatchOptionsPanelController.moduleErr.msg"),
NbBundle.getMessage(this.getClass(), "FileExtMismatchOptionsPanelController.moduleErr.msg"), MessageNotifyUtil.MessageType.ERROR);
MessageNotifyUtil.MessageType.ERROR); }
}
} }
} }

View File

@ -53,7 +53,7 @@
<Image iconType="3" name="/org/sleuthkit/autopsy/fileextmismatch/save16.png"/> <Image iconType="3" name="/org/sleuthkit/autopsy/fileextmismatch/save16.png"/>
</Property> </Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchConfigPanel.saveButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSettingsPanel.saveButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="enabled" type="boolean" value="false"/> <Property name="enabled" type="boolean" value="false"/>
</Properties> </Properties>
@ -128,7 +128,7 @@
<Component class="javax.swing.JLabel" name="jLabel1"> <Component class="javax.swing.JLabel" name="jLabel1">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchConfigPanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSettingsPanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
@ -148,7 +148,7 @@
<Component class="javax.swing.JTextField" name="userTypeTextField"> <Component class="javax.swing.JTextField" name="userTypeTextField">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchConfigPanel.userTypeTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSettingsPanel.userTypeTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>
@ -158,7 +158,7 @@
<Component class="javax.swing.JButton" name="addTypeButton"> <Component class="javax.swing.JButton" name="addTypeButton">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchConfigPanel.addTypeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSettingsPanel.addTypeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>
@ -168,7 +168,7 @@
<Component class="javax.swing.JButton" name="removeTypeButton"> <Component class="javax.swing.JButton" name="removeTypeButton">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchConfigPanel.removeTypeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSettingsPanel.removeTypeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>
@ -181,14 +181,14 @@
<Color blue="0" green="0" red="ff" type="rgb"/> <Color blue="0" green="0" red="ff" type="rgb"/>
</Property> </Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchConfigPanel.mimeErrLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSettingsPanel.mimeErrLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="mimeRemoveErrLabel"> <Component class="javax.swing.JLabel" name="mimeRemoveErrLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchConfigPanel.mimeRemoveErrLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSettingsPanel.mimeRemoveErrLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
@ -254,7 +254,7 @@
<Component class="javax.swing.JTextField" name="userExtTextField"> <Component class="javax.swing.JTextField" name="userExtTextField">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchConfigPanel.userExtTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSettingsPanel.userExtTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>
@ -264,7 +264,7 @@
<Component class="javax.swing.JButton" name="addExtButton"> <Component class="javax.swing.JButton" name="addExtButton">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchConfigPanel.addExtButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSettingsPanel.addExtButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>
@ -287,7 +287,7 @@
<Component class="javax.swing.JButton" name="removeExtButton"> <Component class="javax.swing.JButton" name="removeExtButton">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchConfigPanel.removeExtButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSettingsPanel.removeExtButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>
@ -297,7 +297,7 @@
<Component class="javax.swing.JLabel" name="extHeaderLabel"> <Component class="javax.swing.JLabel" name="extHeaderLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchConfigPanel.extHeaderLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSettingsPanel.extHeaderLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
@ -307,14 +307,14 @@
<Color blue="0" green="0" red="ff" type="rgb"/> <Color blue="0" green="0" red="ff" type="rgb"/>
</Property> </Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchConfigPanel.extErrorLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSettingsPanel.extErrorLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="extRemoveErrLabel"> <Component class="javax.swing.JLabel" name="extRemoveErrLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchConfigPanel.extRemoveErrLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSettingsPanel.extRemoveErrLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
@ -328,7 +328,7 @@
<Color blue="ff" green="0" red="0" type="rgb"/> <Color blue="ff" green="0" red="0" type="rgb"/>
</Property> </Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchConfigPanel.saveMsgLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/fileextmismatch/Bundle.properties" key="FileExtMismatchSettingsPanel.saveMsgLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.sleuthkit.autopsy.fileextmismatch; package org.sleuthkit.autopsy.fileextmismatch;
import java.awt.Color; import java.awt.Color;
@ -30,29 +29,31 @@ import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSetttingsPanel;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.filetypeid.FileTypeIdIngestModule; import org.sleuthkit.autopsy.filetypeid.FileTypeIdIngestModule;
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
/** /**
* Container panel for File Extension Mismatch Ingest Module advanced configuration options * Container panel for File Extension Mismatch Ingest Module advanced
* configuration options
*/ */
final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements OptionsPanel { final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSetttingsPanel implements OptionsPanel {
private static Logger logger = Logger.getLogger(FileExtMismatchConfigPanel.class.getName());
private static Logger logger = Logger.getLogger(FileExtMismatchSettingsPanel.class.getName());
private HashMap<String, String[]> editableMap = new HashMap<>(); private HashMap<String, String[]> editableMap = new HashMap<>();
private ArrayList<String> mimeList = null; private ArrayList<String> mimeList = null;
private ArrayList<String> currentExtensions = null; private ArrayList<String> currentExtensions = null;
private MimeTableModel mimeTableModel; private MimeTableModel mimeTableModel;
private ExtTableModel extTableModel; private ExtTableModel extTableModel;
private final String EXT_HEADER_LABEL = NbBundle.getMessage(FileExtMismatchConfigPanel.class, private final String EXT_HEADER_LABEL = NbBundle.getMessage(FileExtMismatchSettingsPanel.class,
"AddFileExtensionAction.extHeaderLbl.text"); "AddFileExtensionAction.extHeaderLbl.text");
private String selectedMime = ""; private String selectedMime = "";
private String selectedExt = ""; private String selectedExt = "";
ListSelectionModel lsm = null; ListSelectionModel lsm = null;
public FileExtMismatchConfigPanel() { public FileExtMismatchSettingsPanel() {
mimeTableModel = new MimeTableModel(); mimeTableModel = new MimeTableModel();
extTableModel = new ExtTableModel(); extTableModel = new ExtTableModel();
@ -66,7 +67,6 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
// Handle selections on the left table // Handle selections on the left table
lsm = mimeTable.getSelectionModel(); lsm = mimeTable.getSelectionModel();
lsm.addListSelectionListener(new ListSelectionListener() { lsm.addListSelectionListener(new ListSelectionListener() {
@Override @Override
public void valueChanged(ListSelectionEvent e) { public void valueChanged(ListSelectionEvent e) {
ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource(); ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource();
@ -97,7 +97,6 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
// Handle selections on the right table // Handle selections on the right table
ListSelectionModel extLsm = extTable.getSelectionModel(); ListSelectionModel extLsm = extTable.getSelectionModel();
extLsm.addListSelectionListener(new ListSelectionListener() { extLsm.addListSelectionListener(new ListSelectionListener() {
@Override @Override
public void valueChanged(ListSelectionEvent e) { public void valueChanged(ListSelectionEvent e) {
ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource(); ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource();
@ -156,7 +155,7 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
saveMsgLabel = new javax.swing.JLabel(); saveMsgLabel = new javax.swing.JLabel();
saveButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/fileextmismatch/save16.png"))); // NOI18N saveButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/fileextmismatch/save16.png"))); // NOI18N
saveButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.saveButton.text")); // NOI18N saveButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.saveButton.text")); // NOI18N
saveButton.setEnabled(false); saveButton.setEnabled(false);
saveButton.addActionListener(new java.awt.event.ActionListener() { saveButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -166,26 +165,26 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
jSplitPane1.setDividerLocation(430); jSplitPane1.setDividerLocation(430);
jLabel1.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.jLabel1.text")); // NOI18N jLabel1.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.jLabel1.text")); // NOI18N
mimeTable.setModel(mimeTableModel); mimeTable.setModel(mimeTableModel);
jScrollPane2.setViewportView(mimeTable); jScrollPane2.setViewportView(mimeTable);
userTypeTextField.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.userTypeTextField.text")); // NOI18N userTypeTextField.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.userTypeTextField.text")); // NOI18N
userTypeTextField.addFocusListener(new java.awt.event.FocusAdapter() { userTypeTextField.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) { public void focusGained(java.awt.event.FocusEvent evt) {
userTypeTextFieldFocusGained(evt); userTypeTextFieldFocusGained(evt);
} }
}); });
addTypeButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.addTypeButton.text")); // NOI18N addTypeButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.addTypeButton.text")); // NOI18N
addTypeButton.addActionListener(new java.awt.event.ActionListener() { addTypeButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
addTypeButtonActionPerformed(evt); addTypeButtonActionPerformed(evt);
} }
}); });
removeTypeButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.removeTypeButton.text")); // NOI18N removeTypeButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.removeTypeButton.text")); // NOI18N
removeTypeButton.addActionListener(new java.awt.event.ActionListener() { removeTypeButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
removeTypeButtonActionPerformed(evt); removeTypeButtonActionPerformed(evt);
@ -193,9 +192,9 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
}); });
mimeErrLabel.setForeground(new java.awt.Color(255, 0, 0)); mimeErrLabel.setForeground(new java.awt.Color(255, 0, 0));
mimeErrLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.mimeErrLabel.text")); // NOI18N mimeErrLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.mimeErrLabel.text")); // NOI18N
mimeRemoveErrLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.mimeRemoveErrLabel.text")); // NOI18N mimeRemoveErrLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.mimeRemoveErrLabel.text")); // NOI18N
javax.swing.GroupLayout mimePanelLayout = new javax.swing.GroupLayout(mimePanel); javax.swing.GroupLayout mimePanelLayout = new javax.swing.GroupLayout(mimePanel);
mimePanel.setLayout(mimePanelLayout); mimePanel.setLayout(mimePanelLayout);
@ -240,14 +239,14 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
jSplitPane1.setLeftComponent(mimePanel); jSplitPane1.setLeftComponent(mimePanel);
userExtTextField.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.userExtTextField.text")); // NOI18N userExtTextField.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.userExtTextField.text")); // NOI18N
userExtTextField.addFocusListener(new java.awt.event.FocusAdapter() { userExtTextField.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) { public void focusGained(java.awt.event.FocusEvent evt) {
userExtTextFieldFocusGained(evt); userExtTextFieldFocusGained(evt);
} }
}); });
addExtButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.addExtButton.text")); // NOI18N addExtButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.addExtButton.text")); // NOI18N
addExtButton.addActionListener(new java.awt.event.ActionListener() { addExtButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
addExtButtonActionPerformed(evt); addExtButtonActionPerformed(evt);
@ -257,19 +256,19 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
extTable.setModel(extTableModel); extTable.setModel(extTableModel);
jScrollPane3.setViewportView(extTable); jScrollPane3.setViewportView(extTable);
removeExtButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.removeExtButton.text")); // NOI18N removeExtButton.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.removeExtButton.text")); // NOI18N
removeExtButton.addActionListener(new java.awt.event.ActionListener() { removeExtButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
removeExtButtonActionPerformed(evt); removeExtButtonActionPerformed(evt);
} }
}); });
extHeaderLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.extHeaderLabel.text")); // NOI18N extHeaderLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.extHeaderLabel.text")); // NOI18N
extErrorLabel.setForeground(new java.awt.Color(255, 0, 0)); extErrorLabel.setForeground(new java.awt.Color(255, 0, 0));
extErrorLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.extErrorLabel.text")); // NOI18N extErrorLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.extErrorLabel.text")); // NOI18N
extRemoveErrLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.extRemoveErrLabel.text")); // NOI18N extRemoveErrLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.extRemoveErrLabel.text")); // NOI18N
javax.swing.GroupLayout extensionPanelLayout = new javax.swing.GroupLayout(extensionPanel); javax.swing.GroupLayout extensionPanelLayout = new javax.swing.GroupLayout(extensionPanel);
extensionPanel.setLayout(extensionPanelLayout); extensionPanel.setLayout(extensionPanelLayout);
@ -315,7 +314,7 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
jSplitPane1.setRightComponent(extensionPanel); jSplitPane1.setRightComponent(extensionPanel);
saveMsgLabel.setForeground(new java.awt.Color(0, 0, 255)); saveMsgLabel.setForeground(new java.awt.Color(0, 0, 255));
saveMsgLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchConfigPanel.class, "FileExtMismatchConfigPanel.saveMsgLabel.text")); // NOI18N saveMsgLabel.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.saveMsgLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
@ -383,7 +382,7 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
extErrorLabel.setForeground(Color.blue); extErrorLabel.setForeground(Color.blue);
extErrorLabel.setText( extErrorLabel.setText(
NbBundle.getMessage(this.getClass(), "FileExtMismatchConfigPanel.addExtButton.errLabel.extAdded", NbBundle.getMessage(this.getClass(), "FileExtMismatchConfigPanel.addExtButton.errLabel.extAdded",
newExt)); newExt));
extRemoveErrLabel.setText(" "); extRemoveErrLabel.setText(" ");
userExtTextField.setText(""); userExtTextField.setText("");
setIsModified(); setIsModified();
@ -400,10 +399,10 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
mimeErrLabel.setText(NbBundle.getMessage(this.getClass(), "FileExtMismatchConfigPanel.addTypeButton.empty")); mimeErrLabel.setText(NbBundle.getMessage(this.getClass(), "FileExtMismatchConfigPanel.addTypeButton.empty"));
return; return;
} }
if (newMime.equals( "application/octet-stream")){ if (newMime.equals("application/octet-stream")) {
mimeErrLabel.setForeground(Color.red); mimeErrLabel.setForeground(Color.red);
mimeErrLabel.setText(NbBundle.getMessage(this.getClass(), mimeErrLabel.setText(NbBundle.getMessage(this.getClass(),
"FileExtMismatchConfigPanel.addTypeButton.mimeTypeNotSupported")); "FileExtMismatchConfigPanel.addTypeButton.mimeTypeNotSupported"));
return; return;
} }
if (mimeList.contains(newMime)) { if (mimeList.contains(newMime)) {
@ -416,7 +415,7 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
if (!FileTypeIdIngestModule.isMimeTypeDetectable(newMime)) { if (!FileTypeIdIngestModule.isMimeTypeDetectable(newMime)) {
mimeErrLabel.setForeground(Color.red); mimeErrLabel.setForeground(Color.red);
mimeErrLabel.setText(NbBundle.getMessage(this.getClass(), mimeErrLabel.setText(NbBundle.getMessage(this.getClass(),
"FileExtMismatchConfigPanel.addTypeButton.mimeTypeNotDetectable")); "FileExtMismatchConfigPanel.addTypeButton.mimeTypeNotDetectable"));
return; return;
} }
@ -477,7 +476,7 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
if (selectedMime.isEmpty()) { if (selectedMime.isEmpty()) {
extErrorLabel.setForeground(Color.red); extErrorLabel.setForeground(Color.red);
extErrorLabel.setText(NbBundle.getMessage(this.getClass(), extErrorLabel.setText(NbBundle.getMessage(this.getClass(),
"FileExtMismatchConfigPanel.removeExtButton.noMimeTypeSelected")); "FileExtMismatchConfigPanel.removeExtButton.noMimeTypeSelected"));
return; return;
} }
@ -519,16 +518,7 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
} }
@Override @Override
public void load() { public void saveSettings() {
// Load the XML into a buffer that the user can modify. They can choose
// to save it back to the file after making changes.
editableMap = FileExtMismatchXML.getDefault().load();
updateMimeList();
updateExtList();
}
@Override
public void store() {
if (FileExtMismatchXML.getDefault().save(editableMap)) { if (FileExtMismatchXML.getDefault().save(editableMap)) {
mimeErrLabel.setText(" "); mimeErrLabel.setText(" ");
mimeRemoveErrLabel.setText(" "); mimeRemoveErrLabel.setText(" ");
@ -540,14 +530,28 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
} else { } else {
//error //error
JOptionPane.showMessageDialog(this, JOptionPane.showMessageDialog(this,
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"FileExtMismatchConfigPanel.store.msgDlg.msg"), "FileExtMismatchConfigPanel.store.msgDlg.msg"),
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"FileExtMismatchConfigPanel.save.msgDlg.title"), "FileExtMismatchConfigPanel.save.msgDlg.title"),
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
} }
} }
@Override
public void load() {
// Load the XML into a buffer that the user can modify. They can choose
// to save it back to the file after making changes.
editableMap = FileExtMismatchXML.getDefault().load();
updateMimeList();
updateExtList();
}
@Override
public void store() {
saveSettings();
}
private void setIsModified() { private void setIsModified() {
saveButton.setEnabled(true); saveButton.setEnabled(true);
saveMsgLabel.setText(" "); saveMsgLabel.setText(" ");
@ -561,15 +565,15 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
public void ok() { public void ok() {
// if data is unsaved // if data is unsaved
if (saveButton.isEnabled()) { if (saveButton.isEnabled()) {
int choice = JOptionPane.showConfirmDialog(this, int choice = JOptionPane.showConfirmDialog(this,
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"FileExtMismatchConfigPanel.ok.confDlg.msg"), "FileExtMismatchConfigPanel.ok.confDlg.msg"),
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"FileExtMismatchConfigPanel.confDlg.title"), "FileExtMismatchConfigPanel.confDlg.title"),
JOptionPane.YES_NO_OPTION); JOptionPane.YES_NO_OPTION);
if (choice == JOptionPane.YES_OPTION) { if (choice == JOptionPane.YES_OPTION) {
store(); store();
} }
} }
clearErrLabels(); clearErrLabels();
load(); // The next time this panel is opened, we want it to be fresh load(); // The next time this panel is opened, we want it to be fresh
@ -578,7 +582,6 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
boolean valid() { boolean valid() {
return true; return true;
} }
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton addExtButton; private javax.swing.JButton addExtButton;
private javax.swing.JButton addTypeButton; private javax.swing.JButton addTypeButton;
@ -731,5 +734,4 @@ final class FileExtMismatchConfigPanel extends javax.swing.JPanel implements Opt
fireTableDataChanged(); fireTableDataChanged();
} }
} }
} }

View File

@ -1,6 +1,6 @@
OpenIDE-Module-Name=FileTypeId OpenIDE-Module-Name=FileTypeId
FileTypeIdSimpleConfigPanel.skipKnownCheckBox.toolTipText=Depending on how many files have known hashes, checking this box will improve the speed of file type identification. FileTypeIdModuleSettingsPanel.skipKnownCheckBox.text=Skip known files (NSRL)
FileTypeIdSimpleConfigPanel.skipKnownCheckBox.text=Skip Known Files (NSRL) FileTypeIdModuleSettingsPanel.skipKnownCheckBox.toolTipText=Depending on how many files have known hashes, checking this box will improve the speed of file type identification.
FileTypeIdIngestModule.moduleName.text=File Type Identification FileTypeIdIngestModule.moduleName.text=File Type Identification
FileTypeIdIngestModule.moduleDesc.text=Matches file types based on binary signatures. FileTypeIdIngestModule.moduleDesc.text=Matches file types based on binary signatures.
FileTypeIdIngestModule.complete.totalProcTime=Total Processing Time FileTypeIdIngestModule.complete.totalProcTime=Total Processing Time

View File

@ -1,8 +1,7 @@
OpenIDE-Module-Name=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u306E\u7279\u5B9A OpenIDE-Module-Name=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u306e\u7279\u5b9a
FileTypeIdSimpleConfigPanel.skipKnownCheckBox.toolTipText=\u65E2\u77E5\u306E\u30CF\u30C3\u30B7\u30E5\u5024\u3092\u6301\u3064\u30D5\u30A1\u30A4\u30EB\u6570\u306B\u3088\u3063\u3066\u306F\u3001\u3053\u306E\u30DC\u30C3\u30AF\u30B9\u3092\u9078\u629E\u3059\u308B\u306E\u306B\u3088\u308A\u3001\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u306E\u7279\u5B9A\u3092\u52A0\u901F\u3057\u307E\u3059\u3002 FileTypeIdModuleSettingsPanel.skipKnownCheckBox.toolTipText=\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u6301\u3064\u30d5\u30a1\u30a4\u30eb\u6570\u306b\u3088\u3063\u3066\u306f\u3001\u3053\u306e\u30dc\u30c3\u30af\u30b9\u3092\u9078\u629e\u3059\u308b\u306e\u306b\u3088\u308a\u3001\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u306e\u7279\u5b9a\u3092\u52a0\u901f\u3057\u307e\u3059\u3002
FileTypeIdSimpleConfigPanel.skipKnownCheckBox.text=\u65E2\u77E5\u30D5\u30A1\u30A4\u30EB\u3092\u30B9\u30AD\u30C3\u30D7(NSRL) FileTypeIdIngestModule.moduleName.text=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u306e\u7279\u5b9a
FileTypeIdIngestModule.moduleName.text=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u306E\u7279\u5B9A FileTypeIdIngestModule.moduleDesc.text=\u30d0\u30a4\u30ca\u30ea\u7f72\u540d\u306b\u57fa\u3065\u3044\u3066\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u3092\u4e00\u81f4\u3059\u308b\u3002
FileTypeIdIngestModule.moduleDesc.text=\u30D0\u30A4\u30CA\u30EA\u7F72\u540D\u306B\u57FA\u3065\u3044\u3066\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u3092\u4E00\u81F4\u3059\u308B\u3002 FileTypeIdIngestModule.complete.totalProcTime=\u5408\u8a08\u51e6\u7406\u6642\u9593
FileTypeIdIngestModule.complete.totalProcTime=\u5408\u8A08\u51E6\u7406\u6642\u9593 FileTypeIdIngestModule.complete.totalFiles=\u5408\u8a08\u51e6\u7406\u30d5\u30a1\u30a4\u30eb\u6570
FileTypeIdIngestModule.complete.totalFiles=\u5408\u8A08\u51E6\u7406\u30D5\u30A1\u30A4\u30EB\u6570 FileTypeIdIngestModule.complete.srvMsg.text=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u7279\u5b9a\u306e\u7d50\u679c
FileTypeIdIngestModule.complete.srvMsg.text=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u7279\u5B9A\u306E\u7D50\u679C

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2013 Basis Technology Corp. * Copyright 2013-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -27,15 +27,14 @@ import org.sleuthkit.datamodel.AbstractFile;
* to an extension string list instead of the third-party library's extension * to an extension string list instead of the third-party library's extension
* reporting. * reporting.
*/ */
interface FileTypeDetectionInterface { interface FileTypeDetectionInterface {
// Struct to hold multiple values for return
public class FileIdInfo { public class FileIdInfo {
public String type;
public String extension; public String type;
public String extension;
} }
// You only have one job
FileIdInfo attemptMatch(AbstractFile abstractFile); FileIdInfo attemptMatch(AbstractFile abstractFile);
boolean isMimeTypeDetectable(String mimeType); boolean isMimeTypeDetectable(String mimeType);

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2013 Basis Technology Corp. * Copyright 2013-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -16,19 +16,15 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.sleuthkit.autopsy.filetypeid; package org.sleuthkit.autopsy.filetypeid;
import java.util.logging.Level; import java.util.logging.Level;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestMessage; import org.sleuthkit.autopsy.ingest.IngestMessage;
import org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile;
import org.sleuthkit.autopsy.ingest.IngestModuleInit;
import org.sleuthkit.autopsy.ingest.IngestServices; import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.PipelineContext;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
@ -36,75 +32,48 @@ import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.TskData.FileKnown; import org.sleuthkit.datamodel.TskData.FileKnown;
import org.sleuthkit.datamodel.TskException; import org.sleuthkit.datamodel.TskException;
import org.sleuthkit.autopsy.ingest.IngestModule.ProcessResult;
import org.sleuthkit.autopsy.ingest.IngestModuleAdapter;
/** /**
* Detects the type of a file based on signature (magic) values. * Detects the type of a file based on signature (magic) values. Posts results
* Posts results to the blackboard. * to the blackboard.
*/ */
public class FileTypeIdIngestModule extends org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile { public class FileTypeIdIngestModule extends IngestModuleAdapter implements FileIngestModule {
private static FileTypeIdIngestModule defaultInstance = null;
public final static String MODULE_NAME = NbBundle.getMessage(FileTypeIdIngestModule.class,
"FileTypeIdIngestModule.moduleName.text");
public final static String MODULE_DESCRIPTION = NbBundle.getMessage(FileTypeIdIngestModule.class,
"FileTypeIdIngestModule.moduleDesc.text");
public final static String MODULE_VERSION = Version.getVersion();
private static final Logger logger = Logger.getLogger(FileTypeIdIngestModule.class.getName()); private static final Logger logger = Logger.getLogger(FileTypeIdIngestModule.class.getName());
private static long matchTime = 0; private static final long MIN_FILE_SIZE = 512;
private static int messageId = 0; private final FileTypeIdModuleSettings settings;
private static long numFiles = 0; private long matchTime = 0;
// NOTE: This value needs to be in sync with the default GUI value private int messageId = 0; // RJCTODO: If this is not made a thread safe static, duplicate message ids will be used
// given the current design of only updating this when the user changes the default. private long numFiles = 0;
private static boolean skipKnown = true;
private static long MIN_FILE_SIZE = 512;
private FileTypeIdSimpleConfigPanel simpleConfigPanel;
private IngestServices services;
// The detector. Swap out with a different implementation of FileTypeDetectionInterface as needed. // The detector. Swap out with a different implementation of FileTypeDetectionInterface as needed.
// If desired in the future to be more knowledgable about weird files or rare formats, we could // If desired in the future to be more knowledgable about weird files or rare formats, we could
// actually have a list of detectors which are called in order until a match is found. // actually have a list of detectors which are called in order until a match is found.
private FileTypeDetectionInterface detector = new TikaFileTypeDetector(); private FileTypeDetectionInterface detector = new TikaFileTypeDetector();
//private FileTypeDetectionInterface detector = new JMimeMagicFileTypeDetector();
//private FileTypeDetectionInterface detector = new MimeUtilFileTypeDetector();
// Private to ensure Singleton status FileTypeIdIngestModule(FileTypeIdModuleSettings settings) {
private FileTypeIdIngestModule() { this.settings = settings;
}
// File-level ingest modules are currently singleton -- this is required
public static synchronized FileTypeIdIngestModule getDefault() {
//defaultInstance is a private static class variable
if (defaultInstance == null) {
defaultInstance = new FileTypeIdIngestModule();
}
return defaultInstance;
}
@Override
public void init(IngestModuleInit initContext) throws IngestModuleException {
services = IngestServices.getDefault();
} }
@Override @Override
public ProcessResult process(PipelineContext<IngestModuleAbstractFile> pipelineContext, AbstractFile abstractFile) { public ProcessResult process(AbstractFile abstractFile) {
// skip non-files // skip non-files
if ((abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) || if ((abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
(abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)) { || (abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)) {
return ProcessResult.OK; return ProcessResult.OK;
} }
if (skipKnown && (abstractFile.getKnown() == FileKnown.KNOWN)) { if (settings.skipKnownFiles() && (abstractFile.getKnown() == FileKnown.KNOWN)) {
return ProcessResult.OK; return ProcessResult.OK;
} }
if (abstractFile.getSize() < MIN_FILE_SIZE) { if (abstractFile.getSize() < MIN_FILE_SIZE) {
return ProcessResult.OK; return ProcessResult.OK;
} }
try try {
{
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
FileTypeDetectionInterface.FileIdInfo fileId = detector.attemptMatch(abstractFile); FileTypeDetectionInterface.FileIdInfo fileId = detector.attemptMatch(abstractFile);
matchTime += (System.currentTimeMillis() - startTime); matchTime += (System.currentTimeMillis() - startTime);
@ -113,7 +82,7 @@ import org.sleuthkit.datamodel.TskException;
if (!fileId.type.isEmpty()) { if (!fileId.type.isEmpty()) {
// add artifact // add artifact
BlackboardArtifact bart = abstractFile.getGenInfoArtifact(); BlackboardArtifact bart = abstractFile.getGenInfoArtifact();
BlackboardAttribute batt = new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG.getTypeID(), MODULE_NAME, fileId.type); BlackboardAttribute batt = new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG.getTypeID(), FileTypeIdModuleFactory.getModuleName(), fileId.type);
bart.addAttribute(batt); bart.addAttribute(batt);
// we don't fire the event because we just updated TSK_GEN_INFO, which isn't displayed in the tree and is vague. // we don't fire the event because we just updated TSK_GEN_INFO, which isn't displayed in the tree and is vague.
@ -122,82 +91,33 @@ import org.sleuthkit.datamodel.TskException;
} catch (TskException ex) { } catch (TskException ex) {
logger.log(Level.WARNING, "Error matching file signature", ex); logger.log(Level.WARNING, "Error matching file signature", ex);
return ProcessResult.ERROR; return ProcessResult.ERROR;
} } catch (Exception e) {
catch (Exception e) {
logger.log(Level.WARNING, "Error matching file signature", e); logger.log(Level.WARNING, "Error matching file signature", e);
return ProcessResult.ERROR; return ProcessResult.ERROR;
} }
} }
@Override @Override
public void complete() { public void shutDown(boolean ingestJobCancelled) {
StringBuilder detailsSb = new StringBuilder(); StringBuilder detailsSb = new StringBuilder();
//details
detailsSb.append("<table border='0' cellpadding='4' width='280'>"); detailsSb.append("<table border='0' cellpadding='4' width='280'>");
detailsSb.append("<tr><td>").append(FileTypeIdModuleFactory.getModuleName()).append("</td></tr>");
detailsSb.append("<tr><td>"+MODULE_DESCRIPTION+"</td></tr>");
detailsSb.append("<tr><td>") detailsSb.append("<tr><td>")
.append(NbBundle.getMessage(this.getClass(), "FileTypeIdIngestModule.complete.totalProcTime")) .append(NbBundle.getMessage(this.getClass(), "FileTypeIdIngestModule.complete.totalProcTime"))
.append("</td><td>").append(matchTime).append("</td></tr>\n"); .append("</td><td>").append(matchTime).append("</td></tr>\n");
detailsSb.append("<tr><td>") detailsSb.append("<tr><td>")
.append(NbBundle.getMessage(this.getClass(), "FileTypeIdIngestModule.complete.totalFiles")) .append(NbBundle.getMessage(this.getClass(), "FileTypeIdIngestModule.complete.totalFiles"))
.append("</td><td>").append(numFiles).append("</td></tr>\n"); .append("</td><td>").append(numFiles).append("</td></tr>\n");
detailsSb.append("</table>"); detailsSb.append("</table>");
IngestServices.getDefault().postMessage(IngestMessage.createMessage(++messageId, IngestMessage.MessageType.INFO, FileTypeIdModuleFactory.getModuleName(),
services.postMessage(IngestMessage.createMessage(++messageId, IngestMessage.MessageType.INFO, this, NbBundle.getMessage(this.getClass(),
NbBundle.getMessage(this.getClass(), "FileTypeIdIngestModule.complete.srvMsg.text"),
"FileTypeIdIngestModule.complete.srvMsg.text"), detailsSb.toString()));
detailsSb.toString()));
}
@Override
public void stop() {
//do nothing
}
@Override
public String getName() {
return MODULE_NAME;
}
@Override
public String getDescription() {
return MODULE_DESCRIPTION;
}
@Override
public String getVersion() {
return MODULE_VERSION;
}
@Override
public boolean hasSimpleConfiguration() {
return true;
}
@Override
public javax.swing.JPanel getSimpleConfiguration(String context) {
if (simpleConfigPanel == null) {
simpleConfigPanel = new FileTypeIdSimpleConfigPanel();
}
return simpleConfigPanel;
}
@Override
public boolean hasBackgroundJobsRunning() {
// we're single threaded...
return false;
}
protected static void setSkipKnown(boolean flag) {
skipKnown = flag;
} }
/** /**
* Validate if a given mime type is in the detector's registry. * Validate if a given mime type is in the detector's registry.
*
* @param mimeType Full string of mime type, e.g. "text/html" * @param mimeType Full string of mime type, e.g. "text/html"
* @return true if detectable * @return true if detectable
*/ */
@ -205,5 +125,4 @@ import org.sleuthkit.datamodel.TskException;
FileTypeDetectionInterface detector = new TikaFileTypeDetector(); FileTypeDetectionInterface detector = new TikaFileTypeDetector();
return detector.isMimeTypeDetectable(mimeType); return detector.isMimeTypeDetectable(mimeType);
} }
} }

View File

@ -0,0 +1,90 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.filetypeid;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestModuleFactory;
import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
/**
* An factory that creates file ingest modules that determine the types of
* files.
*/
@ServiceProvider(service = IngestModuleFactory.class)
public class FileTypeIdModuleFactory extends IngestModuleFactoryAdapter {
@Override
public String getModuleDisplayName() {
return getModuleName();
}
static String getModuleName() {
return NbBundle.getMessage(FileTypeIdIngestModule.class,
"FileTypeIdIngestModule.moduleName.text");
}
@Override
public String getModuleDescription() {
return NbBundle.getMessage(FileTypeIdIngestModule.class,
"FileTypeIdIngestModule.moduleDesc.text");
}
@Override
public String getModuleVersionNumber() {
return Version.getVersion();
}
@Override
public IngestModuleIngestJobSettings getDefaultModuleSettings() {
return new FileTypeIdModuleSettings();
}
@Override
public boolean hasModuleSettingsPanel() {
return true;
}
@Override
public IngestModuleIngestJobSettingsPanel getModuleSettingsPanel(IngestModuleIngestJobSettings settings) {
assert settings instanceof FileTypeIdModuleSettings;
if (!(settings instanceof FileTypeIdModuleSettings)) {
throw new IllegalArgumentException("Expected settings argument to be instanceof FileTypeIdModuleSettings");
}
return new FileTypeIdModuleSettingsPanel((FileTypeIdModuleSettings) settings);
}
@Override
public boolean isFileIngestModuleFactory() {
return true;
}
@Override
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) {
assert settings instanceof FileTypeIdModuleSettings;
if (!(settings instanceof FileTypeIdModuleSettings)) {
throw new IllegalArgumentException("Expected settings argument to be instanceof FileTypeIdModuleSettings");
}
return new FileTypeIdIngestModule((FileTypeIdModuleSettings) settings);
}
}

View File

@ -0,0 +1,44 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.filetypeid;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
/**
* Ingest job options for the file type identifier ingest module instances.
*/
public class FileTypeIdModuleSettings implements IngestModuleIngestJobSettings {
private boolean skipKnownFiles = true;
FileTypeIdModuleSettings() {
}
FileTypeIdModuleSettings(boolean skipKnownFiles) {
this.skipKnownFiles = skipKnownFiles;
}
void setSkipKnownFiles(boolean enabled) {
skipKnownFiles = enabled;
}
boolean skipKnownFiles() {
return skipKnownFiles;
}
}

View File

@ -19,7 +19,7 @@
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/> <EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Component id="skipKnownCheckBox" min="-2" max="-2" attributes="0"/> <Component id="skipKnownCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="138" max="32767" attributes="0"/> <EmptySpace pref="608" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -28,7 +28,7 @@
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="11" max="-2" attributes="0"/> <EmptySpace min="-2" pref="11" max="-2" attributes="0"/>
<Component id="skipKnownCheckBox" min="-2" max="-2" attributes="0"/> <Component id="skipKnownCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="45" max="32767" attributes="0"/> <EmptySpace pref="47" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -38,10 +38,13 @@
<Properties> <Properties>
<Property name="selected" type="boolean" value="true"/> <Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/filetypeid/Bundle.properties" key="FileTypeIdSimpleConfigPanel.skipKnownCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/filetypeid/Bundle.properties" key="FileTypeIdModuleSettingsPanel.skipKnownCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/filetypeid/Bundle.properties" key="FileTypeIdSimpleConfigPanel.skipKnownCheckBox.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/filetypeid/Bundle.properties" key="FileTypeIdModuleSettingsPanel.skipKnownCheckBox.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="label" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/filetypeid/Bundle.properties" key="FileTypeIdModuleSettingsPanel.skipKnownCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 - 2013 Basis Technology Corp. * Copyright 2013 - 2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -18,25 +18,36 @@
*/ */
package org.sleuthkit.autopsy.filetypeid; package org.sleuthkit.autopsy.filetypeid;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
/** /**
* Instances of this class provide a simplified UI for managing the hash sets configuration. * UI component used to set ingest job options for file type identifier ingest
* modules.
*/ */
class FileTypeIdSimpleConfigPanel extends javax.swing.JPanel { final class FileTypeIdModuleSettingsPanel extends IngestModuleIngestJobSettingsPanel {
public FileTypeIdSimpleConfigPanel() { private final FileTypeIdModuleSettings settings;
public FileTypeIdModuleSettingsPanel(FileTypeIdModuleSettings settings) {
this.settings = settings;
initComponents(); initComponents();
customizeComponents(); customizeComponents();
} }
private void customizeComponents() { private void customizeComponents() {
skipKnownCheckBox.setSelected(settings.skipKnownFiles());
} }
@Override
public IngestModuleIngestJobSettings getSettings() {
return settings;
}
/** This method is called from within the constructor to /**
* initialize the form. * This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is * WARNING: Do NOT modify this code. The content of this method is always
* always regenerated by the Form Editor. * regenerated by the Form Editor.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
@ -45,8 +56,9 @@ package org.sleuthkit.autopsy.filetypeid;
skipKnownCheckBox = new javax.swing.JCheckBox(); skipKnownCheckBox = new javax.swing.JCheckBox();
skipKnownCheckBox.setSelected(true); skipKnownCheckBox.setSelected(true);
skipKnownCheckBox.setText(org.openide.util.NbBundle.getMessage(FileTypeIdSimpleConfigPanel.class, "FileTypeIdSimpleConfigPanel.skipKnownCheckBox.text")); // NOI18N skipKnownCheckBox.setText(org.openide.util.NbBundle.getMessage(FileTypeIdModuleSettingsPanel.class, "FileTypeIdModuleSettingsPanel.skipKnownCheckBox.text")); // NOI18N
skipKnownCheckBox.setToolTipText(org.openide.util.NbBundle.getMessage(FileTypeIdSimpleConfigPanel.class, "FileTypeIdSimpleConfigPanel.skipKnownCheckBox.toolTipText")); // NOI18N skipKnownCheckBox.setToolTipText(org.openide.util.NbBundle.getMessage(FileTypeIdModuleSettingsPanel.class, "FileTypeIdModuleSettingsPanel.skipKnownCheckBox.toolTipText")); // NOI18N
skipKnownCheckBox.setLabel(org.openide.util.NbBundle.getMessage(FileTypeIdModuleSettingsPanel.class, "FileTypeIdModuleSettingsPanel.skipKnownCheckBox.text")); // NOI18N
skipKnownCheckBox.addActionListener(new java.awt.event.ActionListener() { skipKnownCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
skipKnownCheckBoxActionPerformed(evt); skipKnownCheckBoxActionPerformed(evt);
@ -60,21 +72,20 @@ package org.sleuthkit.autopsy.filetypeid;
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGap(10, 10, 10) .addGap(10, 10, 10)
.addComponent(skipKnownCheckBox) .addComponent(skipKnownCheckBox)
.addContainerGap(138, Short.MAX_VALUE)) .addContainerGap(608, Short.MAX_VALUE))
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGap(11, 11, 11) .addGap(11, 11, 11)
.addComponent(skipKnownCheckBox) .addComponent(skipKnownCheckBox)
.addContainerGap(45, Short.MAX_VALUE)) .addContainerGap(47, Short.MAX_VALUE))
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void skipKnownCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_skipKnownCheckBoxActionPerformed private void skipKnownCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_skipKnownCheckBoxActionPerformed
FileTypeIdIngestModule.setSkipKnown(skipKnownCheckBox.isSelected()); settings.setSkipKnownFiles(skipKnownCheckBox.isSelected());
}//GEN-LAST:event_skipKnownCheckBoxActionPerformed }//GEN-LAST:event_skipKnownCheckBoxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox skipKnownCheckBox; private javax.swing.JCheckBox skipKnownCheckBox;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 - 2013 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -16,10 +16,9 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.sleuthkit.autopsy.filetypeid; package org.sleuthkit.autopsy.filetypeid;
import java.util.SortedSet; import java.util.SortedSet;
import org.openide.util.Exceptions;
import org.apache.tika.Tika; import org.apache.tika.Tika;
import org.apache.tika.mime.MediaType; import org.apache.tika.mime.MediaType;
import org.apache.tika.mime.MimeTypes; import org.apache.tika.mime.MimeTypes;
@ -36,7 +35,6 @@ class TikaFileTypeDetector implements FileTypeDetectionInterface {
FileTypeDetectionInterface.FileIdInfo ret = new FileTypeDetectionInterface.FileIdInfo(); FileTypeDetectionInterface.FileIdInfo ret = new FileTypeDetectionInterface.FileIdInfo();
final int maxBytesInitial = 100; //how many bytes to read on first pass final int maxBytesInitial = 100; //how many bytes to read on first pass
byte buffer[] = new byte[maxBytesInitial]; byte buffer[] = new byte[maxBytesInitial];
int len = abstractFile.read(buffer, 0, maxBytesInitial);
boolean found = false; boolean found = false;
try { try {
@ -70,9 +68,10 @@ class TikaFileTypeDetector implements FileTypeDetectionInterface {
} }
/** /**
* Validate if a given mime type is in the registry. * Validate if a given mime type is in the registry. For Tika, we remove the
* For Tika, we remove the string "tika" from all MIME names, * string "tika" from all MIME names, e.g. use "application/x-msoffice" NOT
* e.g. use "application/x-msoffice" NOT "application/x-tika-msoffice" * "application/x-tika-msoffice"
*
* @param mimeType Full string of mime type, e.g. "text/html" * @param mimeType Full string of mime type, e.g. "text/html"
* @return true if detectable * @return true if detectable
*/ */

View File

@ -32,11 +32,12 @@ import org.openide.util.NbBundle;
import org.openide.util.Utilities; import org.openide.util.Utilities;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.openide.util.actions.Presenter; import org.openide.util.actions.Presenter;
import org.sleuthkit.autopsy.ingest.IngestConfigurator; import org.sleuthkit.autopsy.ingest.IngestJobLauncher;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import static org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb; import static org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb;
import org.sleuthkit.autopsy.ingest.IngestManager;
/** /**
* Instances of this Action allow users to content to a hash database. * Instances of this Action allow users to content to a hash database.
@ -81,8 +82,7 @@ final class AddContentToHashDbAction extends AbstractAction implements Presenter
super(SINGLE_SELECTION_NAME); super(SINGLE_SELECTION_NAME);
// Disable the menu if file ingest is in progress. // Disable the menu if file ingest is in progress.
IngestConfigurator ingestConfigurator = Lookup.getDefault().lookup(IngestConfigurator.class); if (IngestManager.getDefault().isIngestRunning()) {
if (null != ingestConfigurator && ingestConfigurator.isIngestRunning()) {
setEnabled(false); setEnabled(false);
return; return;
} }

View File

@ -30,33 +30,10 @@ HashDbImportDatabaseDialog.cancelButton.text=Cancel
HashDbCreateDatabaseDialog.jLabel2.text=Type: HashDbCreateDatabaseDialog.jLabel2.text=Type:
HashDbCreateDatabaseDialog.knownBadRadioButton.text=Known Bad HashDbCreateDatabaseDialog.knownBadRadioButton.text=Known Bad
HashDbCreateDatabaseDialog.cancelButton.text=Cancel HashDbCreateDatabaseDialog.cancelButton.text=Cancel
HashDbConfigPanel.nameLabel.text=Hash Set Name:
HashDbConfigPanel.hashDbNameLabel.text=No database selected
HashDbConfigPanel.hashDatabasesLabel.text=Hash Databases:
HashDbConfigPanel.hashDbLocationLabel.text=No database selected
HashDbConfigPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes.
HashDbConfigPanel.jButton3.text=Import Database
HashDbConfigPanel.jLabel6.text=Type:
HashDbConfigPanel.jLabel4.text=Location:
HashDbConfigPanel.jLabel2.text=Name:
HashDbConfigPanel.optionsLabel.text=Options
HashDbConfigPanel.typeLabel.text=Type:
HashDbConfigPanel.locationLabel.text=Database Path:
HashDbConfigPanel.hashDbIndexStatusLabel.text=No database selected
HashDbConfigPanel.hashDbTypeLabel.text=No database selected
HashDbConfigPanel.indexButton.text=Index
HashDbConfigPanel.indexLabel.text=Index Status:
HashDbConfigPanel.informationLabel.text=Information
HashDbConfigPanel.importDatabaseButton.text=Import Database
HashDbConfigPanel.deleteDatabaseButton.text=Delete Database
HashDbConfigPanel.indexPathLabelLabel.text=Index Path:
HashDbConfigPanel.indexPathLabel.text=No database selected
ModalNoButtons.CURRENTDB_LABEL.text=(CurrentDb) ModalNoButtons.CURRENTDB_LABEL.text=(CurrentDb)
ModalNoButtons.CURRENTLYON_LABEL.text=Currently Indexing x of y ModalNoButtons.CURRENTLYON_LABEL.text=Currently Indexing x of y
ModalNoButtons.GO_GET_COFFEE_LABEL.text=Hash databases are currently being indexed, this may take some time. ModalNoButtons.GO_GET_COFFEE_LABEL.text=Hash databases are currently being indexed, this may take some time.
ModalNoButtons.CANCEL_BUTTON.text=Cancel ModalNoButtons.CANCEL_BUTTON.text=Cancel
HashDbSimpleConfigPanel.knownBadHashDbsLabel.text=Select known BAD hash databases to use:
HashDbSimpleConfigPanel.knownHashDbsLabel.text=Select known hash databases to use:
HashDbImportDatabaseDialog.knownRadioButton.text=Known (NSRL or other) HashDbImportDatabaseDialog.knownRadioButton.text=Known (NSRL or other)
HashDbCreateDatabaseDialog.knownRadioButton.text=Known HashDbCreateDatabaseDialog.knownRadioButton.text=Known
HashDbCreateDatabaseDialog.jLabel1.text=Database Path: HashDbCreateDatabaseDialog.jLabel1.text=Database Path:
@ -66,13 +43,10 @@ HashDbImportDatabaseDialog.jLabel3.text=Database Path:
HashDbCreateDatabaseDialog.sendIngestMessagesCheckbox.text=Send ingest inbox messages for each hit HashDbCreateDatabaseDialog.sendIngestMessagesCheckbox.text=Send ingest inbox messages for each hit
HashDbImportDatabaseDialog.sendIngestMessagesCheckbox.text=Send ingest inbox message for each hit HashDbImportDatabaseDialog.sendIngestMessagesCheckbox.text=Send ingest inbox message for each hit
HashDbImportDatabaseDialog.hashSetNameTextField.text= HashDbImportDatabaseDialog.hashSetNameTextField.text=
HashDbConfigPanel.createDatabaseButton.text=Create Database
HashDbImportDatabaseDialog.openButton.text=Open... HashDbImportDatabaseDialog.openButton.text=Open...
HashDbSimpleConfigPanel.alwaysCalcHashesCheckbox.text=Calculate MD5 even if no hash database is selected
HashDbCreateDatabaseDialog.jLabel3.text=Hash Set Name: HashDbCreateDatabaseDialog.jLabel3.text=Hash Set Name:
HashDbCreateDatabaseDialog.okButton.text=OK HashDbCreateDatabaseDialog.okButton.text=OK
HashDbCreateDatabaseDialog.databasePathTextField.text= HashDbCreateDatabaseDialog.databasePathTextField.text=
HashDbConfigPanel.sendIngestMessagesCheckBox.text=Send ingest inbox message for each hit
AddContentToHashDbAction.ContentMenu.noHashDbsConfigd=No hash databases configured AddContentToHashDbAction.ContentMenu.noHashDbsConfigd=No hash databases configured
AddContentToHashDbAction.ContentMenu.createDbItem=Create database... AddContentToHashDbAction.ContentMenu.createDbItem=Create database...
AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr=Add to Hash Database Error AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr=Add to Hash Database Error
@ -202,3 +176,29 @@ AddContentToHashDbAction.singleSelectionName=Add file to hash database
AddContentToHashDbAction.multipleSelectionName=Add files to hash database AddContentToHashDbAction.multipleSelectionName=Add files to hash database
HashDbManager.ingestRunningExceptionMsg=Ingest is ongoing; this service will be unavailable until it finishes. HashDbManager.ingestRunningExceptionMsg=Ingest is ongoing; this service will be unavailable until it finishes.
HashDbManager.saveErrorExceptionMsg=Error saving hash configuration HashDbManager.saveErrorExceptionMsg=Error saving hash configuration
HashLookupSettingsPanel.optionsLabel.text=Options
HashLookupSettingsPanel.jButton3.text=Import Database
HashLookupSettingsPanel.indexPathLabelLabel.text=Index Path:
HashLookupSettingsPanel.createDatabaseButton.text=Create Database
HashLookupSettingsPanel.jLabel6.text=Type:
HashLookupSettingsPanel.jLabel4.text=Location:
HashLookupSettingsPanel.jLabel2.text=Name:
HashLookupSettingsPanel.indexPathLabel.text=No database selected
HashLookupSettingsPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes.
HashLookupSettingsPanel.deleteDatabaseButton.text=Delete Database
HashLookupSettingsPanel.importDatabaseButton.text=Import Database
HashLookupSettingsPanel.hashDatabasesLabel.text=Hash Databases:
HashLookupSettingsPanel.nameLabel.text=Hash Set Name:
HashLookupSettingsPanel.informationLabel.text=Information
HashLookupSettingsPanel.sendIngestMessagesCheckBox.text=Send ingest inbox message for each hit
HashLookupSettingsPanel.hashDbLocationLabel.text=No database selected
HashLookupSettingsPanel.hashDbNameLabel.text=No database selected
HashLookupSettingsPanel.typeLabel.text=Type:
HashLookupSettingsPanel.locationLabel.text=Database Path:
HashLookupSettingsPanel.hashDbIndexStatusLabel.text=No database selected
HashLookupSettingsPanel.hashDbTypeLabel.text=No database selected
HashLookupSettingsPanel.indexButton.text=Index
HashLookupSettingsPanel.indexLabel.text=Index Status:
HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.text=Calculate MD5 even if no hash database is selected
HashLookupModuleSettingsPanel.knownHashDbsLabel.text=Select known hash databases to use:
HashLookupModuleSettingsPanel.knownBadHashDbsLabel.text=Select known BAD hash databases to use:

View File

@ -23,31 +23,9 @@ HashDbImportDatabaseDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
HashDbCreateDatabaseDialog.jLabel2.text=\u7a2e\u985e\uff1a HashDbCreateDatabaseDialog.jLabel2.text=\u7a2e\u985e\uff1a
HashDbCreateDatabaseDialog.knownBadRadioButton.text=\u65e2\u77e5\u306e\u60aa\u8cea HashDbCreateDatabaseDialog.knownBadRadioButton.text=\u65e2\u77e5\u306e\u60aa\u8cea
HashDbCreateDatabaseDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb HashDbCreateDatabaseDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
HashDbConfigPanel.nameLabel.text=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u306e\u540d\u524d\uff1a
HashDbConfigPanel.hashDbNameLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashDbConfigPanel.hashDatabasesLabel.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\uff1a
HashDbConfigPanel.hashDbLocationLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashDbConfigPanel.ingestWarningLabel.text=\u51e6\u7406\u4e2d\u3067\u3059\u3002\u5b8c\u4e86\u3059\u308b\u307e\u3067\u4e00\u90e8\u306e\u8a2d\u5b9a\u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
HashDbConfigPanel.jButton3.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30dd\u30fc\u30c8
HashDbConfigPanel.jLabel6.text=\u7a2e\u985e\uff1a
HashDbConfigPanel.jLabel4.text=\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\uff1a
HashDbConfigPanel.jLabel2.text=\u540d\u524d\uff1a
HashDbConfigPanel.optionsLabel.text=\u30aa\u30d7\u30b7\u30e7\u30f3
HashDbConfigPanel.typeLabel.text=\u7a2e\u985e\uff1a
HashDbConfigPanel.locationLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d1\u30b9\uff1a
HashDbConfigPanel.hashDbIndexStatusLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashDbConfigPanel.hashDbTypeLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashDbConfigPanel.indexButton.text=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9
HashDbConfigPanel.indexLabel.text=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u30b9\u30c6\u30fc\u30bf\u30b9\uff1a
HashDbConfigPanel.informationLabel.text=\u30a4\u30f3\u30d5\u30a9\u30e1\u30fc\u30b7\u30e7\u30f3
HashDbConfigPanel.importDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30dd\u30fc\u30c8
HashDbConfigPanel.deleteDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u524a\u9664
HashDbConfigPanel.indexPathLabelLabel.text=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u30d1\u30b9\uff1a
HashDbConfigPanel.indexPathLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
ModalNoButtons.CURRENTLYON_LABEL.text=y\u306ex\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d ModalNoButtons.CURRENTLYON_LABEL.text=y\u306ex\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d
ModalNoButtons.GO_GET_COFFEE_LABEL.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d\u3067\u3059\u3002\u6642\u9593\u304c\u304b\u304b\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002 ModalNoButtons.GO_GET_COFFEE_LABEL.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d\u3067\u3059\u3002\u6642\u9593\u304c\u304b\u304b\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002
ModalNoButtons.CANCEL_BUTTON.text=\u30ad\u30e3\u30f3\u30bb\u30eb ModalNoButtons.CANCEL_BUTTON.text=\u30ad\u30e3\u30f3\u30bb\u30eb
HashDbSimpleConfigPanel.knownBadHashDbsLabel.text=\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u51e6\u7406\u306b\u5229\u7528\uff1a
HashDbImportDatabaseDialog.knownRadioButton.text=\u65e2\u77e5\uff08NSRL\u307e\u305f\u306f\u305d\u306e\u4ed6\uff09 HashDbImportDatabaseDialog.knownRadioButton.text=\u65e2\u77e5\uff08NSRL\u307e\u305f\u306f\u305d\u306e\u4ed6\uff09
HashDbCreateDatabaseDialog.knownRadioButton.text=\u65e2\u77e5 HashDbCreateDatabaseDialog.knownRadioButton.text=\u65e2\u77e5
HashDbCreateDatabaseDialog.jLabel1.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d1\u30b9\uff1a HashDbCreateDatabaseDialog.jLabel1.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d1\u30b9\uff1a
@ -55,12 +33,9 @@ HashDbCreateDatabaseDialog.saveAsButton.text=\u540d\u524d\u3092\u3064\u3051\u306
HashDbImportDatabaseDialog.jLabel3.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d1\u30b9\uff1a HashDbImportDatabaseDialog.jLabel3.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d1\u30b9\uff1a
HashDbCreateDatabaseDialog.sendIngestMessagesCheckbox.text=\u51e6\u7406\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u308b HashDbCreateDatabaseDialog.sendIngestMessagesCheckbox.text=\u51e6\u7406\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u308b
HashDbImportDatabaseDialog.sendIngestMessagesCheckbox.text=\u51e6\u7406\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u308b HashDbImportDatabaseDialog.sendIngestMessagesCheckbox.text=\u51e6\u7406\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u308b
HashDbConfigPanel.createDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4f5c\u6210
HashDbImportDatabaseDialog.openButton.text=\u958b\u304f... HashDbImportDatabaseDialog.openButton.text=\u958b\u304f...
HashDbSimpleConfigPanel.alwaysCalcHashesCheckbox.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082\u3001\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u8a08\u7b97
HashDbCreateDatabaseDialog.jLabel3.text=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u306e\u540d\u524d\uff1a HashDbCreateDatabaseDialog.jLabel3.text=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u306e\u540d\u524d\uff1a
HashDbCreateDatabaseDialog.okButton.text=OK HashDbCreateDatabaseDialog.okButton.text=OK
HashDbConfigPanel.sendIngestMessagesCheckBox.text=\u51e6\u7406\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u308b
AddContentToHashDbAction.ContentMenu.noHashDbsConfigd=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093 AddContentToHashDbAction.ContentMenu.noHashDbsConfigd=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093
AddContentToHashDbAction.ContentMenu.createDbItem=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4f5c\u6210... AddContentToHashDbAction.ContentMenu.createDbItem=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4f5c\u6210...
AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a8\u30e9\u30fc\u306b\u8ffd\u52a0 AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a8\u30e9\u30fc\u306b\u8ffd\u52a0
@ -110,7 +85,6 @@ HashDbIngestModule.moduleDescription=\u6a19\u6e96\u306eNSRL\u30c7\u30fc\u30bf\u3
HashDbIngestModule.noKnownHashDbSetMsg=\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\u3002 HashDbIngestModule.noKnownHashDbSetMsg=\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\u3002
HashDbIngestModule.knownFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u304c\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002 HashDbIngestModule.knownFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u304c\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002
HashDbIngestModule.noKnownBadHashDbSetMsg=\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30bb\u30c3\u30c8\u306f\u3042\u308a\u307e\u305b\u3093\u3002 HashDbIngestModule.noKnownBadHashDbSetMsg=\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30bb\u30c3\u30c8\u306f\u3042\u308a\u307e\u305b\u3093\u3002
HashDbSimpleConfigPanel.knownHashDbsLabel.text=\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u51e6\u7406\u306b\u5229\u7528\uff1a
HashDbConfigPanel.dbNotIndexedMsg=\u4e0b\u8a18\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3057\u307e\u3059\u304b\uff1f\ HashDbConfigPanel.dbNotIndexedMsg=\u4e0b\u8a18\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3057\u307e\u3059\u304b\uff1f\
{0} {0}
HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u60aa\u8cea\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u306f\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002 HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u60aa\u8cea\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u306f\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002
@ -191,3 +165,29 @@ OptionsCategory_Name_HashDatabase=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30
OptionsCategory_Keywords_HashDatabase=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9 OptionsCategory_Keywords_HashDatabase=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9
HashDbManager.ingestRunningExceptionMsg=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u4e2d\uff1b\u5b8c\u4e86\u3059\u308b\u307e\u3067\u3053\u306e\u30b5\u30fc\u30d3\u30b9\u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002 HashDbManager.ingestRunningExceptionMsg=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u4e2d\uff1b\u5b8c\u4e86\u3059\u308b\u307e\u3067\u3053\u306e\u30b5\u30fc\u30d3\u30b9\u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
HashLookupSettingsPanel.optionsLabel.text=\u30aa\u30d7\u30b7\u30e7\u30f3
HashLookupSettingsPanel.jButton3.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30dd\u30fc\u30c8
HashLookupSettingsPanel.indexPathLabelLabel.text=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u30d1\u30b9\uff1a
HashLookupSettingsPanel.createDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4f5c\u6210
HashLookupSettingsPanel.jLabel6.text=\u7a2e\u985e\uff1a
HashLookupSettingsPanel.jLabel4.text=\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\uff1a
HashLookupSettingsPanel.jLabel2.text=\u540d\u524d\uff1a
HashLookupSettingsPanel.indexPathLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashLookupSettingsPanel.ingestWarningLabel.text=\u51e6\u7406\u4e2d\u3067\u3059\u3002\u5b8c\u4e86\u3059\u308b\u307e\u3067\u4e00\u90e8\u306e\u8a2d\u5b9a\u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
HashLookupSettingsPanel.deleteDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u524a\u9664
HashLookupSettingsPanel.importDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30dd\u30fc\u30c8
HashLookupSettingsPanel.hashDatabasesLabel.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\uff1a
HashLookupSettingsPanel.nameLabel.text=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u306e\u540d\u524d\uff1a
HashLookupSettingsPanel.informationLabel.text=\u30a4\u30f3\u30d5\u30a9\u30e1\u30fc\u30b7\u30e7\u30f3
HashLookupSettingsPanel.sendIngestMessagesCheckBox.text=\u51e6\u7406\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u308b
HashLookupSettingsPanel.hashDbLocationLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashLookupSettingsPanel.hashDbNameLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashLookupSettingsPanel.typeLabel.text=\u7a2e\u985e\uff1a
HashLookupSettingsPanel.locationLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d1\u30b9\uff1a
HashLookupSettingsPanel.hashDbIndexStatusLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashLookupSettingsPanel.hashDbTypeLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashLookupSettingsPanel.indexButton.text=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9
HashLookupSettingsPanel.indexLabel.text=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u30b9\u30c6\u30fc\u30bf\u30b9\uff1a
HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082\u3001\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u8a08\u7b97
HashLookupModuleSettingsPanel.knownHashDbsLabel.text=\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u51e6\u7406\u306b\u5229\u7528\uff1a
HashLookupModuleSettingsPanel.knownBadHashDbsLabel.text=\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u51e6\u7406\u306b\u5229\u7528\uff1a

View File

@ -41,7 +41,7 @@ id = "HashDatabase")
//@org.openide.util.NbBundle.Messages({"OptionsCategory_Name_HashDatabase=Hash Database", "OptionsCategory_Keywords_HashDatabase=Hash Database"}) //@org.openide.util.NbBundle.Messages({"OptionsCategory_Name_HashDatabase=Hash Database", "OptionsCategory_Keywords_HashDatabase=Hash Database"})
public final class HashDatabaseOptionsPanelController extends OptionsPanelController { public final class HashDatabaseOptionsPanelController extends OptionsPanelController {
private HashDbConfigPanel panel; private HashLookupSettingsPanel panel;
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private boolean changed; private boolean changed;
private static final Logger logger = Logger.getLogger(HashDatabaseOptionsPanelController.class.getName()); private static final Logger logger = Logger.getLogger(HashDatabaseOptionsPanelController.class.getName());
@ -92,9 +92,9 @@ public final class HashDatabaseOptionsPanelController extends OptionsPanelContro
pcs.removePropertyChangeListener(l); pcs.removePropertyChangeListener(l);
} }
private HashDbConfigPanel getPanel() { private HashLookupSettingsPanel getPanel() {
if (panel == null) { if (panel == null) {
panel = new HashDbConfigPanel(); panel = new HashLookupSettingsPanel();
} }
return panel; return panel;
} }

View File

@ -23,15 +23,10 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.autopsy.ingest.PipelineContext;
import org.sleuthkit.autopsy.ingest.IngestMessage; import org.sleuthkit.autopsy.ingest.IngestMessage;
import org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile;
import org.sleuthkit.autopsy.ingest.IngestModuleInit;
import org.sleuthkit.autopsy.ingest.IngestServices; import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
@ -45,143 +40,61 @@ import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.TskException; import org.sleuthkit.datamodel.TskException;
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb; import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb;
import org.sleuthkit.autopsy.ingest.IngestModuleAbstract.IngestModuleException; import org.sleuthkit.autopsy.ingest.IngestModuleAdapter;
import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.datamodel.HashInfo; import org.sleuthkit.datamodel.HashInfo;
public class HashDbIngestModule extends IngestModuleAbstractFile { public class HashDbIngestModule extends IngestModuleAdapter implements FileIngestModule {
private static HashDbIngestModule instance = null;
public final static String MODULE_NAME = NbBundle.getMessage(HashDbIngestModule.class,
"HashDbIngestModule.moduleName");
public final static String MODULE_DESCRIPTION = NbBundle.getMessage(HashDbIngestModule.class,
"HashDbIngestModule.moduleDescription");
final public static String MODULE_VERSION = Version.getVersion();
private static final Logger logger = Logger.getLogger(HashDbIngestModule.class.getName()); private static final Logger logger = Logger.getLogger(HashDbIngestModule.class.getName());
private static final int MAX_COMMENT_SIZE = 500; private static final int MAX_COMMENT_SIZE = 500;
private HashDbSimpleConfigPanel simpleConfigPanel; private static int messageId = 0; // RJCTODO: This is not thread safe
private HashDbConfigPanel advancedConfigPanel; private final IngestServices services = IngestServices.getDefault();
private IngestServices services; private final Hash hasher = new Hash();
private SleuthkitCase skCase; private final SleuthkitCase skCase = Case.getCurrentCase().getSleuthkitCase();
private static int messageId = 0; private final HashDbManager hashDbManager = HashDbManager.getInstance();
private int knownBadCount = 0; private final HashLookupModuleSettings settings;
private boolean calcHashesIsSet;
private List<HashDb> knownBadHashSets = new ArrayList<>(); private List<HashDb> knownBadHashSets = new ArrayList<>();
private List<HashDb> knownHashSets = new ArrayList<>(); private List<HashDb> knownHashSets = new ArrayList<>();
static long calctime = 0; private int knownBadCount = 0;
static long lookuptime = 0; private long calctime = 0;
private final Hash hasher = new Hash(); private long lookuptime = 0;
private HashDbIngestModule() { HashDbIngestModule(HashLookupModuleSettings settings) {
} this.settings = settings;
public static synchronized HashDbIngestModule getDefault() {
if (instance == null) {
instance = new HashDbIngestModule();
}
return instance;
} }
@Override @Override
public String getName() { public void startUp(org.sleuthkit.autopsy.ingest.IngestJobContext context) throws IngestModuleException {
return MODULE_NAME; getEnabledHashSets(hashDbManager.getKnownBadFileHashSets(), knownBadHashSets);
}
@Override
public String getDescription() {
return MODULE_DESCRIPTION;
}
@Override
public String getVersion() {
return MODULE_VERSION;
}
@Override
public boolean hasSimpleConfiguration() {
return true;
}
@Override
public javax.swing.JPanel getSimpleConfiguration(String context) {
if (null == simpleConfigPanel) {
simpleConfigPanel = new HashDbSimpleConfigPanel();
}
else {
simpleConfigPanel.load();
}
return simpleConfigPanel;
}
@Override
public void saveSimpleConfiguration() {
if (simpleConfigPanel != null) {
simpleConfigPanel.store();
}
}
@Override
public boolean hasAdvancedConfiguration() {
return true;
}
@Override
public javax.swing.JPanel getAdvancedConfiguration(String context) {
if (advancedConfigPanel == null) {
advancedConfigPanel = new HashDbConfigPanel();
}
advancedConfigPanel.load();
return advancedConfigPanel;
}
@Override
public void saveAdvancedConfiguration() {
if (advancedConfigPanel != null) {
advancedConfigPanel.store();
}
if (simpleConfigPanel != null) {
simpleConfigPanel.load();
}
}
@Override
public void init(IngestModuleInit initContext) throws IngestModuleException {
services = IngestServices.getDefault();
skCase = Case.getCurrentCase().getSleuthkitCase();
HashDbManager hashDbManager = HashDbManager.getInstance();
getHashSetsUsableForIngest(hashDbManager.getKnownBadFileHashSets(), knownBadHashSets);
getHashSetsUsableForIngest(hashDbManager.getKnownFileHashSets(), knownHashSets);
calcHashesIsSet = hashDbManager.getAlwaysCalculateHashes();
if (knownHashSets.isEmpty()) {
services.postMessage(IngestMessage.createWarningMessage(++messageId,
this,
NbBundle.getMessage(this.getClass(),
"HashDbIngestModule.noKnownHashDbSetMsg"),
NbBundle.getMessage(this.getClass(),
"HashDbIngestModule.knownFileSearchWillNotExecuteWarn")));
}
if (knownBadHashSets.isEmpty()) { if (knownBadHashSets.isEmpty()) {
services.postMessage(IngestMessage.createWarningMessage(++messageId, services.postMessage(IngestMessage.createWarningMessage(++messageId,
this, HashLookupModuleFactory.getModuleName(),
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"HashDbIngestModule.noKnownBadHashDbSetMsg"), "HashDbIngestModule.noKnownBadHashDbSetMsg"),
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn"))); "HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn")));
} }
getEnabledHashSets(hashDbManager.getKnownFileHashSets(), knownHashSets);
if (knownHashSets.isEmpty()) {
services.postMessage(IngestMessage.createWarningMessage(++messageId,
HashLookupModuleFactory.getModuleName(),
NbBundle.getMessage(this.getClass(),
"HashDbIngestModule.noKnownHashDbSetMsg"),
NbBundle.getMessage(this.getClass(),
"HashDbIngestModule.knownFileSearchWillNotExecuteWarn")));
}
} }
private void getHashSetsUsableForIngest(List<HashDb> hashDbs, List<HashDb> hashDbsForIngest) { private void getEnabledHashSets(List<HashDb> hashSets, List<HashDb> enabledHashSets) {
assert hashDbs != null; assert hashSets != null;
assert hashDbsForIngest != null; assert enabledHashSets != null;
hashDbsForIngest.clear(); enabledHashSets.clear();
for (HashDb db : hashDbs) { for (HashDb db : hashSets) {
if (db.getSearchDuringIngest()) { if (settings.isHashSetEnabled(db.getHashSetName())) {
try { try {
if (db.hasIndex()) { if (db.hasIndex()) {
hashDbsForIngest.add(db); enabledHashSets.add(db);
} }
} }
catch (TskCoreException ex) { catch (TskCoreException ex) {
@ -192,23 +105,14 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
} }
@Override @Override
public boolean hasBackgroundJobsRunning() { public ProcessResult process(AbstractFile file) {
return false; // Skip unallocated space files.
}
@Override
public ProcessResult process(PipelineContext<IngestModuleAbstractFile>pipelineContext, AbstractFile file) {
//skip unalloc
if (file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)) { if (file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)) {
return IngestModuleAbstractFile.ProcessResult.OK; return ProcessResult.OK;
} }
return processFile(file);
}
private ProcessResult processFile(AbstractFile file) {
// bail out if we have no hashes set // bail out if we have no hashes set
if ((knownHashSets.isEmpty()) && (knownBadHashSets.isEmpty()) && (calcHashesIsSet == false)) { if ((knownHashSets.isEmpty()) && (knownBadHashSets.isEmpty()) && (!settings.shouldCalculateHashes())) {
return ProcessResult.OK; return ProcessResult.OK;
} }
@ -223,7 +127,7 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.WARNING, "Error calculating hash of file " + name, ex); logger.log(Level.WARNING, "Error calculating hash of file " + name, ex);
services.postMessage(IngestMessage.createErrorMessage(++messageId, services.postMessage(IngestMessage.createErrorMessage(++messageId,
HashDbIngestModule.this, HashLookupModuleFactory.getModuleName(),
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"HashDbIngestModule.fileReadErrorMsg", "HashDbIngestModule.fileReadErrorMsg",
name), name),
@ -249,7 +153,7 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
} catch (TskException ex) { } catch (TskException ex) {
logger.log(Level.WARNING, "Couldn't set known bad state for file " + name + " - see sleuthkit log for details", ex); logger.log(Level.WARNING, "Couldn't set known bad state for file " + name + " - see sleuthkit log for details", ex);
services.postMessage(IngestMessage.createErrorMessage(++messageId, services.postMessage(IngestMessage.createErrorMessage(++messageId,
HashDbIngestModule.this, HashLookupModuleFactory.getModuleName(),
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"HashDbIngestModule.hashLookupErrorMsg", "HashDbIngestModule.hashLookupErrorMsg",
name), name),
@ -280,7 +184,7 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
} catch (TskException ex) { } catch (TskException ex) {
logger.log(Level.WARNING, "Couldn't lookup known bad hash for file " + name + " - see sleuthkit log for details", ex); logger.log(Level.WARNING, "Couldn't lookup known bad hash for file " + name + " - see sleuthkit log for details", ex);
services.postMessage(IngestMessage.createErrorMessage(++messageId, services.postMessage(IngestMessage.createErrorMessage(++messageId,
HashDbIngestModule.this, HashLookupModuleFactory.getModuleName(),
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"HashDbIngestModule.hashLookupErrorMsg", "HashDbIngestModule.hashLookupErrorMsg",
name), name),
@ -304,14 +208,6 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
break; break;
} catch (TskException ex) { } catch (TskException ex) {
logger.log(Level.WARNING, "Couldn't set known state for file " + name + " - see sleuthkit log for details", ex); logger.log(Level.WARNING, "Couldn't set known state for file " + name + " - see sleuthkit log for details", ex);
services.postMessage(IngestMessage.createErrorMessage(++messageId,
HashDbIngestModule.this,
NbBundle.getMessage(this.getClass(),
"HashDbIngestModule.hashLookupErrorMsg",
name),
NbBundle.getMessage(this.getClass(),
"HashDbIngestModule.settingsKnownStateErr",
name)));
ret = ProcessResult.ERROR; ret = ProcessResult.ERROR;
} }
} }
@ -319,7 +215,7 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
} catch (TskException ex) { } catch (TskException ex) {
logger.log(Level.WARNING, "Couldn't lookup known hash for file " + name + " - see sleuthkit log for details", ex); logger.log(Level.WARNING, "Couldn't lookup known hash for file " + name + " - see sleuthkit log for details", ex);
services.postMessage(IngestMessage.createErrorMessage(++messageId, services.postMessage(IngestMessage.createErrorMessage(++messageId,
HashDbIngestModule.this, HashLookupModuleFactory.getModuleName(),
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"HashDbIngestModule.hashLookupErrorMsg", "HashDbIngestModule.hashLookupErrorMsg",
name), name),
@ -336,6 +232,8 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
private void postHashSetHitToBlackboard(AbstractFile abstractFile, String md5Hash, String hashSetName, String comment, boolean showInboxMessage) { private void postHashSetHitToBlackboard(AbstractFile abstractFile, String md5Hash, String hashSetName, String comment, boolean showInboxMessage) {
try { try {
String MODULE_NAME = NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.moduleName");
BlackboardArtifact badFile = abstractFile.newArtifact(ARTIFACT_TYPE.TSK_HASHSET_HIT); BlackboardArtifact badFile = abstractFile.newArtifact(ARTIFACT_TYPE.TSK_HASHSET_HIT);
//TODO Revisit usage of deprecated constructor as per TSK-583 //TODO Revisit usage of deprecated constructor as per TSK-583
//BlackboardAttribute att2 = new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID(), MODULE_NAME, "Known Bad", hashSetName); //BlackboardAttribute att2 = new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID(), MODULE_NAME, "Known Bad", hashSetName);
@ -376,7 +274,7 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
detailsSb.append("</table>"); detailsSb.append("</table>");
services.postMessage(IngestMessage.createDataMessage(++messageId, this, services.postMessage(IngestMessage.createDataMessage(++messageId, HashLookupModuleFactory.getModuleName(),
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"HashDbIngestModule.postToBB.knownBadMsg", "HashDbIngestModule.postToBB.knownBadMsg",
abstractFile.getName()), abstractFile.getName()),
@ -392,7 +290,7 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
@Override @Override
public void complete() { public void shutDown(boolean ingestJobCancelled) {
if ((!knownBadHashSets.isEmpty()) || (!knownHashSets.isEmpty())) { if ((!knownBadHashSets.isEmpty()) || (!knownHashSets.isEmpty())) {
StringBuilder detailsSb = new StringBuilder(); StringBuilder detailsSb = new StringBuilder();
//details //details
@ -421,14 +319,10 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
detailsSb.append("</ul>"); detailsSb.append("</ul>");
services.postMessage(IngestMessage.createMessage(++messageId, services.postMessage(IngestMessage.createMessage(++messageId,
IngestMessage.MessageType.INFO, IngestMessage.MessageType.INFO,
this, HashLookupModuleFactory.getModuleName(),
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"HashDbIngestModule.complete.hashLookupResults"), "HashDbIngestModule.complete.hashLookupResults"),
detailsSb.toString())); detailsSb.toString()));
} }
} }
@Override
public void stop() {
}
} }

View File

@ -0,0 +1,118 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.hashdatabase;
import java.util.ArrayList;
import java.util.List;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter;
import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestModuleFactory;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSetttingsPanel;
/**
* A factory that creates file ingest modules that do hash database lookups.
*/
@ServiceProvider(service = IngestModuleFactory.class)
public class HashLookupModuleFactory extends IngestModuleFactoryAdapter {
private HashLookupModuleSettingsPanel moduleSettingsPanel = null;
@Override
public String getModuleDisplayName() {
return getModuleName();
}
static String getModuleName() {
return NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.moduleName");
}
@Override
public String getModuleDescription() {
return NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.moduleDescription");
}
@Override
public String getModuleVersionNumber() {
return Version.getVersion();
}
@Override
public IngestModuleIngestJobSettings getDefaultModuleSettings() {
HashDbManager hashDbManager = HashDbManager.getInstance();
List<String> enabledHashSets = new ArrayList<>();
List<HashDbManager.HashDb> knownFileHashSets = hashDbManager.getKnownFileHashSets();
for (HashDbManager.HashDb db : knownFileHashSets) {
if (db.getSearchDuringIngest()) {
enabledHashSets.add(db.getHashSetName());
}
}
List<HashDbManager.HashDb> knownBadFileHashSets = hashDbManager.getKnownBadFileHashSets();
for (HashDbManager.HashDb db : knownBadFileHashSets) {
if (db.getSearchDuringIngest()) {
enabledHashSets.add(db.getHashSetName());
}
}
return new HashLookupModuleSettings(hashDbManager.getAlwaysCalculateHashes(), enabledHashSets);
}
@Override
public boolean hasModuleSettingsPanel() {
return true;
}
@Override
public IngestModuleIngestJobSettingsPanel getModuleSettingsPanel(IngestModuleIngestJobSettings settings) {
if (moduleSettingsPanel == null) {
moduleSettingsPanel = new HashLookupModuleSettingsPanel();
}
moduleSettingsPanel.load(); // RJCTODO: Fix this, use passed in settings
return moduleSettingsPanel;
}
@Override
public boolean hasGlobalSettingsPanel() {
return true;
}
@Override
public IngestModuleGlobalSetttingsPanel getGlobalSettingsPanel() {
HashLookupSettingsPanel globalSettingsPanel = new HashLookupSettingsPanel();
globalSettingsPanel.load();
return globalSettingsPanel;
}
@Override
public boolean isFileIngestModuleFactory() {
return true;
}
@Override
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) {
assert settings instanceof HashLookupModuleSettings;
if (!(settings instanceof HashLookupModuleSettings)) {
throw new IllegalArgumentException("Expected settings argument to be instanceof HashLookupModuleSettings");
}
return new HashDbIngestModule((HashLookupModuleSettings) settings);
}
}

View File

@ -0,0 +1,47 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.hashdatabase;
import java.util.HashSet;
import java.util.List;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
/**
* Settings for a hash lookup file ingest module instance.
*/
final class HashLookupModuleSettings implements IngestModuleIngestJobSettings {
private final HashSet<String> enabledHashSets = new HashSet<>();
private boolean shouldCalculateHashes = true;
HashLookupModuleSettings(boolean shouldCalculateHashes, List<String> enabledHashSetNames) {
this.shouldCalculateHashes = shouldCalculateHashes;
for (String hashSet : enabledHashSetNames) {
enabledHashSets.add(hashSet);
}
}
boolean shouldCalculateHashes() {
return shouldCalculateHashes;
}
boolean isHashSetEnabled(String hashSetName) {
return enabledHashSets.contains(hashSetName);
}
}

View File

@ -83,21 +83,21 @@
<Component class="javax.swing.JLabel" name="knownBadHashDbsLabel"> <Component class="javax.swing.JLabel" name="knownBadHashDbsLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbSimpleConfigPanel.knownBadHashDbsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupModuleSettingsPanel.knownBadHashDbsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="knownHashDbsLabel"> <Component class="javax.swing.JLabel" name="knownHashDbsLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbSimpleConfigPanel.knownHashDbsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupModuleSettingsPanel.knownHashDbsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JCheckBox" name="alwaysCalcHashesCheckbox"> <Component class="javax.swing.JCheckBox" name="alwaysCalcHashesCheckbox">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbSimpleConfigPanel.alwaysCalcHashesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 - 2013 Basis Technology Corp. * Copyright 2011 - 2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -16,11 +16,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.sleuthkit.autopsy.hashdatabase; package org.sleuthkit.autopsy.hashdatabase;
import java.awt.event.ActionEvent; import java.beans.PropertyChangeEvent;
import java.awt.event.ActionListener; import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
@ -28,22 +28,25 @@ import javax.swing.JScrollPane;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn; import javax.swing.table.TableColumn;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb; import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
/** /**
* Instances of this class provide a simplified UI for managing the hash sets configuration. * Instances of this class provide a simplified UI for managing the hash sets
* configuration.
*/ */
public class HashDbSimpleConfigPanel extends javax.swing.JPanel { public class HashLookupModuleSettingsPanel extends IngestModuleIngestJobSettingsPanel implements PropertyChangeListener {
private final HashDbManager hashDbManager = HashDbManager.getInstance();
private HashDatabasesTableModel knownTableModel; private HashDatabasesTableModel knownTableModel;
private HashDatabasesTableModel knownBadTableModel; private HashDatabasesTableModel knownBadTableModel;
public HashDbSimpleConfigPanel() { HashLookupModuleSettingsPanel() {
knownTableModel = new HashDatabasesTableModel(HashDbManager.HashDb.KnownFilesType.KNOWN); knownTableModel = new HashDatabasesTableModel(HashDbManager.HashDb.KnownFilesType.KNOWN);
knownBadTableModel = new HashDatabasesTableModel(HashDbManager.HashDb.KnownFilesType.KNOWN_BAD); knownBadTableModel = new HashDatabasesTableModel(HashDbManager.HashDb.KnownFilesType.KNOWN_BAD);
initComponents(); initComponents();
@ -53,18 +56,9 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
private void customizeComponents() { private void customizeComponents() {
customizeHashDbsTable(jScrollPane1, knownHashTable, knownTableModel); customizeHashDbsTable(jScrollPane1, knownHashTable, knownTableModel);
customizeHashDbsTable(jScrollPane2, knownBadHashTable, knownBadTableModel); customizeHashDbsTable(jScrollPane2, knownBadHashTable, knownBadTableModel);
alwaysCalcHashesCheckbox.setSelected(HashDbManager.getInstance().getAlwaysCalculateHashes()); alwaysCalcHashesCheckbox.setSelected(hashDbManager.getAlwaysCalculateHashes());
// Add a listener to the always calculate hashes checkbox component.
// The listener passes the user's selection on to the hash database manager.
alwaysCalcHashesCheckbox.addActionListener( new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
HashDbManager.getInstance().setAlwaysCalculateHashes(alwaysCalcHashesCheckbox.isSelected());
}
});
load(); load();
hashDbManager.addPropertyChangeListener(this);
} }
private void customizeHashDbsTable(JScrollPane scrollPane, JTable table, HashDatabasesTableModel tableModel) { private void customizeHashDbsTable(JScrollPane scrollPane, JTable table, HashDatabasesTableModel tableModel) {
@ -85,16 +79,43 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
} }
} }
public void load() { @Override
public void propertyChange(PropertyChangeEvent event) {
if (event.getPropertyName().equals(HashDbManager.SetEvt.DB_ADDED.name()) ||
event.getPropertyName().equals(HashDbManager.SetEvt.DB_DELETED.name())) {
load();
}
}
@Override
public IngestModuleIngestJobSettings getSettings() {
List<String> enabledHashSets = new ArrayList<>();
List<HashDbManager.HashDb> knownFileHashSets = hashDbManager.getKnownFileHashSets();
for (HashDb db : knownFileHashSets) {
if (db.getSearchDuringIngest()) {
enabledHashSets.add(db.getHashSetName());
}
}
List<HashDbManager.HashDb> knownBadFileHashSets = hashDbManager.getKnownBadFileHashSets();
for (HashDb db : knownBadFileHashSets) {
if (db.getSearchDuringIngest()) {
enabledHashSets.add(db.getHashSetName());
}
}
return new HashLookupModuleSettings(alwaysCalcHashesCheckbox.isSelected(), enabledHashSets);
}
void load() {
knownTableModel.load(); knownTableModel.load();
knownBadTableModel.load(); knownBadTableModel.load();
} }
public void store() { void store() {
HashDbManager.getInstance().save(); hashDbManager.save();
} }
private class HashDatabasesTableModel extends AbstractTableModel { private class HashDatabasesTableModel extends AbstractTableModel {
private final HashDbManager.HashDb.KnownFilesType hashDatabasesType; private final HashDbManager.HashDb.KnownFilesType hashDatabasesType;
private List<HashDb> hashDatabases; private List<HashDb> hashDatabases;
@ -105,10 +126,9 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
private void getHashDatabases() { private void getHashDatabases() {
if (HashDbManager.HashDb.KnownFilesType.KNOWN == hashDatabasesType) { if (HashDbManager.HashDb.KnownFilesType.KNOWN == hashDatabasesType) {
hashDatabases = HashDbManager.getInstance().getKnownFileHashSets(); hashDatabases = hashDbManager.getKnownFileHashSets();
} } else {
else { hashDatabases = hashDbManager.getKnownBadFileHashSets();
hashDatabases = HashDbManager.getInstance().getKnownBadFileHashSets();
} }
} }
@ -144,22 +164,20 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
@Override @Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) { public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if(columnIndex == 0) { if (columnIndex == 0) {
HashDb db = hashDatabases.get(rowIndex); HashDb db = hashDatabases.get(rowIndex);
boolean dbHasIndex = false; boolean dbHasIndex = false;
try { try {
dbHasIndex = db.hasIndex(); dbHasIndex = db.hasIndex();
} catch (TskCoreException ex) {
Logger.getLogger(HashLookupModuleSettingsPanel.class.getName()).log(Level.SEVERE, "Error getting info for " + db.getHashSetName() + " hash database", ex);
} }
catch (TskCoreException ex) { if (((Boolean) getValueAt(rowIndex, columnIndex)) || dbHasIndex) {
Logger.getLogger(HashDbSimpleConfigPanel.class.getName()).log(Level.SEVERE, "Error getting info for " + db.getHashSetName() + " hash database", ex);
}
if(((Boolean) getValueAt(rowIndex, columnIndex)) || dbHasIndex) {
db.setSearchDuringIngest((Boolean) aValue); db.setSearchDuringIngest((Boolean) aValue);
} } else {
else { JOptionPane.showMessageDialog(HashLookupModuleSettingsPanel.this,
JOptionPane.showMessageDialog(HashDbSimpleConfigPanel.this, NbBundle.getMessage(this.getClass(),
NbBundle.getMessage(this.getClass(), "HashDbSimpleConfigPanel.dlgMsg.mustIndexDbBeforeUse"));
"HashDbSimpleConfigPanel.dlgMsg.mustIndexDbBeforeUse"));
} }
} }
} }
@ -170,10 +188,10 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
} }
} }
/** This method is called from within the constructor to /**
* initialize the form. * This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is * WARNING: Do NOT modify this code. The content of this method is always
* always regenerated by the Form Editor. * regenerated by the Form Editor.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
@ -194,11 +212,11 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
knownHashTable.setShowVerticalLines(false); knownHashTable.setShowVerticalLines(false);
jScrollPane1.setViewportView(knownHashTable); jScrollPane1.setViewportView(knownHashTable);
knownBadHashDbsLabel.setText(org.openide.util.NbBundle.getMessage(HashDbSimpleConfigPanel.class, "HashDbSimpleConfigPanel.knownBadHashDbsLabel.text")); // NOI18N knownBadHashDbsLabel.setText(org.openide.util.NbBundle.getMessage(HashLookupModuleSettingsPanel.class, "HashLookupModuleSettingsPanel.knownBadHashDbsLabel.text")); // NOI18N
knownHashDbsLabel.setText(org.openide.util.NbBundle.getMessage(HashDbSimpleConfigPanel.class, "HashDbSimpleConfigPanel.knownHashDbsLabel.text")); // NOI18N knownHashDbsLabel.setText(org.openide.util.NbBundle.getMessage(HashLookupModuleSettingsPanel.class, "HashLookupModuleSettingsPanel.knownHashDbsLabel.text")); // NOI18N
alwaysCalcHashesCheckbox.setText(org.openide.util.NbBundle.getMessage(HashDbSimpleConfigPanel.class, "HashDbSimpleConfigPanel.alwaysCalcHashesCheckbox.text")); // NOI18N alwaysCalcHashesCheckbox.setText(org.openide.util.NbBundle.getMessage(HashLookupModuleSettingsPanel.class, "HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.text")); // NOI18N
alwaysCalcHashesCheckbox.addActionListener(new java.awt.event.ActionListener() { alwaysCalcHashesCheckbox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
alwaysCalcHashesCheckboxActionPerformed(evt); alwaysCalcHashesCheckboxActionPerformed(evt);
@ -256,9 +274,8 @@ public class HashDbSimpleConfigPanel extends javax.swing.JPanel {
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void alwaysCalcHashesCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_alwaysCalcHashesCheckboxActionPerformed private void alwaysCalcHashesCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_alwaysCalcHashesCheckboxActionPerformed
// TODO add your handling code here: hashDbManager.setAlwaysCalculateHashes(alwaysCalcHashesCheckbox.isSelected());
}//GEN-LAST:event_alwaysCalcHashesCheckboxActionPerformed }//GEN-LAST:event_alwaysCalcHashesCheckboxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox alwaysCalcHashesCheckbox; private javax.swing.JCheckBox alwaysCalcHashesCheckbox;
private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane1;

View File

@ -5,21 +5,21 @@
<Component class="javax.swing.JLabel" name="jLabel2"> <Component class="javax.swing.JLabel" name="jLabel2">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="jLabel4"> <Component class="javax.swing.JLabel" name="jLabel4">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.jLabel4.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.jLabel4.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="jLabel6"> <Component class="javax.swing.JLabel" name="jLabel6">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.jLabel6.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.jLabel6.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
@ -29,7 +29,7 @@
<Font name="Tahoma" size="14" style="0"/> <Font name="Tahoma" size="14" style="0"/>
</Property> </Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.jButton3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.jButton3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
@ -206,7 +206,7 @@
<Image iconType="3" name="/org/sleuthkit/autopsy/hashdatabase/warning16.png"/> <Image iconType="3" name="/org/sleuthkit/autopsy/hashdatabase/warning16.png"/>
</Property> </Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.ingestWarningLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.ingestWarningLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
@ -246,7 +246,7 @@
<Image iconType="3" name="/org/sleuthkit/autopsy/hashdatabase/delete16.png"/> <Image iconType="3" name="/org/sleuthkit/autopsy/hashdatabase/delete16.png"/>
</Property> </Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.deleteDatabaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.deleteDatabaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[140, 25]"/> <Dimension value="[140, 25]"/>
@ -268,7 +268,7 @@
<Image iconType="3" name="/org/sleuthkit/autopsy/hashdatabase/import16.png"/> <Image iconType="3" name="/org/sleuthkit/autopsy/hashdatabase/import16.png"/>
</Property> </Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.importDatabaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.importDatabaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[140, 25]"/> <Dimension value="[140, 25]"/>
@ -287,70 +287,70 @@
<Component class="javax.swing.JLabel" name="hashDatabasesLabel"> <Component class="javax.swing.JLabel" name="hashDatabasesLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.hashDatabasesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.hashDatabasesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="nameLabel"> <Component class="javax.swing.JLabel" name="nameLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.nameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.nameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="hashDbNameLabel"> <Component class="javax.swing.JLabel" name="hashDbNameLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.hashDbNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.hashDbNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="hashDbLocationLabel"> <Component class="javax.swing.JLabel" name="hashDbLocationLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.hashDbLocationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.hashDbLocationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="locationLabel"> <Component class="javax.swing.JLabel" name="locationLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.locationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.locationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="typeLabel"> <Component class="javax.swing.JLabel" name="typeLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.typeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.typeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="hashDbTypeLabel"> <Component class="javax.swing.JLabel" name="hashDbTypeLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.hashDbTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.hashDbTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="hashDbIndexStatusLabel"> <Component class="javax.swing.JLabel" name="hashDbIndexStatusLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.hashDbIndexStatusLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.hashDbIndexStatusLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="indexLabel"> <Component class="javax.swing.JLabel" name="indexLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.indexLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.indexLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JButton" name="indexButton"> <Component class="javax.swing.JButton" name="indexButton">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.indexButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.indexButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="enabled" type="boolean" value="false"/> <Property name="enabled" type="boolean" value="false"/>
</Properties> </Properties>
@ -361,7 +361,7 @@
<Component class="javax.swing.JCheckBox" name="sendIngestMessagesCheckBox"> <Component class="javax.swing.JCheckBox" name="sendIngestMessagesCheckBox">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.sendIngestMessagesCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.sendIngestMessagesCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>
@ -371,14 +371,14 @@
<Component class="javax.swing.JLabel" name="informationLabel"> <Component class="javax.swing.JLabel" name="informationLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.informationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.informationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="optionsLabel"> <Component class="javax.swing.JLabel" name="optionsLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.optionsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.optionsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
@ -392,7 +392,7 @@
<Image iconType="3" name="/org/sleuthkit/autopsy/hashdatabase/new16.png"/> <Image iconType="3" name="/org/sleuthkit/autopsy/hashdatabase/new16.png"/>
</Property> </Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.createDatabaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.createDatabaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[140, 25]"/> <Dimension value="[140, 25]"/>
@ -411,14 +411,14 @@
<Component class="javax.swing.JLabel" name="indexPathLabelLabel"> <Component class="javax.swing.JLabel" name="indexPathLabelLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.indexPathLabelLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.indexPathLabelLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="indexPathLabel"> <Component class="javax.swing.JLabel" name="indexPathLabel">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbConfigPanel.indexPathLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashLookupSettingsPanel.indexPathLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
</Component> </Component>

View File

@ -44,21 +44,24 @@ import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb; import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb;
import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb.KnownFilesType; import org.sleuthkit.autopsy.hashdatabase.HashDbManager.HashDb.KnownFilesType;
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSetttingsPanel;
/** /**
* Instances of this class provide a comprehensive UI for managing the hash sets configuration. * Instances of this class provide a comprehensive UI for managing the hash sets
* configuration.
*/ */
public final class HashDbConfigPanel extends javax.swing.JPanel implements OptionsPanel { public final class HashLookupSettingsPanel extends IngestModuleGlobalSetttingsPanel implements OptionsPanel {
private static final String NO_SELECTION_TEXT = NbBundle private static final String NO_SELECTION_TEXT = NbBundle
.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.noSelectionText"); .getMessage(HashLookupSettingsPanel.class, "HashDbConfigPanel.noSelectionText");
private static final String ERROR_GETTING_PATH_TEXT = NbBundle private static final String ERROR_GETTING_PATH_TEXT = NbBundle
.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.errorGettingPathText"); .getMessage(HashLookupSettingsPanel.class, "HashDbConfigPanel.errorGettingPathText");
private static final String ERROR_GETTING_INDEX_STATUS_TEXT = NbBundle private static final String ERROR_GETTING_INDEX_STATUS_TEXT = NbBundle
.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.errorGettingIndexStatusText"); .getMessage(HashLookupSettingsPanel.class, "HashDbConfigPanel.errorGettingIndexStatusText");
private HashDbManager hashSetManager = HashDbManager.getInstance(); private HashDbManager hashSetManager = HashDbManager.getInstance();
private HashSetTableModel hashSetTableModel = new HashSetTableModel(); private HashSetTableModel hashSetTableModel = new HashSetTableModel();
public HashDbConfigPanel() { public HashLookupSettingsPanel() {
initComponents(); initComponents();
customizeComponents(); customizeComponents();
updateComponentsForNoSelection(); updateComponentsForNoSelection();
@ -93,11 +96,10 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
} }
private void updateComponents() { private void updateComponents() {
HashDb db = ((HashSetTable)hashSetTable).getSelection(); HashDb db = ((HashSetTable) hashSetTable).getSelection();
if (db != null) { if (db != null) {
updateComponentsForSelection(db); updateComponentsForSelection(db);
} } else {
else {
updateComponentsForNoSelection(); updateComponentsForNoSelection();
} }
} }
@ -141,17 +143,15 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
try { try {
hashDbLocationLabel.setText(shortenPath(db.getDatabasePath())); hashDbLocationLabel.setText(shortenPath(db.getDatabasePath()));
} } catch (TskCoreException ex) {
catch (TskCoreException ex) { Logger.getLogger(HashLookupSettingsPanel.class.getName()).log(Level.SEVERE, "Error getting database path of " + db.getHashSetName() + " hash database", ex);
Logger.getLogger(HashDbConfigPanel.class.getName()).log(Level.SEVERE, "Error getting database path of " + db.getHashSetName() + " hash database", ex);
hashDbLocationLabel.setText(ERROR_GETTING_PATH_TEXT); hashDbLocationLabel.setText(ERROR_GETTING_PATH_TEXT);
} }
try { try {
indexPathLabel.setText(shortenPath(db.getIndexPath())); indexPathLabel.setText(shortenPath(db.getIndexPath()));
} } catch (TskCoreException ex) {
catch (TskCoreException ex) { Logger.getLogger(HashLookupSettingsPanel.class.getName()).log(Level.SEVERE, "Error getting index path of " + db.getHashSetName() + " hash database", ex);
Logger.getLogger(HashDbConfigPanel.class.getName()).log(Level.SEVERE, "Error getting index path of " + db.getHashSetName() + " hash database", ex);
indexPathLabel.setText(ERROR_GETTING_PATH_TEXT); indexPathLabel.setText(ERROR_GETTING_PATH_TEXT);
} }
@ -164,13 +164,11 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexStatusText.indexGen")); NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexStatusText.indexGen"));
hashDbIndexStatusLabel.setForeground(Color.black); hashDbIndexStatusLabel.setForeground(Color.black);
indexButton.setEnabled(false); indexButton.setEnabled(false);
} } else if (db.hasIndex()) {
else if (db.hasIndex()) {
if (db.hasIndexOnly()) { if (db.hasIndexOnly()) {
hashDbIndexStatusLabel.setText( hashDbIndexStatusLabel.setText(
NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexStatusText.indexOnly")); NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexStatusText.indexOnly"));
} } else {
else {
hashDbIndexStatusLabel.setText( hashDbIndexStatusLabel.setText(
NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexStatusText.indexed")); NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexStatusText.indexed"));
} }
@ -179,22 +177,19 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
indexButton.setText( indexButton.setText(
NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexButtonText.reIndex")); NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexButtonText.reIndex"));
indexButton.setEnabled(true); indexButton.setEnabled(true);
} } else {
else {
indexButton.setText(NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexButtonText.index")); indexButton.setText(NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexButtonText.index"));
indexButton.setEnabled(false); indexButton.setEnabled(false);
} }
} } else {
else {
hashDbIndexStatusLabel.setText( hashDbIndexStatusLabel.setText(
NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexStatusText.noIndex")); NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexStatusText.noIndex"));
hashDbIndexStatusLabel.setForeground(Color.red); hashDbIndexStatusLabel.setForeground(Color.red);
indexButton.setText(NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexButtonText.index")); indexButton.setText(NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexButtonText.index"));
indexButton.setEnabled(true); indexButton.setEnabled(true);
} }
} } catch (TskCoreException ex) {
catch (TskCoreException ex) { Logger.getLogger(HashLookupSettingsPanel.class.getName()).log(Level.SEVERE, "Error getting index state of hash database", ex);
Logger.getLogger(HashDbConfigPanel.class.getName()).log(Level.SEVERE, "Error getting index state of hash database", ex);
hashDbIndexStatusLabel.setText(ERROR_GETTING_INDEX_STATUS_TEXT); hashDbIndexStatusLabel.setText(ERROR_GETTING_INDEX_STATUS_TEXT);
hashDbIndexStatusLabel.setForeground(Color.red); hashDbIndexStatusLabel.setForeground(Color.red);
indexButton.setText(NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexButtonText.index")); indexButton.setText(NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.indexButtonText.index"));
@ -223,14 +218,38 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
private static String shortenPath(String path) { private static String shortenPath(String path) {
String shortenedPath = path; String shortenedPath = path;
if (shortenedPath.length() > 50){ if (shortenedPath.length() > 50) {
shortenedPath = shortenedPath.substring(0, 10 + shortenedPath.substring(10).indexOf(File.separator) + 1) + "..." + shortenedPath.substring((shortenedPath.length() - 20) + shortenedPath.substring(shortenedPath.length() - 20).indexOf(File.separator)); shortenedPath = shortenedPath.substring(0, 10 + shortenedPath.substring(10).indexOf(File.separator) + 1) + "..." + shortenedPath.substring((shortenedPath.length() - 20) + shortenedPath.substring(shortenedPath.length() - 20).indexOf(File.separator));
} }
return shortenedPath; return shortenedPath;
} }
private boolean isFileIngestStatusChangeEvent(PropertyChangeEvent evt) { private boolean isFileIngestStatusChangeEvent(PropertyChangeEvent evt) {
return evt.getPropertyName().equals(IngestManager.IngestModuleEvent.STARTED.toString()) || evt.getPropertyName().equals(IngestManager.IngestModuleEvent.COMPLETED.toString()) || evt.getPropertyName().equals(IngestManager.IngestModuleEvent.STOPPED.toString()); return evt.getPropertyName().equals(IngestManager.IngestEvent.STARTED.toString()) || evt.getPropertyName().equals(IngestManager.IngestEvent.COMPLETED.toString()) || evt.getPropertyName().equals(IngestManager.IngestEvent.STOPPED.toString());
}
@Override
public void saveSettings() {
//Checking for for any unindexed databases
List<HashDb> unindexed = new ArrayList<>();
for (HashDb hashSet : hashSetManager.getAllHashSets()) {
try {
if (!hashSet.hasIndex()) {
unindexed.add(hashSet);
}
} catch (TskCoreException ex) {
Logger.getLogger(HashLookupSettingsPanel.class.getName()).log(Level.SEVERE, "Error getting index info for hash database", ex);
}
}
//If unindexed ones are found, show a popup box that will either index them, or remove them.
if (unindexed.size() == 1) {
showInvalidIndex(false, unindexed);
} else if (unindexed.size() > 1) {
showInvalidIndex(true, unindexed);
}
hashSetManager.save();
} }
@Override @Override
@ -241,28 +260,7 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
@Override @Override
public void store() { public void store() {
//Checking for for any unindexed databases saveSettings();
List<HashDb> unindexed = new ArrayList<>();
for (HashDb hashSet : hashSetManager.getAllHashSets()) {
try {
if (!hashSet.hasIndex()) {
unindexed.add(hashSet);
}
}
catch (TskCoreException ex) {
Logger.getLogger(HashDbConfigPanel.class.getName()).log(Level.SEVERE, "Error getting index info for hash database", ex);
}
}
//If unindexed ones are found, show a popup box that will either index them, or remove them.
if (unindexed.size() == 1){
showInvalidIndex(false, unindexed);
}
else if (unindexed.size() > 1){
showInvalidIndex(true, unindexed);
}
hashSetManager.save();
} }
public void cancel() { public void cancel() {
@ -277,37 +275,38 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
} }
/** /**
* Displays the popup box that tells user that some of his databases are unindexed, along with solutions. * Displays the popup box that tells user that some of his databases are
* This method is related to ModalNoButtons, to be removed at a later date. * unindexed, along with solutions. This method is related to
* ModalNoButtons, to be removed at a later date.
*
* @param plural Whether or not there are multiple unindexed databases * @param plural Whether or not there are multiple unindexed databases
* @param unindexed The list of unindexed databases. Can be of size 1. * @param unindexed The list of unindexed databases. Can be of size 1.
*/ */
private void showInvalidIndex(boolean plural, List<HashDb> unindexed){ private void showInvalidIndex(boolean plural, List<HashDb> unindexed) {
String total = ""; String total = "";
String message; String message;
for(HashDb hdb : unindexed){ for (HashDb hdb : unindexed) {
total+= "\n" + hdb.getHashSetName(); total += "\n" + hdb.getHashSetName();
} }
if(plural){ if (plural) {
message = NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.dbsNotIndexedMsg", total); message = NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.dbsNotIndexedMsg", total);
} } else {
else{
message = NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.dbNotIndexedMsg", total); message = NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.dbNotIndexedMsg", total);
} }
int res = JOptionPane.showConfirmDialog(this, message, int res = JOptionPane.showConfirmDialog(this, message,
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"HashDbConfigPanel.unindexedDbsMsg"), "HashDbConfigPanel.unindexedDbsMsg"),
JOptionPane.YES_NO_OPTION); JOptionPane.YES_NO_OPTION);
if(res == JOptionPane.YES_OPTION){ if (res == JOptionPane.YES_OPTION) {
ModalNoButtons indexingDialog = new ModalNoButtons(this, new Frame(),unindexed); ModalNoButtons indexingDialog = new ModalNoButtons(this, new Frame(), unindexed);
indexingDialog.setLocationRelativeTo(null); indexingDialog.setLocationRelativeTo(null);
indexingDialog.setVisible(true); indexingDialog.setVisible(true);
indexingDialog.setModal(true); indexingDialog.setModal(true);
hashSetTableModel.refreshModel(); hashSetTableModel.refreshModel();
} }
if(res == JOptionPane.NO_OPTION){ if (res == JOptionPane.NO_OPTION) {
JOptionPane.showMessageDialog(this, NbBundle.getMessage(this.getClass(), JOptionPane.showMessageDialog(this, NbBundle.getMessage(this.getClass(),
"HashDbConfigPanel.allUnindexedDbsRmFromListMsg")); "HashDbConfigPanel.allUnindexedDbsRmFromListMsg"));
removeThese(unindexed); removeThese(unindexed);
} }
} }
@ -320,19 +319,19 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
* This class implements a table for displaying configured hash sets. * This class implements a table for displaying configured hash sets.
*/ */
private class HashSetTable extends JTable { private class HashSetTable extends JTable {
@Override @Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
// Use the hash set name as the cell text. // Use the hash set name as the cell text.
JComponent cellRenderer = (JComponent)super.prepareRenderer(renderer, row, column); JComponent cellRenderer = (JComponent) super.prepareRenderer(renderer, row, column);
cellRenderer.setToolTipText((String)getValueAt(row, column)); cellRenderer.setToolTipText((String) getValueAt(row, column));
// Give the user a visual indication of any hash sets with a hash // Give the user a visual indication of any hash sets with a hash
// database that needs to be indexed by displaying the hash set name // database that needs to be indexed by displaying the hash set name
// in red. // in red.
if (hashSetTableModel.indexExists(row)){ if (hashSetTableModel.indexExists(row)) {
cellRenderer.setForeground(Color.black); cellRenderer.setForeground(Color.black);
} } else {
else{
cellRenderer.setForeground(Color.red); cellRenderer.setForeground(Color.red);
} }
@ -359,6 +358,7 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
* configured hash sets. * configured hash sets.
*/ */
private class HashSetTableModel extends AbstractTableModel { private class HashSetTableModel extends AbstractTableModel {
List<HashDb> hashSets = HashDbManager.getInstance().getAllHashSets(); List<HashDb> hashSets = HashDbManager.getInstance().getAllHashSets();
@Override @Override
@ -381,11 +381,10 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
return hashSets.get(rowIndex).getHashSetName(); return hashSets.get(rowIndex).getHashSetName();
} }
private boolean indexExists(int rowIndex){ private boolean indexExists(int rowIndex) {
try { try {
return hashSets.get(rowIndex).hasIndex(); return hashSets.get(rowIndex).hasIndex();
} } catch (TskCoreException ex) {
catch (TskCoreException ex) {
Logger.getLogger(HashSetTableModel.class.getName()).log(Level.SEVERE, "Error getting index info for hash database", ex); Logger.getLogger(HashSetTableModel.class.getName()).log(Level.SEVERE, "Error getting index info for hash database", ex);
return false; return false;
} }
@ -410,8 +409,7 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
HashDb getHashSetAt(int index) { HashDb getHashSetAt(int index) {
if (!hashSets.isEmpty() && index >= 0 && index < hashSets.size()) { if (!hashSets.isEmpty() && index >= 0 && index < hashSets.size()) {
return hashSets.get(index); return hashSets.get(index);
} } else {
else {
return null; return null;
} }
} }
@ -471,20 +469,20 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
indexPathLabelLabel = new javax.swing.JLabel(); indexPathLabelLabel = new javax.swing.JLabel();
indexPathLabel = new javax.swing.JLabel(); indexPathLabel = new javax.swing.JLabel();
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.jLabel2.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.jLabel2.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jLabel4, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.jLabel4.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(jLabel4, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.jLabel4.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jLabel6, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.jLabel6.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(jLabel6, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.jLabel6.text")); // NOI18N
jButton3.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N jButton3.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jButton3, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.jButton3.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(jButton3, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.jButton3.text")); // NOI18N
setMinimumSize(new java.awt.Dimension(700, 500)); setMinimumSize(new java.awt.Dimension(700, 500));
setPreferredSize(new java.awt.Dimension(700, 500)); setPreferredSize(new java.awt.Dimension(700, 500));
ingestWarningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/hashdatabase/warning16.png"))); // NOI18N ingestWarningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/hashdatabase/warning16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(ingestWarningLabel, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.ingestWarningLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(ingestWarningLabel, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.ingestWarningLabel.text")); // NOI18N
hashSetTable.setModel(new javax.swing.table.DefaultTableModel( hashSetTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] { new Object [][] {
@ -504,7 +502,7 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
jScrollPane1.setViewportView(hashSetTable); jScrollPane1.setViewportView(hashSetTable);
deleteDatabaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/hashdatabase/delete16.png"))); // NOI18N deleteDatabaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/hashdatabase/delete16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(deleteDatabaseButton, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.deleteDatabaseButton.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(deleteDatabaseButton, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.deleteDatabaseButton.text")); // NOI18N
deleteDatabaseButton.setMaximumSize(new java.awt.Dimension(140, 25)); deleteDatabaseButton.setMaximumSize(new java.awt.Dimension(140, 25));
deleteDatabaseButton.setMinimumSize(new java.awt.Dimension(140, 25)); deleteDatabaseButton.setMinimumSize(new java.awt.Dimension(140, 25));
deleteDatabaseButton.setPreferredSize(new java.awt.Dimension(140, 25)); deleteDatabaseButton.setPreferredSize(new java.awt.Dimension(140, 25));
@ -515,7 +513,7 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
}); });
importDatabaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/hashdatabase/import16.png"))); // NOI18N importDatabaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/hashdatabase/import16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(importDatabaseButton, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.importDatabaseButton.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(importDatabaseButton, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.importDatabaseButton.text")); // NOI18N
importDatabaseButton.setMaximumSize(new java.awt.Dimension(140, 25)); importDatabaseButton.setMaximumSize(new java.awt.Dimension(140, 25));
importDatabaseButton.setMinimumSize(new java.awt.Dimension(140, 25)); importDatabaseButton.setMinimumSize(new java.awt.Dimension(140, 25));
importDatabaseButton.setPreferredSize(new java.awt.Dimension(140, 25)); importDatabaseButton.setPreferredSize(new java.awt.Dimension(140, 25));
@ -525,25 +523,25 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
} }
}); });
org.openide.awt.Mnemonics.setLocalizedText(hashDatabasesLabel, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.hashDatabasesLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(hashDatabasesLabel, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.hashDatabasesLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(nameLabel, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.nameLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(nameLabel, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.nameLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(hashDbNameLabel, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.hashDbNameLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(hashDbNameLabel, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.hashDbNameLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(hashDbLocationLabel, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.hashDbLocationLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(hashDbLocationLabel, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.hashDbLocationLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(locationLabel, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.locationLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(locationLabel, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.locationLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(typeLabel, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.typeLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(typeLabel, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.typeLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(hashDbTypeLabel, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.hashDbTypeLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(hashDbTypeLabel, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.hashDbTypeLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(hashDbIndexStatusLabel, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.hashDbIndexStatusLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(hashDbIndexStatusLabel, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.hashDbIndexStatusLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(indexLabel, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.indexLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(indexLabel, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.indexLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(indexButton, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.indexButton.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(indexButton, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.indexButton.text")); // NOI18N
indexButton.setEnabled(false); indexButton.setEnabled(false);
indexButton.addActionListener(new java.awt.event.ActionListener() { indexButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -551,19 +549,19 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
} }
}); });
org.openide.awt.Mnemonics.setLocalizedText(sendIngestMessagesCheckBox, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.sendIngestMessagesCheckBox.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(sendIngestMessagesCheckBox, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.sendIngestMessagesCheckBox.text")); // NOI18N
sendIngestMessagesCheckBox.addActionListener(new java.awt.event.ActionListener() { sendIngestMessagesCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
sendIngestMessagesCheckBoxActionPerformed(evt); sendIngestMessagesCheckBoxActionPerformed(evt);
} }
}); });
org.openide.awt.Mnemonics.setLocalizedText(informationLabel, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.informationLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(informationLabel, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.informationLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(optionsLabel, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.optionsLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(optionsLabel, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.optionsLabel.text")); // NOI18N
createDatabaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/hashdatabase/new16.png"))); // NOI18N createDatabaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/hashdatabase/new16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(createDatabaseButton, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.createDatabaseButton.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(createDatabaseButton, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.createDatabaseButton.text")); // NOI18N
createDatabaseButton.setMaximumSize(new java.awt.Dimension(140, 25)); createDatabaseButton.setMaximumSize(new java.awt.Dimension(140, 25));
createDatabaseButton.setMinimumSize(new java.awt.Dimension(140, 25)); createDatabaseButton.setMinimumSize(new java.awt.Dimension(140, 25));
createDatabaseButton.setPreferredSize(new java.awt.Dimension(140, 25)); createDatabaseButton.setPreferredSize(new java.awt.Dimension(140, 25));
@ -573,9 +571,9 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
} }
}); });
org.openide.awt.Mnemonics.setLocalizedText(indexPathLabelLabel, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.indexPathLabelLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(indexPathLabelLabel, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.indexPathLabelLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(indexPathLabel, org.openide.util.NbBundle.getMessage(HashDbConfigPanel.class, "HashDbConfigPanel.indexPathLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(indexPathLabel, org.openide.util.NbBundle.getMessage(HashLookupSettingsPanel.class, "HashLookupSettingsPanel.indexPathLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
@ -692,7 +690,7 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void indexButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_indexButtonActionPerformed private void indexButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_indexButtonActionPerformed
final HashDb hashDb = ((HashSetTable)hashSetTable).getSelection(); final HashDb hashDb = ((HashSetTable) hashSetTable).getSelection();
assert hashDb != null; assert hashDb != null;
// Add a listener for the INDEXING_DONE event. This listener will update // Add a listener for the INDEXING_DONE event. This listener will update
@ -701,7 +699,7 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
@Override @Override
public void propertyChange(PropertyChangeEvent evt) { public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(HashDb.Event.INDEXING_DONE.toString())) { if (evt.getPropertyName().equals(HashDb.Event.INDEXING_DONE.toString())) {
HashDb selectedHashDb = ((HashSetTable)hashSetTable).getSelection(); HashDb selectedHashDb = ((HashSetTable) hashSetTable).getSelection();
if (selectedHashDb != null && hashDb != null && hashDb.equals(selectedHashDb)) { if (selectedHashDb != null && hashDb != null && hashDb.equals(selectedHashDb)) {
updateComponents(); updateComponents();
} }
@ -723,12 +721,12 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
private void deleteDatabaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteDatabaseButtonActionPerformed private void deleteDatabaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteDatabaseButtonActionPerformed
if (JOptionPane.showConfirmDialog(null, if (JOptionPane.showConfirmDialog(null,
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"HashDbConfigPanel.deleteDbActionConfirmMsg"), "HashDbConfigPanel.deleteDbActionConfirmMsg"),
NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.deleteDbActionMsg"), NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.deleteDbActionMsg"),
JOptionPane.YES_NO_OPTION, JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) { JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) {
HashDb hashDb = ((HashSetTable)hashSetTable).getSelection(); HashDb hashDb = ((HashSetTable) hashSetTable).getSelection();
if (hashDb != null) { if (hashDb != null) {
hashSetManager.removeHashDatabaseInternal(hashDb); hashSetManager.removeHashDatabaseInternal(hashDb);
hashSetTableModel.refreshModel(); hashSetTableModel.refreshModel();
@ -738,7 +736,7 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
private void hashSetTableKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_hashSetTableKeyPressed private void hashSetTableKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_hashSetTableKeyPressed
if (evt.getKeyCode() == KeyEvent.VK_DELETE) { if (evt.getKeyCode() == KeyEvent.VK_DELETE) {
HashDb hashDb = ((HashSetTable)hashSetTable).getSelection(); HashDb hashDb = ((HashSetTable) hashSetTable).getSelection();
if (hashDb != null) { if (hashDb != null) {
hashSetManager.removeHashDatabaseInternal(hashDb); hashSetManager.removeHashDatabaseInternal(hashDb);
hashSetTableModel.refreshModel(); hashSetTableModel.refreshModel();
@ -747,7 +745,7 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
}//GEN-LAST:event_hashSetTableKeyPressed }//GEN-LAST:event_hashSetTableKeyPressed
private void sendIngestMessagesCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sendIngestMessagesCheckBoxActionPerformed private void sendIngestMessagesCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sendIngestMessagesCheckBoxActionPerformed
HashDb hashDb = ((HashSetTable)hashSetTable).getSelection(); HashDb hashDb = ((HashSetTable) hashSetTable).getSelection();
if (hashDb != null) { if (hashDb != null) {
hashDb.setSendIngestMessages(sendIngestMessagesCheckBox.isSelected()); hashDb.setSendIngestMessages(sendIngestMessagesCheckBox.isSelected());
} }
@ -757,7 +755,7 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
HashDb hashDb = new HashDbImportDatabaseDialog().getHashDatabase(); HashDb hashDb = new HashDbImportDatabaseDialog().getHashDatabase();
if (null != hashDb) { if (null != hashDb) {
hashSetTableModel.refreshModel(); hashSetTableModel.refreshModel();
((HashSetTable)hashSetTable).selectRowByName(hashDb.getHashSetName()); ((HashSetTable) hashSetTable).selectRowByName(hashDb.getHashSetName());
} }
}//GEN-LAST:event_importDatabaseButtonActionPerformed }//GEN-LAST:event_importDatabaseButtonActionPerformed
@ -765,10 +763,9 @@ public final class HashDbConfigPanel extends javax.swing.JPanel implements Optio
HashDb hashDb = new HashDbCreateDatabaseDialog().getHashDatabase(); HashDb hashDb = new HashDbCreateDatabaseDialog().getHashDatabase();
if (null != hashDb) { if (null != hashDb) {
hashSetTableModel.refreshModel(); hashSetTableModel.refreshModel();
((HashSetTable)hashSetTable).selectRowByName(hashDb.getHashSetName()); ((HashSetTable) hashSetTable).selectRowByName(hashDb.getHashSetName());
} }
}//GEN-LAST:event_createDatabaseButtonActionPerformed }//GEN-LAST:event_createDatabaseButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton createDatabaseButton; private javax.swing.JButton createDatabaseButton;
private javax.swing.JButton deleteDatabaseButton; private javax.swing.JButton deleteDatabaseButton;

View File

@ -42,7 +42,7 @@ class ModalNoButtons extends javax.swing.JDialog implements PropertyChangeListen
List<HashDb> unindexed; List<HashDb> unindexed;
HashDb toIndex; HashDb toIndex;
HashDbConfigPanel hdbmp; HashLookupSettingsPanel hdbmp;
int length = 0; int length = 0;
int currentcount = 1; int currentcount = 1;
String currentDb = ""; String currentDb = "";
@ -53,7 +53,7 @@ class ModalNoButtons extends javax.swing.JDialog implements PropertyChangeListen
* @param parent Swing parent frame. * @param parent Swing parent frame.
* @param unindexed the list of unindexed databases to index. * @param unindexed the list of unindexed databases to index.
*/ */
ModalNoButtons(HashDbConfigPanel hdbmp, java.awt.Frame parent, List<HashDb> unindexed) { ModalNoButtons(HashLookupSettingsPanel hdbmp, java.awt.Frame parent, List<HashDb> unindexed) {
super(parent, NbBundle.getMessage(ModalNoButtons.class, "ModalNoButtons.indexingDbsTitle"), true); super(parent, NbBundle.getMessage(ModalNoButtons.class, "ModalNoButtons.indexingDbsTitle"), true);
this.unindexed = unindexed; this.unindexed = unindexed;
this.toIndex = null; this.toIndex = null;
@ -68,7 +68,7 @@ class ModalNoButtons extends javax.swing.JDialog implements PropertyChangeListen
* @param parent Swing parent frame. * @param parent Swing parent frame.
* @param unindexed The unindexed database to index. * @param unindexed The unindexed database to index.
*/ */
ModalNoButtons(HashDbConfigPanel hdbmp, java.awt.Frame parent, HashDb unindexed){ ModalNoButtons(HashLookupSettingsPanel hdbmp, java.awt.Frame parent, HashDb unindexed){
super(parent, NbBundle.getMessage(ModalNoButtons.class, "ModalNoButtons.indexingDbTitle"), true); super(parent, NbBundle.getMessage(ModalNoButtons.class, "ModalNoButtons.indexingDbTitle"), true);
this.unindexed = null; this.unindexed = null;
this.toIndex = unindexed; this.toIndex = unindexed;

View File

@ -61,8 +61,8 @@ import org.sleuthkit.datamodel.ReadContentInputStream;
//"application/xml-dtd", //"application/xml-dtd",
); );
AbstractFileHtmlExtract() { AbstractFileHtmlExtract(KeywordSearchIngestModule module) {
this.module = KeywordSearchIngestModule.getDefault(); this.module = module;
ingester = Server.getIngester(); ingester = Server.getIngester();
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -60,8 +60,8 @@ class AbstractFileStringExtract implements AbstractFileExtract {
//STRING_CHUNK_BUF[1] = (byte) 0xBB; //STRING_CHUNK_BUF[1] = (byte) 0xBB;
//STRING_CHUNK_BUF[2] = (byte) 0xBF; //STRING_CHUNK_BUF[2] = (byte) 0xBF;
//} //}
public AbstractFileStringExtract() { public AbstractFileStringExtract(KeywordSearchIngestModule module) {
this.module = KeywordSearchIngestModule.getDefault(); this.module = module;
this.ingester = Server.getIngester(); this.ingester = Server.getIngester();
this.extractScripts.add(DEFAULT_SCRIPT); this.extractScripts.add(DEFAULT_SCRIPT);
} }

View File

@ -35,7 +35,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.logging.Level; import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.ReadContentInputStream; import org.sleuthkit.datamodel.ReadContentInputStream;
import org.apache.tika.Tika; import org.apache.tika.Tika;
@ -57,7 +56,7 @@ import org.sleuthkit.autopsy.keywordsearch.Ingester.IngesterException;
*/ */
class AbstractFileTikaTextExtract implements AbstractFileExtract { class AbstractFileTikaTextExtract implements AbstractFileExtract {
private static final Logger logger = Logger.getLogger(IngestModuleAbstractFile.class.getName()); private static final Logger logger = Logger.getLogger(AbstractFileTikaTextExtract.class.getName());
private static final Charset OUTPUT_CHARSET = Server.DEFAULT_INDEXED_TEXT_CHARSET; private static final Charset OUTPUT_CHARSET = Server.DEFAULT_INDEXED_TEXT_CHARSET;
static final int MAX_EXTR_TEXT_CHARS = 512 * 1024; static final int MAX_EXTR_TEXT_CHARS = 512 * 1024;
private static final int SINGLE_READ_CHARS = 1024; private static final int SINGLE_READ_CHARS = 1024;
@ -72,8 +71,8 @@ class AbstractFileTikaTextExtract implements AbstractFileExtract {
private final ExecutorService tikaParseExecutor = Executors.newSingleThreadExecutor(); private final ExecutorService tikaParseExecutor = Executors.newSingleThreadExecutor();
private final List<String> TIKA_SUPPORTED_TYPES = new ArrayList<>(); private final List<String> TIKA_SUPPORTED_TYPES = new ArrayList<>();
AbstractFileTikaTextExtract() { AbstractFileTikaTextExtract(KeywordSearchIngestModule module) {
this.module = KeywordSearchIngestModule.getDefault(); this.module = module;
ingester = Server.getIngester(); ingester = Server.getIngester();
Set<MediaType> mediaTypes = new Tika().getParser().getSupportedTypes(new ParseContext()); Set<MediaType> mediaTypes = new Tika().getParser().getSupportedTypes(new ParseContext());

View File

@ -86,10 +86,10 @@ abstract class AbstractKeywordSearchPerformer extends javax.swing.JPanel impleme
@Override @Override
public void search() { public void search() {
boolean isRunning = IngestManager.getDefault().isModuleRunning(KeywordSearchIngestModule.getDefault()); boolean isIngestRunning = IngestManager.getDefault().isIngestRunning();
if (filesIndexed == 0) { if (filesIndexed == 0) {
if (isRunning) { if (isIngestRunning) {
KeywordSearchUtil.displayDialog(keywordSearchErrorDialogHeader, NbBundle.getMessage(this.getClass(), KeywordSearchUtil.displayDialog(keywordSearchErrorDialogHeader, NbBundle.getMessage(this.getClass(),
"AbstractKeywordSearchPerformer.search.noFilesInIdxMsg", "AbstractKeywordSearchPerformer.search.noFilesInIdxMsg",
KeywordSearchSettings.getUpdateFrequency().getTime()), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR); KeywordSearchSettings.getUpdateFrequency().getTime()), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
@ -101,7 +101,7 @@ abstract class AbstractKeywordSearchPerformer extends javax.swing.JPanel impleme
} }
//check if keyword search module ingest is running (indexing, etc) //check if keyword search module ingest is running (indexing, etc)
if (isRunning) { if (isIngestRunning) {
if (KeywordSearchUtil.displayConfirmDialog(org.openide.util.NbBundle.getMessage(this.getClass(), "AbstractKeywordSearchPerformer.search.searchIngestInProgressTitle"), if (KeywordSearchUtil.displayConfirmDialog(org.openide.util.NbBundle.getMessage(this.getClass(), "AbstractKeywordSearchPerformer.search.searchIngestInProgressTitle"),
NbBundle.getMessage(this.getClass(), "AbstractKeywordSearchPerformer.search.ingestInProgressBody"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN) == false) { NbBundle.getMessage(this.getClass(), "AbstractKeywordSearchPerformer.search.ingestInProgressBody"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN) == false) {
return; return;

View File

@ -52,10 +52,6 @@ KeywordSearchConfigurationPanel2.skipNSRLCheckBox.text=Do not add files in NSRL
KeywordSearchConfigurationPanel2.skipNSRLCheckBox.toolTipText=Requires Hash DB service to had run previously, or be selected for next ingest. KeywordSearchConfigurationPanel2.skipNSRLCheckBox.toolTipText=Requires Hash DB service to had run previously, or be selected for next ingest.
KeywordSearchConfigurationPanel2.filesIndexedValue.text=- KeywordSearchConfigurationPanel2.filesIndexedValue.text=-
KeywordSearchConfigurationPanel2.filesIndexedLabel.text=Files in keyword index: KeywordSearchConfigurationPanel2.filesIndexedLabel.text=Files in keyword index:
KeywordSearchIngestSimplePanel.languagesLabel.text=Scripts enabled for string extraction from unknown file types:
KeywordSearchIngestSimplePanel.languagesValLabel.text=-
KeywordSearchIngestSimplePanel.languagesLabel.toolTipText=Scripts enabled for string extraction from unknown file types. Changes can be done in Advanced Settings.
KeywordSearchIngestSimplePanel.languagesValLabel.toolTipText=
KeywordSearchConfigurationPanel3.languagesLabel.text=Enabled scripts (languages): KeywordSearchConfigurationPanel3.languagesLabel.text=Enabled scripts (languages):
KeywordSearchConfigurationPanel2.chunksLabel.text=Chunks in keyword index: KeywordSearchConfigurationPanel2.chunksLabel.text=Chunks in keyword index:
KeywordSearchConfigurationPanel2.chunksValLabel.text=- KeywordSearchConfigurationPanel2.chunksValLabel.text=-
@ -74,9 +70,6 @@ KeywordSearchConfigurationPanel2.timeRadioButton2.toolTipText=10 minutes (faster
KeywordSearchConfigurationPanel2.timeRadioButton2.text=10 minutes (slower feedback, faster ingest) KeywordSearchConfigurationPanel2.timeRadioButton2.text=10 minutes (slower feedback, faster ingest)
KeywordSearchConfigurationPanel2.timeRadioButton3.toolTipText=5 minutes (overall ingest time will be longer) KeywordSearchConfigurationPanel2.timeRadioButton3.toolTipText=5 minutes (overall ingest time will be longer)
KeywordSearchConfigurationPanel2.timeRadioButton3.text=5 minutes (default) KeywordSearchConfigurationPanel2.timeRadioButton3.text=5 minutes (default)
KeywordSearchIngestSimplePanel.encodingsLabel.text=Encodings:
KeywordSearchIngestSimplePanel.keywordSearchEncodings.text=-
KeywordSearchIngestSimplePanel.titleLabel.text=Select keyword lists to enable during ingest:
OpenIDE-Module-Short-Description=Keyword Search ingest module, extracted text viewer and keyword search tools OpenIDE-Module-Short-Description=Keyword Search ingest module, extracted text viewer and keyword search tools
KeywordSearchListsViewerPanel.manageListsButton.toolTipText=Manage keyword lists, their settings and associated keywords. The settings are shared among all cases. KeywordSearchListsViewerPanel.manageListsButton.toolTipText=Manage keyword lists, their settings and associated keywords. The settings are shared among all cases.
KeywordSearchConfigurationPanel2.frequencyLabel.text=Results update frequency during ingest: KeywordSearchConfigurationPanel2.frequencyLabel.text=Results update frequency during ingest:
@ -264,3 +257,10 @@ Server.close.exception.msg=Cannot close Core
Server.close.exception.msg2=Cannot close Core Server.close.exception.msg2=Cannot close Core
Server.solrServerNoPortException.msg=Indexing server could not bind to port {0}, port is not available, consider change the default {1} port. Server.solrServerNoPortException.msg=Indexing server could not bind to port {0}, port is not available, consider change the default {1} port.
KeywordSearchConfigurationPanel2.showSnippetsCB.text=Show Keyword Preview in Keyword Search Results (will result in longer search times) KeywordSearchConfigurationPanel2.showSnippetsCB.text=Show Keyword Preview in Keyword Search Results (will result in longer search times)
KeywordSearchJobSettingsPanel.keywordSearchEncodings.text=-
KeywordSearchJobSettingsPanel.languagesValLabel.toolTipText=
KeywordSearchJobSettingsPanel.languagesValLabel.text=-
KeywordSearchJobSettingsPanel.encodingsLabel.text=Encodings:
KeywordSearchJobSettingsPanel.titleLabel.text=Select keyword lists to enable during ingest:
KeywordSearchJobSettingsPanel.languagesLabel.toolTipText=Scripts enabled for string extraction from unknown file types. Changes can be done in Advanced Settings.
KeywordSearchJobSettingsPanel.languagesLabel.text=Scripts enabled for string extraction from unknown file types:

View File

@ -44,8 +44,6 @@ KeywordSearchEditListPanel.ingestMessagesCheckbox.toolTipText=\u3053\u306e\u30ea
KeywordSearchConfigurationPanel2.skipNSRLCheckBox.text=\u51e6\u7406\u4e2d\u306bNSRL\u306e\u30d5\u30a1\u30a4\u30eb\uff08\u65e2\u77e5\u306e\u30d5\u30a1\u30a4\u30eb\uff09\u3092\u30ad\u30fc\u30ef\u30fc\u30c9\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u8ffd\u52a0\u3057\u306a\u3044 KeywordSearchConfigurationPanel2.skipNSRLCheckBox.text=\u51e6\u7406\u4e2d\u306bNSRL\u306e\u30d5\u30a1\u30a4\u30eb\uff08\u65e2\u77e5\u306e\u30d5\u30a1\u30a4\u30eb\uff09\u3092\u30ad\u30fc\u30ef\u30fc\u30c9\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u8ffd\u52a0\u3057\u306a\u3044
KeywordSearchConfigurationPanel2.skipNSRLCheckBox.toolTipText=Hash DB\u30b5\u30fc\u30d3\u30b9\u3092\u4e8b\u524d\u306b\u5b9f\u884c\u3059\u308b\u304b\u3001\u6b21\u56de\u306e\u51e6\u7406\u306b\u9078\u629e\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 KeywordSearchConfigurationPanel2.skipNSRLCheckBox.toolTipText=Hash DB\u30b5\u30fc\u30d3\u30b9\u3092\u4e8b\u524d\u306b\u5b9f\u884c\u3059\u308b\u304b\u3001\u6b21\u56de\u306e\u51e6\u7406\u306b\u9078\u629e\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
KeywordSearchConfigurationPanel2.filesIndexedLabel.text=\u30ad\u30fc\u30ef\u30fc\u30c9\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5185\u306e\u30d5\u30a1\u30a4\u30eb\uff1a KeywordSearchConfigurationPanel2.filesIndexedLabel.text=\u30ad\u30fc\u30ef\u30fc\u30c9\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5185\u306e\u30d5\u30a1\u30a4\u30eb\uff1a
KeywordSearchIngestSimplePanel.languagesLabel.text=\u4e0d\u660e\u306a\u30d5\u30a1\u30a4\u30eb\u5f62\u5f0f\u304b\u3089\u306e\u30b9\u30c8\u30ea\u30f3\u30b0\u62bd\u51fa\u3092\u6709\u52b9\u306b\u3057\u305f\u30b9\u30af\u30ea\u30d7\u30c8\uff1a
KeywordSearchIngestSimplePanel.languagesLabel.toolTipText=\u4e0d\u660e\u306a\u30d5\u30a1\u30a4\u30eb\u5f62\u5f0f\u304b\u3089\u306e\u30b9\u30c8\u30ea\u30f3\u30b0\u62bd\u51fa\u3092\u6709\u52b9\u306b\u3057\u305f\u30b9\u30af\u30ea\u30d7\u30c8\u3002\u30a2\u30c9\u30d0\u30f3\u30b9\u8a2d\u5b9a\u304b\u3089\u5909\u66f4\u304c\u53ef\u80fd\u3067\u3059\u3002
KeywordSearchConfigurationPanel3.languagesLabel.text=\u6709\u52b9\u306a\u30b9\u30af\u30ea\u30d7\u30c8\uff08\u8a00\u8a9e\uff09\uff1a KeywordSearchConfigurationPanel3.languagesLabel.text=\u6709\u52b9\u306a\u30b9\u30af\u30ea\u30d7\u30c8\uff08\u8a00\u8a9e\uff09\uff1a
KeywordSearchConfigurationPanel2.chunksLabel.text=\u30ad\u30fc\u30ef\u30fc\u30c9\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5185\u306e\u30c1\u30e3\u30f3\u30af\uff1a KeywordSearchConfigurationPanel2.chunksLabel.text=\u30ad\u30fc\u30ef\u30fc\u30c9\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5185\u306e\u30c1\u30e3\u30f3\u30af\uff1a
KeywordSearchConfigurationPanel3.enableUTF8Checkbox.text=UTF8\u30c6\u30ad\u30b9\u30c8\u62bd\u51fa\u306e\u6709\u52b9\u5316 KeywordSearchConfigurationPanel3.enableUTF8Checkbox.text=UTF8\u30c6\u30ad\u30b9\u30c8\u62bd\u51fa\u306e\u6709\u52b9\u5316
@ -63,8 +61,6 @@ KeywordSearchConfigurationPanel2.timeRadioButton2.toolTipText=\uff11\uff10\u5206
KeywordSearchConfigurationPanel2.timeRadioButton2.text=\uff11\uff10\u5206\uff08\u3088\u308a\u9045\u3044\u30d5\u30a3\u30fc\u30c9\u30d0\u30c3\u30af\u3001\u3088\u308a\u901f\u3044\u51e6\u7406\u6642\u9593\uff09 KeywordSearchConfigurationPanel2.timeRadioButton2.text=\uff11\uff10\u5206\uff08\u3088\u308a\u9045\u3044\u30d5\u30a3\u30fc\u30c9\u30d0\u30c3\u30af\u3001\u3088\u308a\u901f\u3044\u51e6\u7406\u6642\u9593\uff09
KeywordSearchConfigurationPanel2.timeRadioButton3.toolTipText=\uff15\u5206\uff08\u5168\u4f53\u7684\u306a\u51e6\u7406\u6642\u9593\u304c\u9577\u304f\u306a\u308a\u307e\u3059\uff09 KeywordSearchConfigurationPanel2.timeRadioButton3.toolTipText=\uff15\u5206\uff08\u5168\u4f53\u7684\u306a\u51e6\u7406\u6642\u9593\u304c\u9577\u304f\u306a\u308a\u307e\u3059\uff09
KeywordSearchConfigurationPanel2.timeRadioButton3.text=\uff15\u5206\uff08\u30c7\u30d5\u30a9\u30eb\u30c8\uff09 KeywordSearchConfigurationPanel2.timeRadioButton3.text=\uff15\u5206\uff08\u30c7\u30d5\u30a9\u30eb\u30c8\uff09
KeywordSearchIngestSimplePanel.encodingsLabel.text=\u30a8\u30f3\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\uff1a
KeywordSearchIngestSimplePanel.titleLabel.text=\u51e6\u7406\u4e2d\u306b\u6709\u52b9\u306a\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8\u3092\u9078\u629e\uff1a
OpenIDE-Module-Short-Description=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u51e6\u7406\u30e2\u30b8\u30e5\u30fc\u30eb\u3001\u62bd\u51fa\u3055\u308c\u305f\u30c6\u30ad\u30b9\u30c8\u30d3\u30e5\u30fc\u30a2\u3001\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30c4\u30fc\u30eb OpenIDE-Module-Short-Description=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u51e6\u7406\u30e2\u30b8\u30e5\u30fc\u30eb\u3001\u62bd\u51fa\u3055\u308c\u305f\u30c6\u30ad\u30b9\u30c8\u30d3\u30e5\u30fc\u30a2\u3001\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30c4\u30fc\u30eb
KeywordSearchListsViewerPanel.manageListsButton.toolTipText=\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8\u3001\u30ea\u30b9\u30c8\u306e\u8a2d\u5b9a\u3068\u95a2\u9023\u3059\u308b\u30ad\u30fc\u30ef\u30fc\u30c9\u306e\u7ba1\u7406\u3002\u3053\u306e\u8a2d\u5b9a\u306f\u5168\u3066\u306e\u30b1\u30fc\u30b9\u306b\u9069\u7528\u3055\u308c\u307e\u3059\u3002 KeywordSearchListsViewerPanel.manageListsButton.toolTipText=\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8\u3001\u30ea\u30b9\u30c8\u306e\u8a2d\u5b9a\u3068\u95a2\u9023\u3059\u308b\u30ad\u30fc\u30ef\u30fc\u30c9\u306e\u7ba1\u7406\u3002\u3053\u306e\u8a2d\u5b9a\u306f\u5168\u3066\u306e\u30b1\u30fc\u30b9\u306b\u9069\u7528\u3055\u308c\u307e\u3059\u3002
KeywordSearchConfigurationPanel2.frequencyLabel.text=\u51e6\u7406\u4e2d\u306e\u7d50\u679c\u66f4\u65b0\u306e\u983b\u5ea6\uff1a KeywordSearchConfigurationPanel2.frequencyLabel.text=\u51e6\u7406\u4e2d\u306e\u7d50\u679c\u66f4\u65b0\u306e\u983b\u5ea6\uff1a
@ -172,9 +168,7 @@ ExtractedContentPanel.pageOfLabel.text=of
ExtractedContentPanel.pageCurLabel.text=- ExtractedContentPanel.pageCurLabel.text=-
ExtractedContentPanel.pageTotalLabel.text=- ExtractedContentPanel.pageTotalLabel.text=-
KeywordSearchConfigurationPanel2.filesIndexedValue.text=- KeywordSearchConfigurationPanel2.filesIndexedValue.text=-
KeywordSearchIngestSimplePanel.languagesValLabel.text=-
KeywordSearchConfigurationPanel2.chunksValLabel.text=- KeywordSearchConfigurationPanel2.chunksValLabel.text=-
KeywordSearchIngestSimplePanel.keywordSearchEncodings.text=-
AbstractFileChunk.index.exception.msg=\u30d5\u30a1\u30a4\u30eb\u30b9\u30c8\u30ea\u30f3\u30b0\u30c1\u30e3\u30f3\u30af\u306e\u51e6\u7406\u4e2d\u306b\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a {0}, \u30c1\u30e3\u30f3\u30af\: {1} AbstractFileChunk.index.exception.msg=\u30d5\u30a1\u30a4\u30eb\u30b9\u30c8\u30ea\u30f3\u30b0\u30c1\u30e3\u30f3\u30af\u306e\u51e6\u7406\u4e2d\u306b\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a {0}, \u30c1\u30e3\u30f3\u30af\: {1}
AbstractFileStringContentStream.getSize.exception.msg=\u30b9\u30c8\u30ea\u30f3\u30b0\u5168\u4f53\u304c\u5909\u63db\u3055\u308c\u306a\u3051\u308c\u3070\u3001\u5909\u63db\u3055\u308c\u305f\u30b9\u30c8\u30ea\u30f3\u30b0\u5185\u306e\u30ad\u30e3\u30e9\u30af\u30bf\u30fc\u6570\u306f\u4e0d\u660e\u3067\u3059\u3002 AbstractFileStringContentStream.getSize.exception.msg=\u30b9\u30c8\u30ea\u30f3\u30b0\u5168\u4f53\u304c\u5909\u63db\u3055\u308c\u306a\u3051\u308c\u3070\u3001\u5909\u63db\u3055\u308c\u305f\u30b9\u30c8\u30ea\u30f3\u30b0\u5185\u306e\u30ad\u30e3\u30e9\u30af\u30bf\u30fc\u6570\u306f\u4e0d\u660e\u3067\u3059\u3002
AbstractFileStringContentStream.getSrcInfo.text=\u30d5\u30a1\u30a4\u30eb\uff1a{0} AbstractFileStringContentStream.getSrcInfo.text=\u30d5\u30a1\u30a4\u30eb\uff1a{0}
@ -255,4 +249,9 @@ KeywordSearchIngestModule.doInBackGround.cancelMsg=\uff08\u30ad\u30e3\u30f3\u30b
Server.addDoc.exception.msg2=\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u30cf\u30f3\u30c9\u30e9\u30fc\u3092\u4f7f\u7528\u3057\u307e\u3057\u305f\u304c\u3001\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u4e0b\u8a18\u306e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\uff1a{0} Server.addDoc.exception.msg2=\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u30cf\u30f3\u30c9\u30e9\u30fc\u3092\u4f7f\u7528\u3057\u307e\u3057\u305f\u304c\u3001\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u4e0b\u8a18\u306e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\uff1a{0}
ExtractedContentViewer.getSolrContent.txtBodyItal=<span style\=''font-style\:italic''>{0}</span> ExtractedContentViewer.getSolrContent.txtBodyItal=<span style\=''font-style\:italic''>{0}</span>
Keyword.toString.text=Keyword'{'query\={0}, isLiteral\={1}, keywordType\={2}'}' Keyword.toString.text=Keyword'{'query\={0}, isLiteral\={1}, keywordType\={2}'}'
KeywordSearchJobSettingsPanel.keywordSearchEncodings.text=-
KeywordSearchJobSettingsPanel.languagesValLabel.text=-
KeywordSearchJobSettingsPanel.encodingsLabel.text=\u30a8\u30f3\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\uff1a
KeywordSearchJobSettingsPanel.titleLabel.text=\u51e6\u7406\u4e2d\u306b\u6709\u52b9\u306a\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8\u3092\u9078\u629e\uff1a
KeywordSearchJobSettingsPanel.languagesLabel.toolTipText=\u4e0d\u660e\u306a\u30d5\u30a1\u30a4\u30eb\u5f62\u5f0f\u304b\u3089\u306e\u30b9\u30c8\u30ea\u30f3\u30b0\u62bd\u51fa\u3092\u6709\u52b9\u306b\u3057\u305f\u30b9\u30af\u30ea\u30d7\u30c8\u3002\u30a2\u30c9\u30d0\u30f3\u30b9\u8a2d\u5b9a\u304b\u3089\u5909\u66f4\u304c\u53ef\u80fd\u3067\u3059\u3002
KeywordSearchJobSettingsPanel.languagesLabel.text=\u4e0d\u660e\u306a\u30d5\u30a1\u30a4\u30eb\u5f62\u5f0f\u304b\u3089\u306e\u30b9\u30c8\u30ea\u30f3\u30b0\u62bd\u51fa\u3092\u6709\u52b9\u306b\u3057\u305f\u30b9\u30af\u30ea\u30d7\u30c8\uff1a

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -76,8 +76,6 @@ class Keyword {
return NbBundle.getMessage(this.getClass(), "Keyword.toString.text", keywordString, isLiteral, keywordType); return NbBundle.getMessage(this.getClass(), "Keyword.toString.text", keywordString, isLiteral, keywordType);
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj == null) { if (obj == null) {

View File

@ -0,0 +1,118 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2014 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.keywordsearch;
import java.util.Date;
import java.util.List;
public class KeywordList {
private String name;
private Date created;
private Date modified;
private Boolean useForIngest;
private Boolean ingestMessages;
private List<Keyword> keywords;
private Boolean locked;
KeywordList(String name, Date created, Date modified, Boolean useForIngest, Boolean ingestMessages, List<Keyword> keywords, boolean locked) {
this.name = name;
this.created = created;
this.modified = modified;
this.useForIngest = useForIngest;
this.ingestMessages = ingestMessages;
this.keywords = keywords;
this.locked = locked;
}
KeywordList(String name, Date created, Date modified, Boolean useForIngest, Boolean ingestMessages, List<Keyword> keywords) {
this(name, created, modified, useForIngest, ingestMessages, keywords, false);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final KeywordList other = (KeywordList) obj;
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 5;
return hash;
}
String getName() {
return name;
}
Date getDateCreated() {
return created;
}
Date getDateModified() {
return modified;
}
Boolean getUseForIngest() {
return useForIngest;
}
void setUseForIngest(boolean use) {
this.useForIngest = use;
}
Boolean getIngestMessages() {
return ingestMessages;
}
void setIngestMessages(boolean ingestMessages) {
this.ingestMessages = ingestMessages;
}
List<Keyword> getKeywords() {
return keywords;
}
boolean hasKeyword(Keyword keyword) {
return keywords.contains(keyword);
}
boolean hasKeyword(String keyword) {
//note, this ignores isLiteral
for (Keyword k : keywords) {
if (k.getQuery().equals(keyword)) {
return true;
}
}
return false;
}
Boolean isLocked() {
return locked;
}
}

View File

@ -0,0 +1,101 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.keywordsearch;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Keeps track, by name, of the keyword lists to be used for file ingest.
*/
// Note: This is a first step towards a keyword lists manager; it consists of
// the portion of the keyword list management code that resided in the keyword
// search file ingest module.
final class KeywordListsManager {
private static KeywordListsManager instance = null;
private final Logger logger = Logger.getLogger(KeywordListsManager.class.getName());
private final List<String> keywordListNames = new ArrayList<>();
private final List<Keyword> keywords = new ArrayList<>();
/**
* Gets the keyword lists manager singleton.
*/
static synchronized KeywordListsManager getInstance() {
if (null == instance) {
instance = new KeywordListsManager();
}
return instance;
}
private KeywordListsManager() {
addKeywordListsForFileIngest(null);
}
/**
* Sets the keyword lists to be used for ingest. The lists that are used
* will be the union of the lists enabled using the keyword search global
* options panel and a selection, possibly empty, of the disabled lists.
*
* @param listNames The names of disabled lists to temporarily enable
*/
synchronized void addKeywordListsForFileIngest(List<String> listNames) {
keywords.clear();
keywordListNames.clear();
StringBuilder logMessage = new StringBuilder();
KeywordSearchListsXML globalKeywordSearchOptions = KeywordSearchListsXML.getCurrent();
for (KeywordList list : globalKeywordSearchOptions.getListsL()) {
String listName = list.getName();
if ((list.getUseForIngest() == true) || (listNames != null && listNames.contains(listName))) {
keywordListNames.add(listName);
logMessage.append(listName).append(" ");
}
for (Keyword keyword : list.getKeywords()) {
if (!keywords.contains(keyword)) {
keywords.add(keyword);
}
}
}
logger.log(Level.INFO, "Keyword lists for file ingest set to: {0}", logMessage.toString());
}
/**
* Returns the keyword lists to be used for ingest, by name.
*
* @return The names of the enabled keyword lists
*/
synchronized List<String> getNamesOfKeywordListsForFileIngest() {
return new ArrayList<>(keywordListNames);
}
/**
* Indicates whether or not there are currently keywords for which to search
* during ingest.
*
* @return True if there are no keywords specified, false otherwise
*/
synchronized boolean hasNoKeywordsForSearch() {
return (keywords.isEmpty());
}
}

View File

@ -33,11 +33,11 @@ import org.sleuthkit.autopsy.corecomponents.AdvancedConfigurationDialog;
class KeywordSearchConfigurationAction extends CallableSystemAction{ class KeywordSearchConfigurationAction extends CallableSystemAction{
private static final String ACTION_NAME = org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class, "ListBundleConfig"); private static final String ACTION_NAME = org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class, "ListBundleConfig");
private KeywordSearchConfigurationPanel panel; private KeywordSearchGlobalSettingsPanel panel;
@Override @Override
public void performAction() { public void performAction() {
final KeywordSearchConfigurationPanel panel = getPanel(); final KeywordSearchGlobalSettingsPanel panel = getPanel();
panel.load(); panel.load();
final AdvancedConfigurationDialog dialog = new AdvancedConfigurationDialog(); final AdvancedConfigurationDialog dialog = new AdvancedConfigurationDialog();
dialog.addApplyButtonListener(new ActionListener() { dialog.addApplyButtonListener(new ActionListener() {
@ -60,9 +60,9 @@ class KeywordSearchConfigurationAction extends CallableSystemAction{
dialog.display(panel); dialog.display(panel);
} }
private KeywordSearchConfigurationPanel getPanel() { private KeywordSearchGlobalSettingsPanel getPanel() {
if(panel==null) { if(panel==null) {
panel = new KeywordSearchConfigurationPanel(); panel = new KeywordSearchGlobalSettingsPanel();
} }
return panel; return panel;
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -17,18 +17,12 @@
* limitations under the License. * limitations under the License.
*/ */
/*
* KeywordSearchConfigurationPanel1.java
*
* Created on Feb 28, 2012, 4:12:47 PM
*/
package org.sleuthkit.autopsy.keywordsearch; package org.sleuthkit.autopsy.keywordsearch;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.util.List; import java.util.List;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
@ -43,9 +37,7 @@ class KeywordSearchConfigurationPanel1 extends javax.swing.JPanel implements Opt
private static final Logger logger = Logger.getLogger(KeywordSearchConfigurationPanel1.class.getName()); private static final Logger logger = Logger.getLogger(KeywordSearchConfigurationPanel1.class.getName());
private static final String KEYWORD_CONFIG_NAME = org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class, "ListBundleConfig"); private static final String KEYWORD_CONFIG_NAME = org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class, "ListBundleConfig");
/** Creates new form KeywordSearchConfigurationPanel1 */
KeywordSearchConfigurationPanel1() { KeywordSearchConfigurationPanel1() {
initComponents(); initComponents();
customizeComponents(); customizeComponents();
setName(KEYWORD_CONFIG_NAME); setName(KEYWORD_CONFIG_NAME);
@ -80,7 +72,7 @@ class KeywordSearchConfigurationPanel1 extends javax.swing.JPanel implements Opt
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
final String FEATURE_NAME = "Save Keyword List"; final String FEATURE_NAME = "Save Keyword List";
KeywordSearchListsXML writer = KeywordSearchListsXML.getCurrent(); KeywordSearchListsXML writer = KeywordSearchListsXML.getCurrent();
KeywordSearchListsAbstract.KeywordSearchList currentKeywordList = editListPanel.getCurrentKeywordList(); KeywordList currentKeywordList = editListPanel.getCurrentKeywordList();
List<Keyword> keywords = currentKeywordList.getKeywords(); List<Keyword> keywords = currentKeywordList.getKeywords();
if (keywords.isEmpty()) { if (keywords.isEmpty()) {
@ -122,8 +114,6 @@ class KeywordSearchConfigurationPanel1 extends javax.swing.JPanel implements Opt
KeywordSearchUtil.displayDialog(FEATURE_NAME, NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel1.customizeComponents.kwListSavedMsg", listName), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO); KeywordSearchUtil.displayDialog(FEATURE_NAME, NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel1.customizeComponents.kwListSavedMsg", listName), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
} }
//currentKeywordList = writer.getList(listName);
listsManagementPanel.resync(); listsManagementPanel.resync();
} }
}); });

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2012 Basis Technology Corp. * Copyright 2012-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -22,7 +22,6 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.logging.Level; import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.apache.solr.client.solrj.SolrServerException;
import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.keywordsearch.KeywordSearchIngestModule.UpdateFrequency; import org.sleuthkit.autopsy.keywordsearch.KeywordSearchIngestModule.UpdateFrequency;
@ -45,8 +44,7 @@ class KeywordSearchConfigurationPanel2 extends javax.swing.JPanel implements Opt
private void activateWidgets() { private void activateWidgets() {
skipNSRLCheckBox.setSelected(KeywordSearchSettings.getSkipKnown()); skipNSRLCheckBox.setSelected(KeywordSearchSettings.getSkipKnown());
showSnippetsCB.setSelected(KeywordSearchSettings.getShowSnippets()); showSnippetsCB.setSelected(KeywordSearchSettings.getShowSnippets());
boolean enable = !IngestManager.getDefault().isIngestRunning() boolean enable = !IngestManager.getDefault().isIngestRunning();
&& !IngestManager.getDefault().isModuleRunning(KeywordSearchIngestModule.getDefault());
skipNSRLCheckBox.setEnabled(enable); skipNSRLCheckBox.setEnabled(enable);
setTimeSettingEnabled(enable); setTimeSettingEnabled(enable);
@ -70,7 +68,6 @@ class KeywordSearchConfigurationPanel2 extends javax.swing.JPanel implements Opt
timeRadioButton3.setSelected(true); timeRadioButton3.setSelected(true);
break; break;
} }
} }
/** /**
@ -205,7 +202,6 @@ class KeywordSearchConfigurationPanel2 extends javax.swing.JPanel implements Opt
.addContainerGap(116, Short.MAX_VALUE)) .addContainerGap(116, Short.MAX_VALUE))
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel chunksLabel; private javax.swing.JLabel chunksLabel;
private javax.swing.JLabel chunksValLabel; private javax.swing.JLabel chunksValLabel;
@ -248,14 +244,11 @@ class KeywordSearchConfigurationPanel2 extends javax.swing.JPanel implements Opt
private UpdateFrequency getSelectedTimeValue() { private UpdateFrequency getSelectedTimeValue() {
if (timeRadioButton1.isSelected()) { if (timeRadioButton1.isSelected()) {
return UpdateFrequency.FAST; return UpdateFrequency.FAST;
} } else if (timeRadioButton2.isSelected()) {
else if (timeRadioButton2.isSelected()) {
return UpdateFrequency.AVG; return UpdateFrequency.AVG;
} } else if (timeRadioButton3.isSelected()) {
else if (timeRadioButton3.isSelected()) {
return UpdateFrequency.SLOW; return UpdateFrequency.SLOW;
} } else if (timeRadioButton4.isSelected()) {
else if (timeRadioButton4.isSelected()) {
return UpdateFrequency.SLOWEST; return UpdateFrequency.SLOWEST;
} }
return UpdateFrequency.DEFAULT; return UpdateFrequency.DEFAULT;
@ -273,36 +266,28 @@ class KeywordSearchConfigurationPanel2 extends javax.swing.JPanel implements Opt
try { try {
filesIndexedValue.setText(Integer.toString(KeywordSearch.getServer().queryNumIndexedFiles())); filesIndexedValue.setText(Integer.toString(KeywordSearch.getServer().queryNumIndexedFiles()));
chunksValLabel.setText(Integer.toString(KeywordSearch.getServer().queryNumIndexedChunks())); chunksValLabel.setText(Integer.toString(KeywordSearch.getServer().queryNumIndexedChunks()));
} catch (KeywordSearchModuleException ex) { } catch (KeywordSearchModuleException | NoOpenCoreException ex) {
logger.log(Level.WARNING, "Could not get number of indexed files/chunks");
} catch (NoOpenCoreException ex) {
logger.log(Level.WARNING, "Could not get number of indexed files/chunks"); logger.log(Level.WARNING, "Could not get number of indexed files/chunks");
} }
KeywordSearch.addNumIndexedFilesChangeListener( KeywordSearch.addNumIndexedFilesChangeListener(
new PropertyChangeListener() { new PropertyChangeListener() {
@Override @Override
public void propertyChange(PropertyChangeEvent evt) { public void propertyChange(PropertyChangeEvent evt) {
String changed = evt.getPropertyName(); String changed = evt.getPropertyName();
Object newValue = evt.getNewValue(); Object newValue = evt.getNewValue();
if (changed.equals(KeywordSearch.NUM_FILES_CHANGE_EVT)) { if (changed.equals(KeywordSearch.NUM_FILES_CHANGE_EVT)) {
int newFilesIndexed = ((Integer) newValue).intValue(); int newFilesIndexed = ((Integer) newValue).intValue();
filesIndexedValue.setText(Integer.toString(newFilesIndexed)); filesIndexedValue.setText(Integer.toString(newFilesIndexed));
try { try {
chunksValLabel.setText(Integer.toString(KeywordSearch.getServer().queryNumIndexedChunks())); chunksValLabel.setText(Integer.toString(KeywordSearch.getServer().queryNumIndexedChunks()));
} catch (KeywordSearchModuleException ex) { } catch (KeywordSearchModuleException | NoOpenCoreException ex) {
logger.log(Level.WARNING, "Could not get number of indexed chunks"); logger.log(Level.WARNING, "Could not get number of indexed chunks");
} catch (NoOpenCoreException ex) {
logger.log(Level.WARNING, "Could not get number of indexed chunks");
}
}
} }
}); }
}
});
} }
} }

View File

@ -149,8 +149,7 @@ class KeywordSearchConfigurationPanel3 extends javax.swing.JPanel implements Opt
enableUTF8Checkbox.setSelected(utf8); enableUTF8Checkbox.setSelected(utf8);
final boolean extractEnabled = utf16 || utf8; final boolean extractEnabled = utf16 || utf8;
boolean ingestNotRunning = !IngestManager.getDefault().isIngestRunning() boolean ingestNotRunning = !IngestManager.getDefault().isIngestRunning() && !IngestManager.getDefault().isIngestRunning();
&& ! IngestManager.getDefault().isModuleRunning(KeywordSearchIngestModule.getDefault());
//enable / disable checboxes //enable / disable checboxes
activateScriptsCheckboxes(extractEnabled && ingestNotRunning); activateScriptsCheckboxes(extractEnabled && ingestNotRunning);
enableUTF16Checkbox.setEnabled(ingestNotRunning); enableUTF16Checkbox.setEnabled(ingestNotRunning);

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -17,7 +17,6 @@
* limitations under the License. * limitations under the License.
*/ */
package org.sleuthkit.autopsy.keywordsearch; package org.sleuthkit.autopsy.keywordsearch;
import java.awt.Component; import java.awt.Component;
@ -30,7 +29,6 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -49,7 +47,7 @@ import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn; import javax.swing.table.TableColumn;
import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent; import org.sleuthkit.autopsy.ingest.IngestManager.IngestEvent;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
/** /**
@ -59,7 +57,7 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
private static Logger logger = Logger.getLogger(KeywordSearchEditListPanel.class.getName()); private static Logger logger = Logger.getLogger(KeywordSearchEditListPanel.class.getName());
private KeywordTableModel tableModel; private KeywordTableModel tableModel;
private KeywordSearchListsAbstract.KeywordSearchList currentKeywordList; private KeywordList currentKeywordList;
private boolean ingestRunning; private boolean ingestRunning;
@ -161,7 +159,7 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
if (IngestManager.getDefault().isModuleRunning(KeywordSearchIngestModule.getDefault())) { if (IngestManager.getDefault().isIngestRunning()) {
initIngest(0); initIngest(0);
} else { } else {
initIngest(1); initIngest(1);
@ -173,14 +171,14 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
public void propertyChange(PropertyChangeEvent evt) { public void propertyChange(PropertyChangeEvent evt) {
String changed = evt.getPropertyName(); String changed = evt.getPropertyName();
Object oldValue = evt.getOldValue(); Object oldValue = evt.getOldValue();
if (changed.equals(IngestModuleEvent.COMPLETED.toString() ) if (changed.equals(IngestEvent.COMPLETED.toString() )
&& ((String) oldValue).equals(KeywordSearchIngestModule.MODULE_NAME)) { && ((String) oldValue).equals(KeywordSearchModuleFactory.getModuleName())) {
initIngest(1); initIngest(1);
} else if (changed.equals(IngestModuleEvent.STARTED.toString() ) } else if (changed.equals(IngestEvent.STARTED.toString() )
&& ((String) oldValue).equals(KeywordSearchIngestModule.MODULE_NAME)) { && ((String) oldValue).equals(KeywordSearchModuleFactory.getModuleName())) {
initIngest(0); initIngest(0);
} else if (changed.equals(IngestModuleEvent.STOPPED.toString() ) } else if (changed.equals(IngestEvent.STOPPED.toString() )
&& ((String) oldValue).equals(KeywordSearchIngestModule.MODULE_NAME)) { && ((String) oldValue).equals(KeywordSearchModuleFactory.getModuleName())) {
initIngest(1); initIngest(1);
} }
} }
@ -221,9 +219,9 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
boolean noKeywords = !listSet ? true : currentKeywordList.getKeywords().isEmpty(); boolean noKeywords = !listSet ? true : currentKeywordList.getKeywords().isEmpty();
// Certain buttons will be disabled if ingest is ongoing on this list // Certain buttons will be disabled if ingest is ongoing on this list
List<String> ingestLists = new ArrayList<String>(); List<String> ingestLists = new ArrayList<>();
if (ingestOngoing) { if (ingestOngoing) {
ingestLists = KeywordSearchIngestModule.getDefault().getKeywordLists(); ingestLists = KeywordListsManager.getInstance().getNamesOfKeywordListsForFileIngest();
} }
boolean inIngest = !listSet ? false : ingestLists.contains(currentKeywordList.getName()); boolean inIngest = !listSet ? false : ingestLists.contains(currentKeywordList.getName());
@ -575,7 +573,7 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
KeywordSearchListsXML reader = KeywordSearchListsXML.getCurrent(); KeywordSearchListsXML reader = KeywordSearchListsXML.getCurrent();
List<KeywordSearchListsAbstract.KeywordSearchList> toWrite = new ArrayList<KeywordSearchListsAbstract.KeywordSearchList>(); List<KeywordList> toWrite = new ArrayList<KeywordList>();
toWrite.add(reader.getList(currentKeywordList.getName())); toWrite.add(reader.getList(currentKeywordList.getName()));
final KeywordSearchListsXML exporter = new KeywordSearchListsXML(fileAbs); final KeywordSearchListsXML exporter = new KeywordSearchListsXML(fileAbs);
boolean written = exporter.saveLists(toWrite); boolean written = exporter.saveLists(toWrite);
@ -659,11 +657,11 @@ private void useForIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt)
// Implemented by parent panel // Implemented by parent panel
} }
KeywordSearchListsAbstract.KeywordSearchList getCurrentKeywordList() { KeywordList getCurrentKeywordList() {
return currentKeywordList; return currentKeywordList;
} }
void setCurrentKeywordList(KeywordSearchListsAbstract.KeywordSearchList list) { void setCurrentKeywordList(KeywordList list) {
currentKeywordList = list; currentKeywordList = list;
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 - 2013 Basis Technology Corp. * Copyright 2011-2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -16,22 +16,22 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.sleuthkit.autopsy.keywordsearch; package org.sleuthkit.autopsy.keywordsearch;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSetttingsPanel;
/** /**
* Container panel for keyword search advanced configuration options * Global options panel for keyword searching.
*/ */
public final class KeywordSearchConfigurationPanel extends javax.swing.JPanel implements OptionsPanel { final class KeywordSearchGlobalSettingsPanel extends IngestModuleGlobalSetttingsPanel implements OptionsPanel {
private KeywordSearchConfigurationPanel1 listsPanel; private KeywordSearchConfigurationPanel1 listsPanel;
private KeywordSearchConfigurationPanel3 languagesPanel; private KeywordSearchConfigurationPanel3 languagesPanel;
private KeywordSearchConfigurationPanel2 generalPanel; private KeywordSearchConfigurationPanel2 generalPanel;
public KeywordSearchConfigurationPanel() { public KeywordSearchGlobalSettingsPanel() {
initComponents(); initComponents();
customizeComponents(); customizeComponents();
} }
@ -63,46 +63,45 @@ public final class KeywordSearchConfigurationPanel extends javax.swing.JPanel im
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tabbedPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 675, Short.MAX_VALUE) .addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tabbedPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 505, Short.MAX_VALUE) .addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
/**
* Load each of the tabs and reload the XML.
*/
@Override @Override
public void load() { public void load() {
// Deselect all table rows // This calls actually clears the component.
listsPanel.load(); listsPanel.load();
languagesPanel.load(); languagesPanel.load();
generalPanel.load(); generalPanel.load();
// Reload the XML to avoid 'ghost' vars // Reload the XML to avoid 'ghost' vars
KeywordSearchListsXML.getCurrent().reload(); KeywordSearchListsXML.getCurrent().reload();
} }
/**
* Store each panel's settings.
*/
@Override @Override
public void store() { public void saveSettings() {
listsPanel.store(); listsPanel.store();
languagesPanel.store(); languagesPanel.store();
generalPanel.store(); generalPanel.store();
} }
@Override
public void store() {
saveSettings();
}
public void cancel() { public void cancel() {
KeywordSearchListsXML.getCurrent().reload(); KeywordSearchListsXML.getCurrent().reload();
} }
boolean valid() { boolean valid() {
// TODO check whether form is consistent and complete
return true; return true;
} }
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JTabbedPane tabbedPane; private javax.swing.JTabbedPane tabbedPane;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables

Some files were not shown because too many files have changed in this diff Show More