merge from new_table_load

This commit is contained in:
Greg DiCristofaro 2022-01-26 15:27:25 -05:00
commit f014c2a93a
239 changed files with 8623 additions and 1175 deletions

View File

@ -52,11 +52,12 @@ public class ViewOsAccountAction extends AbstractAction {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
final DirectoryTreeTopComponent topComp = DirectoryTreeTopComponent.findInstance();
new SwingWorker<Void, Void>() { new SwingWorker<Void, Void>() {
@Override @Override
protected Void doInBackground() throws Exception { protected Void doInBackground() throws Exception {
DirectoryTreeTopComponent.findInstance().viewOsAccount(osAccount); topComp.viewOsAccount(osAccount);
return null; return null;
} }

View File

@ -19,6 +19,7 @@
package org.sleuthkit.autopsy.corecomponents; package org.sleuthkit.autopsy.corecomponents;
import com.google.common.eventbus.Subscribe; import com.google.common.eventbus.Subscribe;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.awt.Cursor; import java.awt.Cursor;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
@ -32,6 +33,8 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.prefs.PreferenceChangeEvent; import java.util.prefs.PreferenceChangeEvent;
import java.util.prefs.PreferenceChangeListener; import java.util.prefs.PreferenceChangeListener;
@ -75,7 +78,6 @@ import org.sleuthkit.autopsy.mainui.datamodel.CreditCardBinSearchParams;
import org.sleuthkit.autopsy.mainui.datamodel.CreditCardDAO.CreditCardByBinFetcher; import org.sleuthkit.autopsy.mainui.datamodel.CreditCardDAO.CreditCardByBinFetcher;
import org.sleuthkit.autopsy.mainui.datamodel.CreditCardDAO.CreditCardByFileFetcher; import org.sleuthkit.autopsy.mainui.datamodel.CreditCardDAO.CreditCardByFileFetcher;
import org.sleuthkit.autopsy.mainui.datamodel.CreditCardFileSearchParams; import org.sleuthkit.autopsy.mainui.datamodel.CreditCardFileSearchParams;
import org.sleuthkit.autopsy.mainui.datamodel.CreditCardSearchParams;
import org.sleuthkit.autopsy.mainui.datamodel.events.DAOAggregateEvent; import org.sleuthkit.autopsy.mainui.datamodel.events.DAOAggregateEvent;
import org.sleuthkit.autopsy.mainui.datamodel.DataArtifactDAO.DataArtifactFetcher; import org.sleuthkit.autopsy.mainui.datamodel.DataArtifactDAO.DataArtifactFetcher;
import org.sleuthkit.autopsy.mainui.datamodel.DataArtifactSearchParam; import org.sleuthkit.autopsy.mainui.datamodel.DataArtifactSearchParam;
@ -194,6 +196,9 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
}; };
private final PropertyChangeListener weakDAOListener = WeakListeners.propertyChange(DAOListener, mainDAO); private final PropertyChangeListener weakDAOListener = WeakListeners.propertyChange(DAOListener, mainDAO);
private ExecutorService nodeBackgroundTasksPool;
private static final Integer MAX_POOL_SIZE = 10;
/** /**
* Creates and opens a Swing JPanel with a JTabbedPane child component that * Creates and opens a Swing JPanel with a JTabbedPane child component that
@ -1551,11 +1556,19 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
SwingUtilities.invokeLater(() -> displaySearchResults(searchResults, resetPaging, childSelectionInfo)); SwingUtilities.invokeLater(() -> displaySearchResults(searchResults, resetPaging, childSelectionInfo));
return; return;
} }
// Stop any running background threads.
if(nodeBackgroundTasksPool != null) {
nodeBackgroundTasksPool.shutdown();
}
nodeBackgroundTasksPool = Executors.newFixedThreadPool(MAX_POOL_SIZE,
new ThreadFactoryBuilder().setNameFormat("DataResultPanel-background-task-%d").build());
if (searchResults == null) { if (searchResults == null) {
setNode(null, resetPaging); setNode(null, resetPaging);
} else { } else {
SearchResultRootNode node = new SearchResultRootNode(searchResults); SearchResultRootNode node = new SearchResultRootNode(searchResults, nodeBackgroundTasksPool);
node.setNodeSelectionInfo(childSelectionInfo); node.setNodeSelectionInfo(childSelectionInfo);
setNode(node, resetPaging); setNode(node, resetPaging);
setNumberOfChildNodes( setNumberOfChildNodes(

View File

@ -36,7 +36,7 @@ import org.sleuthkit.autopsy.casemodule.DeleteDataSourceAction;
import org.sleuthkit.autopsy.datasourcesummary.ui.ViewSummaryInformationAction; import org.sleuthkit.autopsy.datasourcesummary.ui.ViewSummaryInformationAction;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.directorytree.ExplorerNodeActionVisitor; import org.sleuthkit.autopsy.directorytree.ExplorerNodeActionVisitor;
import org.sleuthkit.autopsy.directorytree.FileSearchAction; import org.sleuthkit.autopsy.directorytree.FileSearchTreeAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
@ -105,7 +105,7 @@ public class ImageNode extends AbstractContentNode<Image> {
List<Action> actionsList = new ArrayList<>(); List<Action> actionsList = new ArrayList<>();
actionsList.addAll(ExplorerNodeActionVisitor.getActions(content)); actionsList.addAll(ExplorerNodeActionVisitor.getActions(content));
actionsList.add(new FileSearchAction(Bundle.ImageNode_getActions_openFileSearchByAttr_text(), content.getId())); actionsList.add(new FileSearchTreeAction(Bundle.ImageNode_getActions_openFileSearchByAttr_text(), content.getId()));
actionsList.add(new ViewSummaryInformationAction(content.getId())); actionsList.add(new ViewSummaryInformationAction(content.getId()));
actionsList.add(new RunIngestModulesAction(Collections.<Content>singletonList(content))); actionsList.add(new RunIngestModulesAction(Collections.<Content>singletonList(content)));
actionsList.add(new NewWindowViewAction(NbBundle.getMessage(this.getClass(), "ImageNode.getActions.viewInNewWin.text"), this)); actionsList.add(new NewWindowViewAction(NbBundle.getMessage(this.getClass(), "ImageNode.getActions.viewInNewWin.text"), this));

View File

@ -29,7 +29,7 @@ import org.sleuthkit.autopsy.datasourcesummary.ui.ViewSummaryInformationAction;
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint; import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
import org.sleuthkit.autopsy.directorytree.ExportCSVAction; import org.sleuthkit.autopsy.directorytree.ExportCSVAction;
import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.FileSearchAction; import org.sleuthkit.autopsy.directorytree.FileSearchTreeAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.RunIngestModulesAction; import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.RunIngestModulesAction;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
@ -62,7 +62,7 @@ public abstract class SpecialDirectoryNode extends AbstractAbstractFileNode<Spec
actions.add(ExtractAction.getInstance()); actions.add(ExtractAction.getInstance());
actions.add(ExportCSVAction.getInstance()); actions.add(ExportCSVAction.getInstance());
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new FileSearchAction(Bundle.ImageNode_getActions_openFileSearchByAttr_text(), content.getId())); actions.add(new FileSearchTreeAction(Bundle.ImageNode_getActions_openFileSearchByAttr_text(), content.getId()));
if (content.isDataSource()) { if (content.isDataSource()) {
actions.add(new ViewSummaryInformationAction(content.getId())); actions.add(new ViewSummaryInformationAction(content.getId()));
actions.add(new RunIngestModulesAction(Collections.<Content>singletonList(content))); actions.add(new RunIngestModulesAction(Collections.<Content>singletonList(content)));

View File

@ -87,6 +87,7 @@ import org.sleuthkit.autopsy.datamodel.Tags;
import org.sleuthkit.autopsy.datamodel.ViewsNode; import org.sleuthkit.autopsy.datamodel.ViewsNode;
import org.sleuthkit.autopsy.datamodel.accounts.Accounts; import org.sleuthkit.autopsy.datamodel.accounts.Accounts;
import org.sleuthkit.autopsy.corecomponents.SelectionResponder; import org.sleuthkit.autopsy.corecomponents.SelectionResponder;
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.datamodel.CreditCards; import org.sleuthkit.autopsy.datamodel.CreditCards;
import org.sleuthkit.autopsy.datamodel.accounts.BINRange; import org.sleuthkit.autopsy.datamodel.accounts.BINRange;
import org.sleuthkit.autopsy.mainui.datamodel.EmailsDAO; import org.sleuthkit.autopsy.mainui.datamodel.EmailsDAO;
@ -461,6 +462,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
* *
* @return getDefault() - the default instance * @return getDefault() - the default instance
*/ */
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
public static synchronized DirectoryTreeTopComponent findInstance() { public static synchronized DirectoryTreeTopComponent findInstance() {
WindowManager winManager = WindowManager.getDefault(); WindowManager winManager = WindowManager.getDefault();
TopComponent win = winManager.findTopComponent(PREFERRED_ID); TopComponent win = winManager.findTopComponent(PREFERRED_ID);

View File

@ -1,30 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2021 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.directorytree;
/**
* Lookup interface for File Search (to deal with circular deps)
*/
public interface FileSearchProvider {
public void showDialog(Long dataSourceID);
@Deprecated
public void showDialog();
}

View File

@ -20,14 +20,15 @@ package org.sleuthkit.autopsy.directorytree;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
import org.openide.util.Lookup; import org.sleuthkit.autopsy.filesearch.FileSearchAction;
/** /**
* The File Search by Attributes action for data sources in the tree. * The File Search by Attributes action for data sources in the tree.
*/ */
public class FileSearchAction extends AbstractAction { public class FileSearchTreeAction extends AbstractAction {
private final long dataSourceId; private final long dataSourceId;
private FileSearchAction searcher;
/** /**
* Main constructor. * Main constructor.
@ -36,14 +37,17 @@ public class FileSearchAction extends AbstractAction {
* @param dataSourceID The data source id of the item that is selected in * @param dataSourceID The data source id of the item that is selected in
* the tree. * the tree.
*/ */
public FileSearchAction(String title, long dataSourceID) { public FileSearchTreeAction(String title, long dataSourceID) {
super(title); super(title);
dataSourceId = dataSourceID; dataSourceId = dataSourceID;
} }
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
FileSearchProvider searcher = Lookup.getDefault().lookup(FileSearchProvider.class); if(searcher == null) {
searcher = FileSearchAction.getDefault();
}
searcher.showDialog(dataSourceId); searcher.showDialog(dataSourceId);
} }

View File

@ -61,3 +61,4 @@ DateSearchPanel.dateFormatLabel.text=*The date format is mm/dd/yyyy
MimeTypePanel.noteLabel.text=*Note: Multiple MIME types can be selected MimeTypePanel.noteLabel.text=*Note: Multiple MIME types can be selected
HashSearchPanel.sha256CheckBox.text=SHA-256: HashSearchPanel.sha256CheckBox.text=SHA-256:
HashSearchPanel.sha256TextField.text= HashSearchPanel.sha256TextField.text=
FileSearchPanel.closeButton.text=Close

View File

@ -80,3 +80,4 @@ DateSearchPanel.dateFormatLabel.text=*The date format is mm/dd/yyyy
MimeTypePanel.noteLabel.text=*Note: Multiple MIME types can be selected MimeTypePanel.noteLabel.text=*Note: Multiple MIME types can be selected
HashSearchPanel.sha256CheckBox.text=SHA-256: HashSearchPanel.sha256CheckBox.text=SHA-256:
HashSearchPanel.sha256TextField.text= HashSearchPanel.sha256TextField.text=
FileSearchPanel.closeButton.text=Close

View File

@ -19,7 +19,10 @@
package org.sleuthkit.autopsy.filesearch; package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.util.EnumSet;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
/** /**
* Filter by mime type used in filter areas of file search by attribute. * Filter by mime type used in filter areas of file search by attribute.

View File

@ -18,9 +18,11 @@
*/ */
package org.sleuthkit.autopsy.filesearch; package org.sleuthkit.autopsy.filesearch;
import java.beans.PropertyChangeEvent;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -53,6 +55,18 @@ public class DataSourcePanel extends javax.swing.JPanel {
public DataSourcePanel() { public DataSourcePanel() {
initComponents(); initComponents();
resetDataSourcePanel(); resetDataSourcePanel();
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED), (PropertyChangeEvent evt) -> {
if(evt.getPropertyName().equals(Case.Events.DATA_SOURCE_ADDED.toString())) {
List<String> strings = getDataSourceArray();
for (String dataSource : strings) {
DefaultListModel<String> model = (DefaultListModel<String>) dataSourceList.getModel();
if(!model.contains(dataSource)) {
model.addElement(dataSource);
}
}
}
});
} }
/** /**

View File

@ -25,16 +25,16 @@ import org.openide.util.HelpCtx;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction; import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.directorytree.FileSearchProvider; import org.sleuthkit.autopsy.timeline.OpenTimelineAction;
final class FileSearchAction extends CallableSystemAction implements FileSearchProvider { final public class FileSearchAction extends CallableSystemAction {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static FileSearchAction instance = null; private static FileSearchAction instance = null;
private static FileSearchDialog searchDialog; private static FileSearchDialog searchDialog;
private static Long selectedDataSourceId; private static Long selectedDataSourceId;
FileSearchAction() { private FileSearchAction() {
super(); super();
setEnabled(Case.isCaseOpen()); setEnabled(Case.isCaseOpen());
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> {
@ -49,7 +49,7 @@ final class FileSearchAction extends CallableSystemAction implements FileSearchP
public static FileSearchAction getDefault() { public static FileSearchAction getDefault() {
if (instance == null) { if (instance == null) {
instance = new FileSearchAction(); instance = CallableSystemAction.get(FileSearchAction.class);
} }
return instance; return instance;
} }
@ -89,15 +89,12 @@ final class FileSearchAction extends CallableSystemAction implements FileSearchP
return false; return false;
} }
@Override
public void showDialog(Long dataSourceId) { public void showDialog(Long dataSourceId) {
selectedDataSourceId = dataSourceId; selectedDataSourceId = dataSourceId;
performAction(); performAction();
} }
@Override
@Deprecated
public void showDialog() { public void showDialog() {
showDialog(null); showDialog(null);
} }

View File

@ -42,12 +42,18 @@ final class FileSearchDialog extends javax.swing.JDialog {
setResizable(false); setResizable(false);
this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
fileSearchPanel1.addListenerToAll(new ActionListener() { fileSearchPanel1.addListenerToAll(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
setVisible(false); setVisible(false);
} }
}); });
fileSearchPanel1.addCloseListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dispose();
}
});
} }
/** /**

View File

@ -18,32 +18,7 @@
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues> </AuxValues>
<Layout> <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="filterPanel" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="errorLabel" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="filterPanel" pref="266" max="32767" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents> <SubComponents>
<Container class="javax.swing.JPanel" name="filterPanel"> <Container class="javax.swing.JPanel" name="filterPanel">
<Properties> <Properties>
@ -56,18 +31,45 @@
<Dimension value="[300, 400]"/> <Dimension value="[300, 400]"/>
</Property> </Property>
</Properties> </Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
<Property name="axis" type="int" value="1"/> <Property name="axis" type="int" value="1"/>
</Layout> </Layout>
</Container> </Container>
<Component class="javax.swing.JButton" name="searchButton"> <Container class="javax.swing.JPanel" name="buttonPanel">
<Properties> <Constraints>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="FileSearchPanel.searchButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="5" insetsRight="5" anchor="13" weightX="0.0" weightY="0.0"/>
</Property> </Constraint>
</Properties> </Constraints>
</Component>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout">
<Property name="columns" type="int" value="0"/>
<Property name="horizontalGap" type="int" value="3"/>
<Property name="rows" type="int" value="1"/>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="searchButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="FileSearchPanel.searchButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="closeButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="FileSearchPanel.closeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="errorLabel"> <Component class="javax.swing.JLabel" name="errorLabel">
<Properties> <Properties>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor"> <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
@ -77,6 +79,11 @@
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="FileSearchPanel.errorLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="FileSearchPanel.errorLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component> </Component>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -358,6 +358,10 @@ class FileSearchPanel extends javax.swing.JPanel {
fsf.addActionListener(l); fsf.addActionListener(l);
} }
} }
void addCloseListener(ActionListener l) {
closeButton.addActionListener(l);
}
/** /**
* This method is called from within the constructor to initialize the form. * This method is called from within the constructor to initialize the form.
@ -367,46 +371,57 @@ class FileSearchPanel extends javax.swing.JPanel {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() { private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
filterPanel = new javax.swing.JPanel(); filterPanel = new javax.swing.JPanel();
buttonPanel = new javax.swing.JPanel();
searchButton = new javax.swing.JButton(); searchButton = new javax.swing.JButton();
closeButton = new javax.swing.JButton();
errorLabel = new javax.swing.JLabel(); errorLabel = new javax.swing.JLabel();
setPreferredSize(new java.awt.Dimension(300, 300)); setPreferredSize(new java.awt.Dimension(300, 300));
setLayout(new java.awt.GridBagLayout());
filterPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); filterPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
filterPanel.setPreferredSize(new java.awt.Dimension(300, 400)); filterPanel.setPreferredSize(new java.awt.Dimension(300, 400));
filterPanel.setLayout(new javax.swing.BoxLayout(filterPanel, javax.swing.BoxLayout.Y_AXIS)); filterPanel.setLayout(new javax.swing.BoxLayout(filterPanel, javax.swing.BoxLayout.Y_AXIS));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.gridwidth = 2;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
add(filterPanel, gridBagConstraints);
buttonPanel.setLayout(new java.awt.GridLayout(1, 0, 3, 0));
searchButton.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.searchButton.text")); // NOI18N searchButton.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.searchButton.text")); // NOI18N
buttonPanel.add(searchButton);
closeButton.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.closeButton.text")); // NOI18N
buttonPanel.add(closeButton);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 1;
gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 5);
add(buttonPanel, gridBagConstraints);
errorLabel.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.errorLabel.text")); // NOI18N
errorLabel.setForeground(new java.awt.Color(255, 51, 51)); errorLabel.setForeground(new java.awt.Color(255, 51, 51));
errorLabel.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.errorLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); gridBagConstraints = new java.awt.GridBagConstraints();
this.setLayout(layout); gridBagConstraints.gridx = 0;
layout.setHorizontalGroup( gridBagConstraints.gridy = 1;
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
.addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) gridBagConstraints.weightx = 1.0;
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() add(errorLabel, gridBagConstraints);
.addContainerGap()
.addComponent(errorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(searchButton)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 266, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(searchButton)
.addComponent(errorLabel))
.addContainerGap())
);
}// </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.JPanel buttonPanel;
private javax.swing.JButton closeButton;
private javax.swing.JLabel errorLabel; private javax.swing.JLabel errorLabel;
private javax.swing.JPanel filterPanel; private javax.swing.JPanel filterPanel;
private javax.swing.JButton searchButton; private javax.swing.JButton searchButton;

View File

@ -365,12 +365,12 @@ final class IngestJobExecutor {
* thread executing an ingest task, so such a job would run forever, * thread executing an ingest task, so such a job would run forever,
* doing nothing, without a check here. * doing nothing, without a check here.
*/ */
checkForTierCompleted(); checkForTierCompleted(moduleTierIndex);
} }
} }
/** /**
* Estimates the files to be prcessed in the current tier. * Estimates the files to be processed in the current tier.
*/ */
private void estimateFilesToProcess() { private void estimateFilesToProcess() {
estimatedFilesToProcess = 0; estimatedFilesToProcess = 0;
@ -487,7 +487,7 @@ final class IngestJobExecutor {
* job, so such a job would run forever, doing nothing, without * job, so such a job would run forever, doing nothing, without
* a check here. * a check here.
*/ */
checkForTierCompleted(); checkForTierCompleted(moduleTierIndex);
} }
} }
} }
@ -497,11 +497,16 @@ final class IngestJobExecutor {
* module tier are completed, and does an appropriate state transition if * module tier are completed, and does an appropriate state transition if
* they are. * they are.
*/ */
private void checkForTierCompleted() { private void checkForTierCompleted(int currentTier) {
synchronized (tierTransitionLock) { synchronized (tierTransitionLock) {
if (jobState.equals(IngestJobState.ACCEPTING_STREAMED_CONTENT_AND_ANALYZING)) { if (jobState.equals(IngestJobState.ACCEPTING_STREAMED_CONTENT_AND_ANALYZING)) {
return; return;
} }
if (currentTier < moduleTierIndex) {
// We likely had a leftover task from the previous tier. Since we've already
// advanced to the next tier, ignore it.
return;
}
if (taskScheduler.currentTasksAreCompleted(getIngestJobId())) { if (taskScheduler.currentTasksAreCompleted(getIngestJobId())) {
do { do {
shutDownCurrentTier(); shutDownCurrentTier();
@ -512,7 +517,7 @@ final class IngestJobExecutor {
shutDown(); shutDown();
break; break;
} }
} while (taskScheduler.currentTasksAreCompleted(getIngestJobId())); } while (taskScheduler.currentTasksAreCompleted(getIngestJobId())); // Loop again immediately in case the new tier is empty
} }
} }
} }
@ -566,8 +571,11 @@ final class IngestJobExecutor {
} }
} }
} finally { } finally {
// Save the module tier assocaited with this task since it could change after
// notifyTaskComplete
int currentTier = moduleTierIndex;
taskScheduler.notifyTaskCompleted(task); taskScheduler.notifyTaskCompleted(task);
checkForTierCompleted(); checkForTierCompleted(currentTier);
} }
} }
@ -619,8 +627,11 @@ final class IngestJobExecutor {
logger.log(Level.SEVERE, String.format("File ingest thread interrupted during execution of file ingest job (file object ID = %d, thread ID = %d)", task.getFileId(), task.getThreadId()), ex); logger.log(Level.SEVERE, String.format("File ingest thread interrupted during execution of file ingest job (file object ID = %d, thread ID = %d)", task.getFileId(), task.getThreadId()), ex);
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} finally { } finally {
// Save the module tier assocaited with this task since it could change after
// notifyTaskComplete
int currentTier = moduleTierIndex;
taskScheduler.notifyTaskCompleted(task); taskScheduler.notifyTaskCompleted(task);
checkForTierCompleted(); checkForTierCompleted(currentTier);
} }
} }
@ -644,13 +655,16 @@ final class IngestJobExecutor {
} }
} }
} finally { } finally {
// Save the module tier assocaited with this task since it could change after
// notifyTaskComplete
int currentTier = moduleTierIndex;
taskScheduler.notifyTaskCompleted(task); taskScheduler.notifyTaskCompleted(task);
checkForTierCompleted(); checkForTierCompleted(currentTier);
} }
} }
/** /**
* Passes an analyisis result from the data source for the ingest job * Passes an analysis result from the data source for the ingest job
* through the analysis result ingest module pipeline. * through the analysis result ingest module pipeline.
* *
* @param task An analysis result ingest task encapsulating the analysis * @param task An analysis result ingest task encapsulating the analysis
@ -669,8 +683,11 @@ final class IngestJobExecutor {
} }
} }
} finally { } finally {
// Save the module tier assocaited with this task since it could change after
// notifyTaskComplete
int currentTier = moduleTierIndex;
taskScheduler.notifyTaskCompleted(task); taskScheduler.notifyTaskCompleted(task);
checkForTierCompleted(); checkForTierCompleted(currentTier);
} }
} }
@ -793,6 +810,12 @@ final class IngestJobExecutor {
* Shuts down the ingest module pipelines in the current module tier. * Shuts down the ingest module pipelines in the current module tier.
*/ */
private void shutDownCurrentTier() { private void shutDownCurrentTier() {
// Note that this method is only called while holding the tierTransitionLock, so moduleTierIndex can not change
// during execution.
if (moduleTierIndex >= ingestModuleTiers.size()) {
logErrorMessage(Level.SEVERE, "shutDownCurrentTier called with out-of-bounds moduleTierIndex (" + moduleTierIndex + ")");
return;
}
logInfoMessage(String.format("Finished all ingest tasks for tier %s of ingest job", moduleTierIndex)); //NON-NLS logInfoMessage(String.format("Finished all ingest tasks for tier %s of ingest job", moduleTierIndex)); //NON-NLS
jobState = IngestJobExecutor.IngestJobState.PIPELINES_SHUTTING_DOWN; jobState = IngestJobExecutor.IngestJobState.PIPELINES_SHUTTING_DOWN;
IngestModuleTier moduleTier = ingestModuleTiers.get(moduleTierIndex); IngestModuleTier moduleTier = ingestModuleTiers.get(moduleTierIndex);
@ -861,7 +884,7 @@ final class IngestJobExecutor {
* @return The currently running module, may be null. * @return The currently running module, may be null.
*/ */
DataSourceIngestPipeline.DataSourcePipelineModule getCurrentDataSourceIngestModule() { DataSourceIngestPipeline.DataSourcePipelineModule getCurrentDataSourceIngestModule() {
Optional<DataSourceIngestPipeline> pipeline = ingestModuleTiers.get(moduleTierIndex).getDataSourceIngestPipeline(); Optional<DataSourceIngestPipeline> pipeline = getCurrentDataSourceIngestPipelines();
if (pipeline.isPresent()) { if (pipeline.isPresent()) {
return (DataSourceIngestPipeline.DataSourcePipelineModule) pipeline.get().getCurrentlyRunningModule(); return (DataSourceIngestPipeline.DataSourcePipelineModule) pipeline.get().getCurrentlyRunningModule();
} else { } else {
@ -963,7 +986,7 @@ final class IngestJobExecutor {
} }
pausedIngestThreads.clear(); pausedIngestThreads.clear();
} }
checkForTierCompleted(); checkForTierCompleted(moduleTierIndex);
} }
/** /**
@ -1407,6 +1430,35 @@ final class IngestJobExecutor {
logErrorMessage(Level.SEVERE, String.format("%s experienced an error during analysis while processing file %s (object ID = %d)", error.getModuleDisplayName(), file.getName(), file.getId()), error.getThrowable()); //NON-NLS logErrorMessage(Level.SEVERE, String.format("%s experienced an error during analysis while processing file %s (object ID = %d)", error.getModuleDisplayName(), file.getName(), file.getId()), error.getThrowable()); //NON-NLS
} }
} }
/**
* Safely gets the file ingest pipelines for the current tier.
*
* @return The file ingest pipelines or empty if ingest has completed/is shutting down.
*/
Optional<List<FileIngestPipeline>> getCurrentFileIngestPipelines() {
// Make a local copy in case the tier increments
int currentModuleTierIndex = moduleTierIndex;
if (currentModuleTierIndex < ingestModuleTiers.size()) {
return Optional.of(ingestModuleTiers.get(currentModuleTierIndex).getFileIngestPipelines());
}
return Optional.empty();
}
/**
* Safely gets the data source ingest pipeline for the current tier.
*
* @return The data source ingest pipeline or empty if ingest has completed/is shutting down.
*/
Optional<DataSourceIngestPipeline> getCurrentDataSourceIngestPipelines() {
// Make a local copy in case the tier increments
int currentModuleTierIndex = moduleTierIndex;
if (currentModuleTierIndex < ingestModuleTiers.size()) {
return ingestModuleTiers.get(currentModuleTierIndex).getDataSourceIngestPipeline();
}
return Optional.empty();
}
/** /**
* Gets a snapshot of some basic diagnostic statistics for the ingest job * Gets a snapshot of some basic diagnostic statistics for the ingest job
@ -1431,7 +1483,12 @@ final class IngestJobExecutor {
*/ */
boolean fileIngestRunning = false; boolean fileIngestRunning = false;
Date fileIngestStartTime = null; Date fileIngestStartTime = null;
for (FileIngestPipeline pipeline : ingestModuleTiers.get(moduleTierIndex).getFileIngestPipelines()) { Optional<List<FileIngestPipeline>> fileIngestPipelines = getCurrentFileIngestPipelines();
if (!fileIngestPipelines.isPresent()) {
// If there are no currently running pipelines, use the original set.
fileIngestPipelines = Optional.of(ingestModuleTiers.get(0).getFileIngestPipelines());
}
for (FileIngestPipeline pipeline : fileIngestPipelines.get()) {
if (pipeline.isRunning()) { if (pipeline.isRunning()) {
fileIngestRunning = true; fileIngestRunning = true;
} }

View File

@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.mainui.nodes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.logging.Level; import java.util.logging.Level;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
@ -55,8 +56,8 @@ public class AnalysisResultNode extends ArtifactNode<AnalysisResult, AnalysisRes
* @param tableData The table search result DTO. * @param tableData The table search result DTO.
* @param resultRow The row DTO. * @param resultRow The row DTO.
*/ */
AnalysisResultNode(AnalysisResultTableSearchResultsDTO tableData, AnalysisResultRowDTO resultRow) { AnalysisResultNode(AnalysisResultTableSearchResultsDTO tableData, AnalysisResultRowDTO resultRow, ExecutorService backgroundTasksPool) {
this(tableData, resultRow, IconsUtil.getIconFilePath(tableData.getArtifactType().getTypeID())); this(tableData, resultRow, IconsUtil.getIconFilePath(tableData.getArtifactType().getTypeID()), backgroundTasksPool);
} }
/** /**
@ -66,8 +67,8 @@ public class AnalysisResultNode extends ArtifactNode<AnalysisResult, AnalysisRes
* @param resultRow The row DTO. * @param resultRow The row DTO.
* @param iconPath The path for the node icon. * @param iconPath The path for the node icon.
*/ */
AnalysisResultNode(AnalysisResultTableSearchResultsDTO tableData, AnalysisResultRowDTO resultRow, String iconPath) { AnalysisResultNode(AnalysisResultTableSearchResultsDTO tableData, AnalysisResultRowDTO resultRow, String iconPath, ExecutorService backgroundTasksPool) {
super(tableData, resultRow, tableData.getColumns(), createLookup(resultRow), iconPath); super(tableData, resultRow, tableData.getColumns(), createLookup(resultRow), iconPath, backgroundTasksPool);
} }
/** /**

View File

@ -47,6 +47,8 @@ import org.sleuthkit.autopsy.mainui.datamodel.events.DAOEvent;
import org.sleuthkit.autopsy.mainui.datamodel.events.DeleteAnalysisResultEvent; import org.sleuthkit.autopsy.mainui.datamodel.events.DeleteAnalysisResultEvent;
import org.sleuthkit.autopsy.mainui.datamodel.events.TreeEvent; import org.sleuthkit.autopsy.mainui.datamodel.events.TreeEvent;
import static org.sleuthkit.autopsy.mainui.nodes.TreeNode.getDefaultLookup; import static org.sleuthkit.autopsy.mainui.nodes.TreeNode.getDefaultLookup;
import org.sleuthkit.autopsy.mainui.nodes.actions.ActionsFactory;
import org.sleuthkit.autopsy.mainui.nodes.actions.DeleteAnalysisResultSetAction;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskData;
@ -163,6 +165,24 @@ public class AnalysisResultTypeFactory extends TreeChildFactory<AnalysisResultSe
public Optional<BlackboardArtifact.Type> getAnalysisResultType() { public Optional<BlackboardArtifact.Type> getAnalysisResultType() {
return Optional.ofNullable(this.getItemData().getSearchParams().getArtifactType()); return Optional.ofNullable(this.getItemData().getSearchParams().getArtifactType());
} }
@Override
public Optional<Long> getDataSourceIdForActions() {
return Optional.ofNullable(this.getItemData().getSearchParams().getDataSourceId());
}
@Override
public Optional<ActionsFactory.ActionGroup> getNodeSpecificActions() {
ActionsFactory.ActionGroup group = new ActionsFactory.ActionGroup();
Optional<BlackboardArtifact.Type> type = getAnalysisResultType();
Optional<Long> dsId = getDataSourceIdForActions();
if (type.isPresent()) {
group.add(new DeleteAnalysisResultSetAction(type.get(), "", dsId.isPresent() ? dsId.get() : null));
}
return Optional.of(group);
}
} }
@ -324,6 +344,20 @@ public class AnalysisResultTypeFactory extends TreeChildFactory<AnalysisResultSe
public List<String> getAnalysisResultConfigurations() { public List<String> getAnalysisResultConfigurations() {
return Collections.singletonList(this.getItemData().getSearchParams().getConfiguration()); return Collections.singletonList(this.getItemData().getSearchParams().getConfiguration());
} }
@Override
public Optional<ActionsFactory.ActionGroup> getNodeSpecificActions() {
ActionsFactory.ActionGroup group = new ActionsFactory.ActionGroup();
Optional<BlackboardArtifact.Type> type = getAnalysisResultType();
Optional<String> configuration = getAnalysisResultConfiguration();
Optional<Long> dsId = getDataSourceIdForActions();
if (type.isPresent()) {
group.add(new DeleteAnalysisResultSetAction(type.get(), configuration.isPresent() ? configuration.get() : "", dsId.isPresent() ? dsId.get() : null));
}
return Optional.of(group);
}
} }
/** /**
@ -541,6 +575,16 @@ public class AnalysisResultTypeFactory extends TreeChildFactory<AnalysisResultSe
} }
@Override @Override
public Optional<ActionsFactory.ActionGroup> getNodeSpecificActions() {
ActionsFactory.ActionGroup group = new ActionsFactory.ActionGroup();
KeywordSearchTermParams searchTermParams = this.getItemData().getSearchParams();
// ELTODO fill this stub when implementing KWS result deletion
// group.add(new DeleteAnalysisResultSetAction(searchTermParams));
return Optional.of(group);
}
public Optional<Long> getDataSourceIdForActions() { public Optional<Long> getDataSourceIdForActions() {
return Optional.ofNullable(this.getItemData().getSearchParams().getDataSourceId()); return Optional.ofNullable(this.getItemData().getSearchParams().getDataSourceId());
} }

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.mainui.nodes;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutorService;
import javax.swing.Action; import javax.swing.Action;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.openide.nodes.Children; import org.openide.nodes.Children;
@ -63,8 +64,8 @@ public abstract class ArtifactNode<T extends BlackboardArtifact, R extends Artif
private final List<ColumnKey> columns; private final List<ColumnKey> columns;
private Node parentFileNode; private Node parentFileNode;
ArtifactNode(SearchResultsDTO searchResults, R rowData, List<ColumnKey> columns, Lookup lookup, String iconPath) { ArtifactNode(SearchResultsDTO searchResults, R rowData, List<ColumnKey> columns, Lookup lookup, String iconPath, ExecutorService backgroundTasksPool) {
super(Children.LEAF, lookup, searchResults, rowData); super(Children.LEAF, lookup, searchResults, rowData, backgroundTasksPool);
this.rowData = rowData; this.rowData = rowData;
this.columns = columns; this.columns = columns;
setupNodeDisplay(iconPath); setupNodeDisplay(iconPath);

View File

@ -18,7 +18,6 @@
*/ */
package org.sleuthkit.autopsy.mainui.nodes; package org.sleuthkit.autopsy.mainui.nodes;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
@ -28,7 +27,6 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask; import java.util.concurrent.FutureTask;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.swing.Action; import javax.swing.Action;
@ -36,7 +34,6 @@ import javax.swing.SwingUtilities;
import org.openide.nodes.AbstractNode; import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.nodes.Sheet; import org.openide.nodes.Sheet;
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.WeakListeners; import org.openide.util.WeakListeners;
@ -60,9 +57,6 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
import org.sleuthkit.autopsy.texttranslation.TextTranslationService; import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
import org.sleuthkit.datamodel.AnalysisResult;
import org.sleuthkit.datamodel.DataArtifact;
import org.sleuthkit.datamodel.TskCoreException;
/** /**
* A a simple starting point for nodes. * A a simple starting point for nodes.
@ -144,22 +138,15 @@ abstract class BaseNode<S extends SearchResultsDTO, R extends BaseRowDTO> extend
* A pool of background tasks to run any long computation needed to populate * A pool of background tasks to run any long computation needed to populate
* this node. * this node.
*/ */
static final ExecutorService backgroundTasksPool; private final ExecutorService backgroundTasksPool;
private static final Integer MAX_POOL_SIZE = 10;
private FutureTask<String> scoFutureTask; private FutureTask<String> scoFutureTask;
static { BaseNode(Children children, Lookup lookup, S results, R rowData, ExecutorService backgroundTasksPool) {
//Initialize this pool only once! This will be used by every instance BaseNode
//to do their heavy duty SCO column and translation updates.
backgroundTasksPool = Executors.newFixedThreadPool(MAX_POOL_SIZE,
new ThreadFactoryBuilder().setNameFormat("BaseNode-background-task-%d").build());
}
BaseNode(Children children, Lookup lookup, S results, R rowData) {
super(children, lookup); super(children, lookup);
this.results = results; this.results = results;
this.rowData = rowData; this.rowData = rowData;
this.backgroundTasksPool = backgroundTasksPool;
// If the S column is there register the listeners. // If the S column is there register the listeners.
if (results.getColumns().stream().map(p -> p.getDisplayName()).collect(Collectors.toList()).contains(SCOUtils.SCORE_COLUMN_NAME)) { if (results.getColumns().stream().map(p -> p.getDisplayName()).collect(Collectors.toList()).contains(SCOUtils.SCORE_COLUMN_NAME)) {
@ -218,7 +205,7 @@ abstract class BaseNode<S extends SearchResultsDTO, R extends BaseRowDTO> extend
scoFutureTask = null; scoFutureTask = null;
} }
if ((scoFutureTask == null || scoFutureTask.isDone()) && this instanceof SCOSupporter) { if ((backgroundTasksPool != null && !backgroundTasksPool.isShutdown() && !backgroundTasksPool.isTerminated()) && (scoFutureTask == null || scoFutureTask.isDone()) && this instanceof SCOSupporter) {
scoFutureTask = new FutureTask<>(new SCOFetcher<>(new WeakReference<>((SCOSupporter) this)), ""); scoFutureTask = new FutureTask<>(new SCOFetcher<>(new WeakReference<>((SCOSupporter) this)), "");
backgroundTasksPool.submit(scoFutureTask); backgroundTasksPool.submit(scoFutureTask);
} }
@ -318,4 +305,8 @@ abstract class BaseNode<S extends SearchResultsDTO, R extends BaseRowDTO> extend
public Action getPreferredAction() { public Action getPreferredAction() {
return DirectoryTreeTopComponent.getOpenChildAction(getName()); return DirectoryTreeTopComponent.getOpenChildAction(getName());
} }
protected ExecutorService getTaskPool() {
return backgroundTasksPool;
}
} }

View File

@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.mainui.nodes;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.openide.nodes.Children; import org.openide.nodes.Children;
@ -54,8 +55,8 @@ public final class BlackboardArtifactTagNode extends BaseNode<SearchResultsDTO,
private static final Logger logger = Logger.getLogger(BlackboardArtifactTagNode.class.getName()); private static final Logger logger = Logger.getLogger(BlackboardArtifactTagNode.class.getName());
public BlackboardArtifactTagNode(SearchResultsDTO results, BlackboardArtifactTagsRowDTO rowData) { public BlackboardArtifactTagNode(SearchResultsDTO results, BlackboardArtifactTagsRowDTO rowData, ExecutorService backgroundTasksPool) {
super(Children.LEAF, createLookup(rowData.getTag()), results, rowData); super(Children.LEAF, createLookup(rowData.getTag()), results, rowData, backgroundTasksPool);
this.rowData = rowData; this.rowData = rowData;
this.columns = results.getColumns(); this.columns = results.getColumns();
setDisplayName(rowData.getDisplayName()); setDisplayName(rowData.getDisplayName());

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.mainui.nodes;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutorService;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.nodes.Node; import org.openide.nodes.Node;
import org.openide.nodes.Sheet; import org.openide.nodes.Sheet;
@ -48,8 +49,8 @@ public final class ContentTagNode extends BaseNode<SearchResultsDTO, ContentTags
* @param results Search results. * @param results Search results.
* @param rowData Row data. * @param rowData Row data.
*/ */
public ContentTagNode(SearchResultsDTO results, ContentTagsRowDTO rowData) { public ContentTagNode(SearchResultsDTO results, ContentTagsRowDTO rowData, ExecutorService backgroundTasksPool) {
super(Children.LEAF, createLookup(rowData.getTag()), results, rowData); super(Children.LEAF, createLookup(rowData.getTag()), results, rowData, backgroundTasksPool);
this.rowData = rowData; this.rowData = rowData;
this.columns = results.getColumns(); this.columns = results.getColumns();
setDisplayName(rowData.getDisplayName()); setDisplayName(rowData.getDisplayName());

View File

@ -19,6 +19,7 @@
package org.sleuthkit.autopsy.mainui.nodes; package org.sleuthkit.autopsy.mainui.nodes;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.nodes.Node; import org.openide.nodes.Node;
@ -37,11 +38,12 @@ public class CreditCardByFileNode extends BaseNode<SearchResultsDTO, CreditCardB
.toArray(); .toArray();
} }
public CreditCardByFileNode(SearchResultsDTO results, CreditCardByFileRowDTO rowData) { public CreditCardByFileNode(SearchResultsDTO results, CreditCardByFileRowDTO rowData, ExecutorService backgroundTasksPool) {
super(Children.LEAF, super(Children.LEAF,
Lookups.fixed(getLookupItems(rowData)), Lookups.fixed(getLookupItems(rowData)),
results, results,
rowData); rowData,
backgroundTasksPool);
setName(rowData.getFileName() + rowData.getId()); setName(rowData.getFileName() + rowData.getId());
setDisplayName(rowData.getFileName()); setDisplayName(rowData.getFileName());

View File

@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.mainui.nodes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.logging.Level; import java.util.logging.Level;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
@ -52,12 +53,12 @@ public class DataArtifactNode extends ArtifactNode<DataArtifact, DataArtifactRow
} }
} }
public DataArtifactNode(DataArtifactTableSearchResultsDTO tableData, DataArtifactRowDTO artifactRow) { public DataArtifactNode(DataArtifactTableSearchResultsDTO tableData, DataArtifactRowDTO artifactRow, ExecutorService backgroundTasksPool) {
this(tableData, artifactRow, getIconFilePath(tableData)); this(tableData, artifactRow, getIconFilePath(tableData), backgroundTasksPool);
} }
public DataArtifactNode(DataArtifactTableSearchResultsDTO tableData, DataArtifactRowDTO artifactRow, String iconPath) { public DataArtifactNode(DataArtifactTableSearchResultsDTO tableData, DataArtifactRowDTO artifactRow, String iconPath, ExecutorService backgroundTasksPool) {
super(tableData, artifactRow, tableData.getColumns(), createLookup(artifactRow), iconPath); super(tableData, artifactRow, tableData.getColumns(), createLookup(artifactRow), iconPath, backgroundTasksPool);
} }
@Override @Override

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.mainui.nodes;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutorService;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
@ -47,8 +48,8 @@ public class DirectoryNode extends BaseNode<SearchResultsDTO, DirectoryRowDTO> i
* @param results The search result DTO. * @param results The search result DTO.
* @param row The table row DTO. * @param row The table row DTO.
*/ */
public DirectoryNode(SearchResultsDTO results, DirectoryRowDTO row) { public DirectoryNode(SearchResultsDTO results, DirectoryRowDTO row, ExecutorService backgroundTasksPool) {
super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row); super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row, backgroundTasksPool);
setName(ContentNodeUtil.getContentName(row.getContent().getId())); setName(ContentNodeUtil.getContentName(row.getContent().getId()));
setDisplayName(ContentNodeUtil.getContentDisplayName(row.getContent().getName())); setDisplayName(ContentNodeUtil.getContentDisplayName(row.getContent().getName()));
setShortDescription(ContentNodeUtil.getContentDisplayName(row.getContent().getName())); setShortDescription(ContentNodeUtil.getContentDisplayName(row.getContent().getName()));

View File

@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.mainui.nodes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.Action; import javax.swing.Action;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -69,13 +70,13 @@ public class FileNode extends BaseNode<SearchResultsDTO, FileRowDTO> implements
private final FileRowDTO fileData; private final FileRowDTO fileData;
private final List<ColumnKey> columns; private final List<ColumnKey> columns;
public FileNode(SearchResultsDTO results, FileRowDTO file) { public FileNode(SearchResultsDTO results, FileRowDTO file, ExecutorService backgroundTasksPool) {
this(results, file, true); this(results, file, true, backgroundTasksPool);
} }
public FileNode(SearchResultsDTO results, FileRowDTO file, boolean directoryBrowseMode) { public FileNode(SearchResultsDTO results, FileRowDTO file, boolean directoryBrowseMode, ExecutorService backgroundTasksPool) {
// GVDTODO: at some point, this leaf will need to allow for children // GVDTODO: at some point, this leaf will need to allow for children
super(Children.LEAF, ContentNodeUtil.getLookup(file.getAbstractFile()), results, file); super(Children.LEAF, ContentNodeUtil.getLookup(file.getAbstractFile()), results, file, backgroundTasksPool);
setIcon(file); setIcon(file);
setName(ContentNodeUtil.getContentName(file.getId())); setName(ContentNodeUtil.getContentName(file.getId()));
setDisplayName(ContentNodeUtil.getContentDisplayName(file.getFileName())); setDisplayName(ContentNodeUtil.getContentDisplayName(file.getFileName()));
@ -266,8 +267,8 @@ public class FileNode extends BaseNode<SearchResultsDTO, FileRowDTO> implements
private final LayoutFileRowDTO layoutFileRow; private final LayoutFileRowDTO layoutFileRow;
public LayoutFileNode(SearchResultsDTO results, LayoutFileRowDTO file) { public LayoutFileNode(SearchResultsDTO results, LayoutFileRowDTO file, ExecutorService backgroundTasksPool) {
super(results, file, true); super(results, file, true, backgroundTasksPool);
layoutFileRow = file; layoutFileRow = file;
} }
@ -296,8 +297,8 @@ public class FileNode extends BaseNode<SearchResultsDTO, FileRowDTO> implements
*/ */
public static class SlackFileNode extends FileNode { public static class SlackFileNode extends FileNode {
public SlackFileNode(SearchResultsDTO results, SlackFileRowDTO file) { public SlackFileNode(SearchResultsDTO results, SlackFileRowDTO file, ExecutorService backgroundTasksPool) {
super(results, file); super(results, file, backgroundTasksPool);
} }
@Override @Override

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.mainui.nodes;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutorService;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.nodes.Node; import org.openide.nodes.Node;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
@ -42,8 +43,8 @@ public class ImageNode extends BaseNode<SearchResultsDTO, ImageRowDTO> implement
* @param results The search result DTO. * @param results The search result DTO.
* @param row The table row DTO. * @param row The table row DTO.
*/ */
public ImageNode(SearchResultsDTO results, ImageRowDTO row) { public ImageNode(SearchResultsDTO results, ImageRowDTO row, ExecutorService backgroundTasksPool) {
super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row); super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row, backgroundTasksPool);
setName(ContentNodeUtil.getContentName(row.getContent().getId())); setName(ContentNodeUtil.getContentName(row.getContent().getId()));
setDisplayName(row.getContent().getName()); setDisplayName(row.getContent().getName());
setShortDescription(row.getContent().getName()); setShortDescription(row.getContent().getName());

View File

@ -22,6 +22,7 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.concurrent.FutureTask; import java.util.concurrent.FutureTask;
import java.util.logging.Level; import java.util.logging.Level;
@ -43,7 +44,6 @@ import org.sleuthkit.autopsy.datamodel.TskContentItem;
import org.sleuthkit.autopsy.mainui.datamodel.ContentRowDTO.OsAccountRowDTO; import org.sleuthkit.autopsy.mainui.datamodel.ContentRowDTO.OsAccountRowDTO;
import org.sleuthkit.autopsy.mainui.datamodel.OsAccountsDAO; import org.sleuthkit.autopsy.mainui.datamodel.OsAccountsDAO;
import org.sleuthkit.autopsy.mainui.datamodel.SearchResultsDTO; import org.sleuthkit.autopsy.mainui.datamodel.SearchResultsDTO;
import static org.sleuthkit.autopsy.mainui.nodes.BaseNode.backgroundTasksPool;
import org.sleuthkit.autopsy.mainui.sco.SCOSupporter; import org.sleuthkit.autopsy.mainui.sco.SCOSupporter;
import org.sleuthkit.autopsy.mainui.sco.SCOUtils; import org.sleuthkit.autopsy.mainui.sco.SCOUtils;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
@ -64,11 +64,12 @@ public class OsAccountNode extends BaseNode<SearchResultsDTO, OsAccountRowDTO> i
private FutureTask<String> realmFutureTask = null; private FutureTask<String> realmFutureTask = null;
public OsAccountNode(SearchResultsDTO results, OsAccountRowDTO rowData) { public OsAccountNode(SearchResultsDTO results, OsAccountRowDTO rowData, ExecutorService backgroundTasksPool) {
super(Children.LEAF, super(Children.LEAF,
Lookups.fixed(rowData.getContent(), new TskContentItem<>(rowData.getContent())), Lookups.fixed(rowData.getContent(), new TskContentItem<>(rowData.getContent())),
results, results,
rowData); rowData,
backgroundTasksPool);
String name = rowData.getContent().getName(); String name = rowData.getContent().getName();
setName(ContentNodeUtil.getContentName(rowData.getContent().getId())); setName(ContentNodeUtil.getContentName(rowData.getContent().getId()));
setDisplayName(name); setDisplayName(name);
@ -112,9 +113,10 @@ public class OsAccountNode extends BaseNode<SearchResultsDTO, OsAccountRowDTO> i
realmFutureTask = null; realmFutureTask = null;
} }
if ((realmFutureTask == null || realmFutureTask.isDone())) { ExecutorService threadPool = getTaskPool();
if ((threadPool != null && !threadPool.isShutdown() && !threadPool.isTerminated()) && (realmFutureTask == null || realmFutureTask.isDone())) {
realmFutureTask = new FutureTask<>(new RealmFetcher<>(new WeakReference<>(this)), ""); realmFutureTask = new FutureTask<>(new RealmFetcher<>(new WeakReference<>(this)), "");
backgroundTasksPool.submit(realmFutureTask); threadPool.submit(realmFutureTask);
} }
} }
@Override @Override

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.mainui.nodes;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutorService;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.autopsy.datamodel.NodeProperty;
@ -40,10 +41,10 @@ public class PoolNode extends BaseNode<SearchResultsDTO, PoolRowDTO> implements
* @param results Search Result DTO. * @param results Search Result DTO.
* @param row Pool table row DTO. * @param row Pool table row DTO.
*/ */
public PoolNode(SearchResultsDTO results, PoolRowDTO row) { public PoolNode(SearchResultsDTO results, PoolRowDTO row, ExecutorService backgroundTasksPool) {
super(Children.LEAF, super(Children.LEAF,
Lookups.fixed(row.getContent(), new TskContentItem<>(row.getContent())), Lookups.fixed(row.getContent(), new TskContentItem<>(row.getContent())),
results, row); results, row, backgroundTasksPool);
String name = row.getContent().getType().getName(); String name = row.getContent().getType().getName();
setName(ContentNodeUtil.getContentName(row.getContent().getId())); setName(ContentNodeUtil.getContentName(row.getContent().getId()));

View File

@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.mainui.nodes;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.openide.nodes.ChildFactory; import org.openide.nodes.ChildFactory;
@ -60,9 +61,12 @@ public class SearchResultChildFactory extends ChildFactory<ChildKey> {
private static final Logger logger = Logger.getLogger(SearchResultChildFactory.class.getName()); private static final Logger logger = Logger.getLogger(SearchResultChildFactory.class.getName());
private SearchResultsDTO results; private SearchResultsDTO results;
private final ExecutorService nodeThreadPool;
public SearchResultChildFactory(SearchResultsDTO initialResults) { public SearchResultChildFactory(SearchResultsDTO initialResults, ExecutorService nodeThreadPool) {
this.results = initialResults; this.results = initialResults;
this.nodeThreadPool = nodeThreadPool;
} }
@Override @Override
@ -85,37 +89,37 @@ public class SearchResultChildFactory extends ChildFactory<ChildKey> {
String typeId = key.getRow().getTypeId(); String typeId = key.getRow().getTypeId();
try { try {
if (DataArtifactRowDTO.getTypeIdForClass().equals(typeId)) { if (DataArtifactRowDTO.getTypeIdForClass().equals(typeId)) {
return new DataArtifactNode((DataArtifactTableSearchResultsDTO) key.getSearchResults(), (DataArtifactRowDTO) key.getRow()); return new DataArtifactNode((DataArtifactTableSearchResultsDTO) key.getSearchResults(), (DataArtifactRowDTO) key.getRow(), nodeThreadPool);
} else if (FileRowDTO.getTypeIdForClass().equals(typeId)) { } else if (FileRowDTO.getTypeIdForClass().equals(typeId)) {
return new FileNode(key.getSearchResults(), (FileRowDTO) key.getRow(), true); return new FileNode(key.getSearchResults(), (FileRowDTO) key.getRow(), true, nodeThreadPool);
} else if (AnalysisResultRowDTO.getTypeIdForClass().equals(typeId)) { } else if (AnalysisResultRowDTO.getTypeIdForClass().equals(typeId)) {
return new AnalysisResultNode((AnalysisResultTableSearchResultsDTO) key.getSearchResults(), (AnalysisResultRowDTO) key.getRow()); return new AnalysisResultNode((AnalysisResultTableSearchResultsDTO) key.getSearchResults(), (AnalysisResultRowDTO) key.getRow(), nodeThreadPool);
} else if (ContentTagsRowDTO.getTypeIdForClass().equals(typeId)) { } else if (ContentTagsRowDTO.getTypeIdForClass().equals(typeId)) {
return new ContentTagNode(key.getSearchResults(), (ContentTagsRowDTO) key.getRow()); return new ContentTagNode(key.getSearchResults(), (ContentTagsRowDTO) key.getRow(), nodeThreadPool);
} else if (BlackboardArtifactTagsRowDTO.getTypeIdForClass().equals(typeId)) { } else if (BlackboardArtifactTagsRowDTO.getTypeIdForClass().equals(typeId)) {
return new BlackboardArtifactTagNode(key.getSearchResults(), (BlackboardArtifactTagsRowDTO) key.getRow()); return new BlackboardArtifactTagNode(key.getSearchResults(), (BlackboardArtifactTagsRowDTO) key.getRow(), nodeThreadPool);
} else if (ImageRowDTO.getTypeIdForClass().equals(typeId)) { } else if (ImageRowDTO.getTypeIdForClass().equals(typeId)) {
return new ImageNode(key.getSearchResults(), (ImageRowDTO) key.getRow()); return new ImageNode(key.getSearchResults(), (ImageRowDTO) key.getRow(), nodeThreadPool);
} else if (LocalFileDataSourceRowDTO.getTypeIdForClass().equals(typeId)) { } else if (LocalFileDataSourceRowDTO.getTypeIdForClass().equals(typeId)) {
return new LocalFileDataSourceNode(key.getSearchResults(), (LocalFileDataSourceRowDTO) key.getRow()); return new LocalFileDataSourceNode(key.getSearchResults(), (LocalFileDataSourceRowDTO) key.getRow(), nodeThreadPool);
} else if (DirectoryRowDTO.getTypeIdForClass().equals(typeId)) { } else if (DirectoryRowDTO.getTypeIdForClass().equals(typeId)) {
return new DirectoryNode(key.getSearchResults(), (DirectoryRowDTO) key.getRow()); return new DirectoryNode(key.getSearchResults(), (DirectoryRowDTO) key.getRow(), nodeThreadPool);
} else if (VolumeRowDTO.getTypeIdForClass().equals(typeId)) { } else if (VolumeRowDTO.getTypeIdForClass().equals(typeId)) {
return new VolumeNode(key.getSearchResults(), (VolumeRowDTO) key.getRow()); return new VolumeNode(key.getSearchResults(), (VolumeRowDTO) key.getRow(), nodeThreadPool);
} else if (LocalDirectoryRowDTO.getTypeIdForClass().equals(typeId)) { } else if (LocalDirectoryRowDTO.getTypeIdForClass().equals(typeId)) {
return new LocalDirectoryNode(key.getSearchResults(), (LocalDirectoryRowDTO) key.getRow()); return new LocalDirectoryNode(key.getSearchResults(), (LocalDirectoryRowDTO) key.getRow(), nodeThreadPool);
} else if (VirtualDirectoryRowDTO.getTypeIdForClass().equals(typeId)) { } else if (VirtualDirectoryRowDTO.getTypeIdForClass().equals(typeId)) {
return new VirtualDirectoryNode(key.getSearchResults(), (VirtualDirectoryRowDTO) key.getRow()); return new VirtualDirectoryNode(key.getSearchResults(), (VirtualDirectoryRowDTO) key.getRow(), nodeThreadPool);
} else if (LayoutFileRowDTO.getTypeIdForClass().equals(typeId)) { } else if (LayoutFileRowDTO.getTypeIdForClass().equals(typeId)) {
return new LayoutFileNode(key.getSearchResults(), (LayoutFileRowDTO) key.getRow()); return new LayoutFileNode(key.getSearchResults(), (LayoutFileRowDTO) key.getRow(), nodeThreadPool);
} else if (PoolRowDTO.getTypeIdForClass().equals(typeId)) { } else if (PoolRowDTO.getTypeIdForClass().equals(typeId)) {
return new PoolNode(key.getSearchResults(), (PoolRowDTO) key.getRow()); return new PoolNode(key.getSearchResults(), (PoolRowDTO) key.getRow(), nodeThreadPool);
} else if (SlackFileRowDTO.getTypeIdForClass().equals(typeId)) { } else if (SlackFileRowDTO.getTypeIdForClass().equals(typeId)) {
return new SlackFileNode(key.getSearchResults(), (SlackFileRowDTO) key.getRow()); return new SlackFileNode(key.getSearchResults(), (SlackFileRowDTO) key.getRow(), nodeThreadPool);
} else if (OsAccountRowDTO.getTypeIdForClass().equals(typeId)) { } else if (OsAccountRowDTO.getTypeIdForClass().equals(typeId)) {
return new OsAccountNode(key.getSearchResults(), (OsAccountRowDTO) key.getRow()); return new OsAccountNode(key.getSearchResults(), (OsAccountRowDTO) key.getRow(), nodeThreadPool);
} else if (CreditCardByFileRowDTO.getTypeIdForClass().equals(typeId)) { } else if (CreditCardByFileRowDTO.getTypeIdForClass().equals(typeId)) {
return new CreditCardByFileNode(key.getSearchResults(), (CreditCardByFileRowDTO) key.getRow()); return new CreditCardByFileNode(key.getSearchResults(), (CreditCardByFileRowDTO) key.getRow(), nodeThreadPool);
}else { }else {
logger.log(Level.WARNING, MessageFormat.format("No known node for type id: {0} provided by row result: {1}", typeId, key.getRow())); logger.log(Level.WARNING, MessageFormat.format("No known node for type id: {0} provided by row result: {1}", typeId, key.getRow()));
} }

View File

@ -18,6 +18,7 @@
*/ */
package org.sleuthkit.autopsy.mainui.nodes; package org.sleuthkit.autopsy.mainui.nodes;
import java.util.concurrent.ExecutorService;
import org.openide.nodes.AbstractNode; import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.nodes.Sheet; import org.openide.nodes.Sheet;
@ -38,8 +39,8 @@ public class SearchResultRootNode extends AbstractNode {
// therefore is not included in the equals and hashcode methods. // therefore is not included in the equals and hashcode methods.
private ChildNodeSelectionInfo childNodeSelectionInfo; private ChildNodeSelectionInfo childNodeSelectionInfo;
public SearchResultRootNode(SearchResultsDTO initialResults) { public SearchResultRootNode(SearchResultsDTO initialResults, ExecutorService nodeThreadPool) {
this(initialResults, new SearchResultChildFactory(initialResults)); this(initialResults, new SearchResultChildFactory(initialResults, nodeThreadPool));
} }
private SearchResultRootNode(SearchResultsDTO initialResults, SearchResultChildFactory factory) { private SearchResultRootNode(SearchResultsDTO initialResults, SearchResultChildFactory factory) {

View File

@ -18,9 +18,9 @@
*/ */
package org.sleuthkit.autopsy.mainui.nodes; package org.sleuthkit.autopsy.mainui.nodes;
import java.lang.ref.WeakReference;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutorService;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.nodes.Node; import org.openide.nodes.Node;
import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.autopsy.datamodel.NodeProperty;
@ -45,8 +45,8 @@ abstract class SpecialDirectoryNode extends BaseNode<SearchResultsDTO, ContentRo
* @param results The search result DTO. * @param results The search result DTO.
* @param row The table row DTO. * @param row The table row DTO.
*/ */
private SpecialDirectoryNode(SearchResultsDTO results, ContentRowDTO<? extends SpecialDirectory> row) { private SpecialDirectoryNode(SearchResultsDTO results, ContentRowDTO<? extends SpecialDirectory> row, ExecutorService backgroundTasksPool) {
super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row); super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row, backgroundTasksPool);
setName(ContentNodeUtil.getContentName(row.getContent().getId())); setName(ContentNodeUtil.getContentName(row.getContent().getId()));
setDisplayName(row.getContent().getName()); setDisplayName(row.getContent().getName());
setShortDescription(row.getContent().getName()); setShortDescription(row.getContent().getName());
@ -105,8 +105,8 @@ abstract class SpecialDirectoryNode extends BaseNode<SearchResultsDTO, ContentRo
* @param results The search result DTO. * @param results The search result DTO.
* @param row The table row DTO. * @param row The table row DTO.
*/ */
public LocalDirectoryNode(SearchResultsDTO results, LocalDirectoryRowDTO row) { public LocalDirectoryNode(SearchResultsDTO results, LocalDirectoryRowDTO row, ExecutorService backgroundTasksPool) {
super(results, row); super(results, row, backgroundTasksPool);
setIconBaseWithExtension("org/sleuthkit/autopsy/images/Folder-icon.png"); setIconBaseWithExtension("org/sleuthkit/autopsy/images/Folder-icon.png");
} }
} }
@ -122,8 +122,8 @@ abstract class SpecialDirectoryNode extends BaseNode<SearchResultsDTO, ContentRo
* @param results The search result DTO. * @param results The search result DTO.
* @param row The table row DTO. * @param row The table row DTO.
*/ */
public VirtualDirectoryNode(SearchResultsDTO results, VirtualDirectoryRowDTO row) { public VirtualDirectoryNode(SearchResultsDTO results, VirtualDirectoryRowDTO row, ExecutorService backgroundTasksPool) {
super(results, row); super(results, row, backgroundTasksPool);
setIconBaseWithExtension("org/sleuthkit/autopsy/images/folder-icon-virtual.png"); setIconBaseWithExtension("org/sleuthkit/autopsy/images/folder-icon-virtual.png");
} }
} }
@ -141,8 +141,8 @@ abstract class SpecialDirectoryNode extends BaseNode<SearchResultsDTO, ContentRo
* @param results The search result DTO. * @param results The search result DTO.
* @param row The table row DTO. * @param row The table row DTO.
*/ */
public LocalFileDataSourceNode(SearchResultsDTO results, LocalFileDataSourceRowDTO row) { public LocalFileDataSourceNode(SearchResultsDTO results, LocalFileDataSourceRowDTO row, ExecutorService backgroundTasksPool) {
super(results, row); super(results, row, backgroundTasksPool);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/fileset-icon-16.png"); //NON-NLS this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/fileset-icon-16.png"); //NON-NLS
} }
} }

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.mainui.nodes;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutorService;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.nodes.Node; import org.openide.nodes.Node;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
@ -44,8 +45,8 @@ public class VolumeNode extends BaseNode<SearchResultsDTO, VolumeRowDTO> impleme
* @param results The search result DTO. * @param results The search result DTO.
* @param row The table row DTO. * @param row The table row DTO.
*/ */
public VolumeNode(SearchResultsDTO results, VolumeRowDTO row) { public VolumeNode(SearchResultsDTO results, VolumeRowDTO row, ExecutorService backgroundTasksPool) {
super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row); super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row, backgroundTasksPool);
setIconBaseWithExtension(NodeIconUtil.VOLUME.getPath()); //NON-NLS setIconBaseWithExtension(NodeIconUtil.VOLUME.getPath()); //NON-NLS
// use first cell value for display name // use first cell value for display name

View File

@ -61,9 +61,10 @@ import org.sleuthkit.autopsy.directorytree.ExportCSVAction;
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
import org.sleuthkit.autopsy.directorytree.ExternalViewerShortcutAction; import org.sleuthkit.autopsy.directorytree.ExternalViewerShortcutAction;
import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.FileSearchAction; import org.sleuthkit.autopsy.directorytree.FileSearchTreeAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.directorytree.ViewContextAction; import org.sleuthkit.autopsy.directorytree.ViewContextAction;
import org.sleuthkit.autopsy.filesearch.FileSearchAction;
import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.RunIngestModulesAction; import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.RunIngestModulesAction;
import org.sleuthkit.autopsy.modules.embeddedfileextractor.ExtractArchiveWithPasswordAction; import org.sleuthkit.autopsy.modules.embeddedfileextractor.ExtractArchiveWithPasswordAction;
import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction; import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction;
@ -173,26 +174,6 @@ public final class ActionsFactory {
actionGroups.add(new ActionGroup(new ExtractArchiveWithPasswordAction(optionalFile.get()))); actionGroups.add(new ActionGroup(new ExtractArchiveWithPasswordAction(optionalFile.get())));
} }
Optional<BlackboardArtifact.Type> analysisResultType = actionContext.getAnalysisResultType();
if (analysisResultType.isPresent() && actionContext.hasAnalysisResultConfigurations()) {
Optional<Long> dataSourceId = actionContext.getDataSourceIdForActions();
actionGroups.add(new ActionGroup(new AbstractAction("Delete Analysis Results of Type") {
@Override
public void actionPerformed(ActionEvent e) {
List<String> configurations = actionContext.getAnalysisResultConfigurations();
JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
MessageFormat.format("Stub Action for deleting analysis result type: {0} with configurations [{1}] and data source of {2}",
analysisResultType.get().getDisplayName(),
configurations.stream().map(c -> c == null ? "<Null>" : "\"" + c + "\"").collect(Collectors.joining(",")),
dataSourceId.map(d -> Long.toString(d)).orElse("<Null or Empty>")),
"Deleting...",
JOptionPane.WARNING_MESSAGE);
}
}));
}
List<Action> actionList = new ArrayList<>(); List<Action> actionList = new ArrayList<>();
for (ActionGroup aGroup : actionGroups) { for (ActionGroup aGroup : actionGroups) {
if (aGroup != null) { if (aGroup != null) {
@ -511,7 +492,7 @@ public final class ActionsFactory {
ActionGroup group = new ActionGroup(); ActionGroup group = new ActionGroup();
Optional<Content> optional = context.getDataSourceForActions(); Optional<Content> optional = context.getDataSourceForActions();
if(optional.isPresent()) { if(optional.isPresent()) {
group.add(new FileSearchAction(Bundle.ActionFactory_openFileSearchByAttr_text(), optional.get().getId())); group.add(new FileSearchTreeAction(Bundle.ActionFactory_openFileSearchByAttr_text(), optional.get().getId()));
group.add(new ViewSummaryInformationAction(optional.get().getId())); group.add(new ViewSummaryInformationAction(optional.get().getId()));
group.add(new RunIngestModulesAction(Collections.<Content>singletonList(optional.get()))); group.add(new RunIngestModulesAction(Collections.<Content>singletonList(optional.get())));
group.add(new DeleteDataSourceAction(optional.get().getId())); group.add(new DeleteDataSourceAction(optional.get().getId()));
@ -522,7 +503,7 @@ public final class ActionsFactory {
if(optional.isPresent()) { if(optional.isPresent()) {
if (optional.get() instanceof AbstractFile) { if (optional.get() instanceof AbstractFile) {
if(context.supportsFileSearchAction()) { if(context.supportsFileSearchAction()) {
group.add(new FileSearchAction(Bundle.ActionFactory_openFileSearchByAttr_text(), optional.get().getId())); group.add(new FileSearchTreeAction(Bundle.ActionFactory_openFileSearchByAttr_text(), optional.get().getId()));
} }
group.add(new RunIngestModulesAction((AbstractFile)optional.get())); group.add(new RunIngestModulesAction((AbstractFile)optional.get()));

View File

@ -24,3 +24,15 @@ ArtifactFactory_getViewSrcContentAction_displayName=View Source {0} in Directory
# {0} - contentType # {0} - contentType
ArtifactFactory_getViewSrcContentAction_displayName2=View Source {0} ArtifactFactory_getViewSrcContentAction_displayName2=View Source {0}
DeleteAnalysisResultAction_label=Delete Analysis Result DeleteAnalysisResultAction_label=Delete Analysis Result
DeleteAnalysisResultsAction.label=Delete Analysis Results
# {0} - result type
DeleteAnalysisResultsAction.progress.allResults=Deleting Analysis Results type {0}
# {0} - result type
# {1} - configuration
DeleteAnalysisResultsAction.progress.allResultsWithConfiguration=Deleting Analysis Results type {0} and configuration {1}
DeleteAnalysisResultsAction.title=Deleting Analysis Results
# {0} - result type
DeleteAnalysisResultsAction.warning.allResults=Are you sure you want to delete all Analysis Results of type {0}?
# {0} - result type
# {1} - configuration
DeleteAnalysisResultsAction.warning.allResultsWithConfiguration=Are you sure you want to delete all Analysis Results of type {0} and configuration {1}?

View File

@ -0,0 +1,115 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2022 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.mainui.nodes.actions;
import java.awt.event.ActionEvent;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.progress.AppFrameProgressBar;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Action class for Deleting Analysis Result objects.
*/
public class DeleteAnalysisResultSetAction extends AbstractAction {
@Messages({
"DeleteAnalysisResultsAction.label=Delete Analysis Results",
"DeleteAnalysisResultsAction.title=Deleting Analysis Results",
"# {0} - result type",
"DeleteAnalysisResultsAction.progress.allResults=Deleting Analysis Results type {0}",
"# {0} - result type", "# {1} - configuration",
"DeleteAnalysisResultsAction.progress.allResultsWithConfiguration=Deleting Analysis Results type {0} and configuration {1}",
"# {0} - result type",
"DeleteAnalysisResultsAction.warning.allResults=Are you sure you want to delete all Analysis Results of type {0}?",
"# {0} - result type", "# {1} - configuration",
"DeleteAnalysisResultsAction.warning.allResultsWithConfiguration=Are you sure you want to delete all Analysis Results of type {0} and configuration {1}?"
})
private static final Logger logger = Logger.getLogger(DeleteAnalysisResultSetAction.class.getName());
private static final long serialVersionUID = 1L;
private final BlackboardArtifact.Type type;
private final String configuration;
private final Long dsID;
public DeleteAnalysisResultSetAction(BlackboardArtifact.Type type, String configuration, Long dsID) {
super(Bundle.DeleteAnalysisResultsAction_label());
this.type = type;
this.configuration = configuration;
this.dsID = dsID;
}
@Override
public void actionPerformed(ActionEvent e) {
String warningMessage;
String progressMessage;
if (configuration == null || configuration.isEmpty()) {
warningMessage = Bundle.DeleteAnalysisResultsAction_warning_allResults(type.getDisplayName());
progressMessage = Bundle.DeleteAnalysisResultsAction_progress_allResults(type.getDisplayName());
} else {
warningMessage = Bundle.DeleteAnalysisResultsAction_warning_allResultsWithConfiguration(type.getDisplayName(), configuration);
progressMessage = Bundle.DeleteAnalysisResultsAction_progress_allResultsWithConfiguration(type.getDisplayName(), configuration);
}
int response = JOptionPane.showConfirmDialog(
WindowManager.getDefault().getMainWindow(),
warningMessage,
Bundle.DeleteAnalysisResultsAction_title(),
JOptionPane.YES_NO_OPTION);
if (response != JOptionPane.YES_OPTION) {
return;
}
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
AppFrameProgressBar progress = new AppFrameProgressBar(Bundle.DeleteAnalysisResultsAction_title());
try {
progress.start(progressMessage);
progress.switchToIndeterminate(progressMessage);
if (!isCancelled()) {
try {
logger.log(Level.INFO, "Deleting Analysis Results type = {0}, data source ID = {1}, configuration = {2}", new Object[]{type, dsID, configuration});
Case.getCurrentCase().getSleuthkitCase().getBlackboard().deleteAnalysisResults(type, dsID, configuration);
logger.log(Level.INFO, "Deleted Analysis Results type = {0}, data source ID = {1}, configuration = {2}", new Object[]{type, dsID, configuration});
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to delete analysis results of type = "+type+", data source ID = "+dsID+", configuration = "+configuration, ex);
}
}
return null;
} finally {
progress.finish();
}
}
};
worker.execute();
}
}

View File

@ -70,9 +70,8 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule {
private static final String ALEAPP_FS = "fs_"; //NON-NLS private static final String ALEAPP_FS = "fs_"; //NON-NLS
private static final String ALEAPP_EXECUTABLE = "aleapp.exe";//NON-NLS private static final String ALEAPP_EXECUTABLE = "aleapp.exe";//NON-NLS
private static final String ALEAPP_PATHS_FILE = "aLeapp_paths.txt"; //NON-NLS private static final String ALEAPP_PATHS_FILE = "aLeapp_paths.txt"; //NON-NLS
private static final String XMLFILE = "aleap-artifact-attribute-reference.xml"; //NON-NLS
private static final String XMLFILE = "aleap-artifact-attribute-reference.xml"; //NON-NLS
private File aLeappExecutable; private File aLeappExecutable;
@ -118,8 +117,8 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule {
@NbBundle.Messages({ @NbBundle.Messages({
"ALeappAnalyzerIngestModule.error.running.aLeapp=Error running aLeapp, see log file.", "ALeappAnalyzerIngestModule.error.running.aLeapp=Error running aLeapp, see log file.",
"ALeappAnalyzerIngestModule.error.creating.output.dir=Error creating aLeapp module output directory.", "ALeappAnalyzerIngestModule.error.creating.output.dir=Error creating aLeapp module output directory.",
"ALeappAnalyzerIngestModule.starting.aLeapp=Starting aLeapp",
"ALeappAnalyzerIngestModule.running.aLeapp=Running aLeapp", "ALeappAnalyzerIngestModule.running.aLeapp=Running aLeapp",
"ALeappAnalyzerIngestModule_processing_aLeapp_results=Processing aLeapp results",
"ALeappAnalyzerIngestModule.has.run=aLeapp", "ALeappAnalyzerIngestModule.has.run=aLeapp",
"ALeappAnalyzerIngestModule.aLeapp.cancelled=aLeapp run was canceled", "ALeappAnalyzerIngestModule.aLeapp.cancelled=aLeapp run was canceled",
"ALeappAnalyzerIngestModule.completed=aLeapp Processing Completed", "ALeappAnalyzerIngestModule.completed=aLeapp Processing Completed",
@ -127,51 +126,62 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule {
@Override @Override
public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper) { public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper) {
statusHelper.switchToIndeterminate();
statusHelper.progress(Bundle.ALeappAnalyzerIngestModule_running_aLeapp());
Case currentCase = Case.getCurrentCase(); Case currentCase = Case.getCurrentCase();
Path tempOutputPath = Paths.get(currentCase.getTempDirectory(), ALEAPP, ALEAPP_FS + dataSource.getId()); Path tempOutputPath = Paths.get(currentCase.getTempDirectory(), ALEAPP, ALEAPP_FS + dataSource.getId());
try { try {
Files.createDirectories(tempOutputPath); Files.createDirectories(tempOutputPath);
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.SEVERE, String.format("Error creating aLeapp output directory %s", tempOutputPath.toString()), ex); logger.log(Level.SEVERE, String.format("Error creating aLeapp output directory %s", tempOutputPath.toString()), ex);
writeErrorMsgToIngestInbox();
return ProcessResult.ERROR; return ProcessResult.ERROR;
} }
List<String> aLeappPathsToProcess = new ArrayList<>(); List<String> aLeappPathsToProcess;
ProcessBuilder aLeappCommand = buildaLeappListCommand(tempOutputPath); ProcessBuilder aLeappCommand = buildaLeappListCommand(tempOutputPath);
try { try {
int result = ExecUtil.execute(aLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true)); int result = ExecUtil.execute(aLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true));
if (result != 0) { if (result != 0) {
logger.log(Level.SEVERE, String.format("Error when trying to execute aLeapp program getting file paths to search for result is %d", result)); logger.log(Level.SEVERE, String.format("Error when trying to execute aLeapp program getting file paths to search for result is %d", result));
writeErrorMsgToIngestInbox();
return ProcessResult.ERROR; return ProcessResult.ERROR;
} }
aLeappPathsToProcess = loadIleappPathFile(tempOutputPath); aLeappPathsToProcess = loadIleappPathFile(tempOutputPath);
if (aLeappPathsToProcess.isEmpty()) {
logger.log(Level.SEVERE, String.format("Error getting file paths to search, list is empty"));
writeErrorMsgToIngestInbox();
return ProcessResult.ERROR;
}
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.SEVERE, String.format("Error when trying to execute aLeapp program getting file paths to search"), ex); logger.log(Level.SEVERE, String.format("Error when trying to execute aLeapp program getting file paths to search"), ex);
writeErrorMsgToIngestInbox();
return ProcessResult.ERROR; return ProcessResult.ERROR;
} }
statusHelper.progress(Bundle.ALeappAnalyzerIngestModule_starting_aLeapp(), 0); if ((context.getDataSource() instanceof LocalFilesDataSource)) {
/*
List<AbstractFile> aLeappFilesToProcess = new ArrayList<>(); * The data source may be local files from an iOS file system, or it
* may be a tarred/ZIP of an iOS file system. If it is the latter,
if (!(context.getDataSource() instanceof LocalFilesDataSource)) { * extract the files we need to process.
extractFilesFromImage(dataSource, aLeappPathsToProcess, tempOutputPath); */
statusHelper.switchToDeterminate(aLeappFilesToProcess.size()); List<AbstractFile> aLeappFilesToProcess = LeappFileProcessor.findLeappFilesToProcess(dataSource);
processALeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString()); if (!aLeappFilesToProcess.isEmpty()) {
} else { statusHelper.switchToDeterminate(aLeappFilesToProcess.size());
aLeappFilesToProcess = LeappFileProcessor.findLeappFilesToProcess(dataSource); Integer filesProcessedCount = 0;
statusHelper.switchToDeterminate(aLeappFilesToProcess.size()); for (AbstractFile aLeappFile : aLeappFilesToProcess) {
processALeappFile(dataSource, currentCase, statusHelper, filesProcessedCount, aLeappFile);
Integer filesProcessedCount = 0; filesProcessedCount++;
for (AbstractFile aLeappFile : aLeappFilesToProcess) { }
processALeappFile(dataSource, currentCase, statusHelper, filesProcessedCount, aLeappFile);
filesProcessedCount++;
} }
// Process the logical image as a fs in aLeapp to make sure this is not a logical fs that was added
extractFilesFromImage(dataSource, aLeappPathsToProcess, tempOutputPath);
processALeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString());
} }
statusHelper.switchToIndeterminate();
statusHelper.progress(Bundle.ILeappAnalyzerIngestModule_processing_iLeapp_results());
extractFilesFromDataSource(dataSource, aLeappPathsToProcess, tempOutputPath);
processALeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString());
IngestMessage message = IngestMessage.createMessage(IngestMessage.MessageType.DATA, IngestMessage message = IngestMessage.createMessage(IngestMessage.MessageType.DATA,
Bundle.ALeappAnalyzerIngestModule_has_run(), Bundle.ALeappAnalyzerIngestModule_has_run(),
Bundle.ALeappAnalyzerIngestModule_completed()); Bundle.ALeappAnalyzerIngestModule_completed());
@ -181,14 +191,17 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule {
/** /**
* Process a file from a logical image using the aLeapp program * Process a file from a logical image using the aLeapp program
* @param dataSource datasource to process *
* @param currentCase current case that is being worked on * @param dataSource datasource to process
* @param statusHelper show progress and update what is being processed * @param currentCase current case that is being worked on
* @param statusHelper show progress and update what is being
* processed
* @param filesProcessedCount number of files that have been processed * @param filesProcessedCount number of files that have been processed
* @param aLeappFile the abstract file to process * @param aLeappFile the abstract file to process
*/ */
private void processALeappFile(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, int filesProcessedCount, private void processALeappFile(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, int filesProcessedCount,
AbstractFile aLeappFile) { AbstractFile aLeappFile) {
statusHelper.progress(NbBundle.getMessage(this.getClass(), "ALeappAnalyzerIngestModule.processing.file", aLeappFile.getName()), filesProcessedCount);
String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS
Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ALEAPP, currentTime); Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ALEAPP, currentTime);
try { try {
@ -198,7 +211,6 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule {
return; return;
} }
statusHelper.progress(NbBundle.getMessage(this.getClass(), "ALeappAnalyzerIngestModule.processing.file", aLeappFile.getName()), filesProcessedCount);
ProcessBuilder aLeappCommand = buildaLeappCommand(moduleOutputPath, aLeappFile.getLocalAbsPath(), aLeappFile.getNameExtension()); ProcessBuilder aLeappCommand = buildaLeappCommand(moduleOutputPath, aLeappFile.getLocalAbsPath(), aLeappFile.getNameExtension());
try { try {
int result = ExecUtil.execute(aLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true)); int result = ExecUtil.execute(aLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true));
@ -219,21 +231,20 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule {
return; return;
} }
ProcessResult fileProcessorResult = aLeappFileProcessor.processFiles(dataSource, moduleOutputPath, aLeappFile); aLeappFileProcessor.processFiles(dataSource, moduleOutputPath, aLeappFile);
if (fileProcessorResult == ProcessResult.ERROR) {
return;
}
} }
/** /**
* Process a image/directory using the aLeapp program * Process a image/directory using the aLeapp program
* @param dataSource datasource to process *
* @param currentCase current case being procesed * @param dataSource datasource to process
* @param statusHelper show progress and update what is being processed * @param currentCase current case being procesed
* @param statusHelper show progress and update what is being
* processed
* @param directoryToProcess directory to run aLeapp against * @param directoryToProcess directory to run aLeapp against
*/ */
private void processALeappFs(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, String directoryToProcess) { private void processALeappFs(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, String directoryToProcess) {
statusHelper.progress(NbBundle.getMessage(this.getClass(), "ALeappAnalyzerIngestModule.processing.filesystem"));
String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS
Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ALEAPP, currentTime); Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ALEAPP, currentTime);
try { try {
@ -243,7 +254,6 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule {
return; return;
} }
statusHelper.progress(NbBundle.getMessage(this.getClass(), "ALeappAnalyzerIngestModule.processing.filesystem"));
ProcessBuilder aLeappCommand = buildaLeappCommand(moduleOutputPath, directoryToProcess, "fs"); ProcessBuilder aLeappCommand = buildaLeappCommand(moduleOutputPath, directoryToProcess, "fs");
try { try {
int result = ExecUtil.execute(aLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true)); int result = ExecUtil.execute(aLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true));
@ -264,23 +274,16 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule {
return; return;
} }
ProcessResult fileProcessorResult = aLeappFileProcessor.processFileSystem(dataSource, moduleOutputPath); aLeappFileProcessor.processFileSystem(dataSource, moduleOutputPath);
if (fileProcessorResult == ProcessResult.ERROR) {
return;
}
} }
/** /**
* Build the aLeapp command to run * Build the aLeapp command to run
* *
* @param moduleOutputPath output path for the aLeapp program. * @param moduleOutputPath output path for the aLeapp program.
* @param sourceFilePath where the source files to process reside. * @param sourceFilePath where the source files to process reside.
* @param aLeappFileSystemType the filesystem type to process * @param aLeappFileSystemType the filesystem type to process
* *
* @return the command to execute * @return the command to execute
*/ */
private ProcessBuilder buildaLeappCommand(Path moduleOutputPath, String sourceFilePath, String aLeappFileSystemType) { private ProcessBuilder buildaLeappCommand(Path moduleOutputPath, String sourceFilePath, String aLeappFileSystemType) {
@ -311,8 +314,8 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule {
static private ProcessBuilder buildProcessWithRunAsInvoker(String... commandLine) { static private ProcessBuilder buildProcessWithRunAsInvoker(String... commandLine) {
ProcessBuilder processBuilder = new ProcessBuilder(commandLine); ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
/* /*
* Add an environment variable to force aLeapp to run with * Add an environment variable to force aLeapp to run with the same
* the same permissions Autopsy uses. * permissions Autopsy uses.
*/ */
processBuilder.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS processBuilder.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS
return processBuilder; return processBuilder;
@ -335,7 +338,7 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule {
private void addILeappReportToReports(Path aLeappOutputDir, Case currentCase) { private void addILeappReportToReports(Path aLeappOutputDir, Case currentCase) {
List<String> allIndexFiles = new ArrayList<>(); List<String> allIndexFiles = new ArrayList<>();
try (Stream<Path> walk = Files.walk(aLeappOutputDir)) { try (Stream<Path> walk = Files.walk(aLeappOutputDir)) {
allIndexFiles = walk.map(x -> x.toString()) allIndexFiles = walk.map(x -> x.toString())
.filter(f -> f.toLowerCase().endsWith("index.html")).collect(Collectors.toList()); .filter(f -> f.toLowerCase().endsWith("index.html")).collect(Collectors.toList());
@ -380,7 +383,7 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule {
return aLeappPathsToProcess; return aLeappPathsToProcess;
} }
private void extractFilesFromImage(Content dataSource, List<String> aLeappPathsToProcess, Path moduleOutputPath) { private void extractFilesFromDataSource(Content dataSource, List<String> aLeappPathsToProcess, Path moduleOutputPath) {
FileManager fileManager = getCurrentCase().getServices().getFileManager(); FileManager fileManager = getCurrentCase().getServices().getFileManager();
for (String fullFilePath : aLeappPathsToProcess) { for (String fullFilePath : aLeappPathsToProcess) {
@ -418,33 +421,33 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule {
private void extractFileToOutput(Content dataSource, AbstractFile aLeappFile, File fileParentPath, Path parentPath) { private void extractFileToOutput(Content dataSource, AbstractFile aLeappFile, File fileParentPath, Path parentPath) {
if (fileParentPath.exists()) { if (fileParentPath.exists()) {
if (!aLeappFile.isDir()) { if (!aLeappFile.isDir()) {
writeaLeappFile(dataSource, aLeappFile, fileParentPath.toString()); writeaLeappFile(dataSource, aLeappFile, fileParentPath.toString());
} else { } else {
try { try {
Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName())); Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName()));
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex); logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex);
}
}
} else {
try {
Files.createDirectories(parentPath);
} catch (IOException ex) {
logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex);
}
if (!aLeappFile.isDir()) {
writeaLeappFile(dataSource, aLeappFile, fileParentPath.toString());
} else {
try {
Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName()));
} catch (IOException ex) {
logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex);
}
}
} }
}
} else {
try {
Files.createDirectories(parentPath);
} catch (IOException ex) {
logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex);
}
if (!aLeappFile.isDir()) {
writeaLeappFile(dataSource, aLeappFile, fileParentPath.toString());
} else {
try {
Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName()));
} catch (IOException ex) {
logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex);
}
}
}
} }
private void writeaLeappFile(Content dataSource, AbstractFile aLeappFile, String parentPath) { private void writeaLeappFile(Content dataSource, AbstractFile aLeappFile, String parentPath) {
String fileName = aLeappFile.getName().replace(":", "-"); String fileName = aLeappFile.getName().replace(":", "-");
if (!fileName.matches(".") && !fileName.matches("..") && !fileName.toLowerCase().endsWith("-slack")) { if (!fileName.matches(".") && !fileName.matches("..") && !fileName.toLowerCase().endsWith("-slack")) {
@ -461,4 +464,16 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule {
} }
} }
} }
/**
* Writes a generic error message to the ingest inbox, directing the user to
* consult the application log fpor more details.
*/
private void writeErrorMsgToIngestInbox() {
IngestMessage message = IngestMessage.createMessage(IngestMessage.MessageType.ERROR,
MODULE_NAME,
Bundle.ALeappAnalyzerIngestModule_error_running_aLeapp());
IngestServices.getInstance().postMessage(message);
}
} }

View File

@ -8,7 +8,7 @@ ALeappAnalyzerIngestModule.has.run=aLeapp
ALeappAnalyzerIngestModule.report.name=aLeapp Html Report ALeappAnalyzerIngestModule.report.name=aLeapp Html Report
ALeappAnalyzerIngestModule.requires.windows=aLeapp module requires windows. ALeappAnalyzerIngestModule.requires.windows=aLeapp module requires windows.
ALeappAnalyzerIngestModule.running.aLeapp=Running aLeapp ALeappAnalyzerIngestModule.running.aLeapp=Running aLeapp
ALeappAnalyzerIngestModule.starting.aLeapp=Starting aLeapp ALeappAnalyzerIngestModule_processing_aLeapp_results=Processing aLeapp results
ALeappAnalyzerModuleFactory_moduleDesc=Uses aLEAPP to analyze logical acquisitions of Android devices. ALeappAnalyzerModuleFactory_moduleDesc=Uses aLEAPP to analyze logical acquisitions of Android devices.
ALeappAnalyzerModuleFactory_moduleName=Android Analyzer (aLEAPP) ALeappAnalyzerModuleFactory_moduleName=Android Analyzer (aLEAPP)
ILeappAnalyzerIngestModule.completed=iLeapp Processing Completed ILeappAnalyzerIngestModule.completed=iLeapp Processing Completed
@ -31,7 +31,7 @@ AleappAnalyzerIngestModule.not.64.bit.os=aLeapp will not run on a 32bit operatin
ILeappAnalyzerIngestModule.report.name=iLeapp Html Report ILeappAnalyzerIngestModule.report.name=iLeapp Html Report
ILeappAnalyzerIngestModule.requires.windows=iLeapp module requires windows. ILeappAnalyzerIngestModule.requires.windows=iLeapp module requires windows.
ILeappAnalyzerIngestModule.running.iLeapp=Running iLeapp ILeappAnalyzerIngestModule.running.iLeapp=Running iLeapp
ILeappAnalyzerIngestModule.starting.iLeapp=Starting iLeapp ILeappAnalyzerIngestModule_processing_iLeapp_results=Processing iLeapp results
ILeappAnalyzerModuleFactory_moduleDesc=Uses iLEAPP to analyze logical acquisitions of iOS devices. ILeappAnalyzerModuleFactory_moduleDesc=Uses iLEAPP to analyze logical acquisitions of iOS devices.
ILeappAnalyzerModuleFactory_moduleName=iOS Analyzer (iLEAPP) ILeappAnalyzerModuleFactory_moduleName=iOS Analyzer (iLEAPP)
LeappFileProcessor.cannot.create.calllog.relationship=Cannot create TSK_CALLLOG Relationship. LeappFileProcessor.cannot.create.calllog.relationship=Cannot create TSK_CALLLOG Relationship.

View File

@ -73,7 +73,6 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
private static final String XMLFILE = "ileap-artifact-attribute-reference.xml"; //NON-NLS private static final String XMLFILE = "ileap-artifact-attribute-reference.xml"; //NON-NLS
private File iLeappExecutable; private File iLeappExecutable;
private IngestJobContext context; private IngestJobContext context;
@ -95,7 +94,7 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
if (false == PlatformUtil.is64BitOS()) { if (false == PlatformUtil.is64BitOS()) {
throw new IngestModuleException(NbBundle.getMessage(this.getClass(), "IleappAnalyzerIngestModule.not.64.bit.os")); throw new IngestModuleException(NbBundle.getMessage(this.getClass(), "IleappAnalyzerIngestModule.not.64.bit.os"));
} }
if (false == PlatformUtil.isWindowsOS()) { if (false == PlatformUtil.isWindowsOS()) {
throw new IngestModuleException(Bundle.ILeappAnalyzerIngestModule_requires_windows()); throw new IngestModuleException(Bundle.ILeappAnalyzerIngestModule_requires_windows());
} }
@ -118,8 +117,8 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
@NbBundle.Messages({ @NbBundle.Messages({
"ILeappAnalyzerIngestModule.error.running.iLeapp=Error running iLeapp, see log file.", "ILeappAnalyzerIngestModule.error.running.iLeapp=Error running iLeapp, see log file.",
"ILeappAnalyzerIngestModule.error.creating.output.dir=Error creating iLeapp module output directory.", "ILeappAnalyzerIngestModule.error.creating.output.dir=Error creating iLeapp module output directory.",
"ILeappAnalyzerIngestModule.starting.iLeapp=Starting iLeapp",
"ILeappAnalyzerIngestModule.running.iLeapp=Running iLeapp", "ILeappAnalyzerIngestModule.running.iLeapp=Running iLeapp",
"ILeappAnalyzerIngestModule_processing_iLeapp_results=Processing iLeapp results",
"ILeappAnalyzerIngestModule.has.run=iLeapp", "ILeappAnalyzerIngestModule.has.run=iLeapp",
"ILeappAnalyzerIngestModule.iLeapp.cancelled=iLeapp run was canceled", "ILeappAnalyzerIngestModule.iLeapp.cancelled=iLeapp run was canceled",
"ILeappAnalyzerIngestModule.completed=iLeapp Processing Completed", "ILeappAnalyzerIngestModule.completed=iLeapp Processing Completed",
@ -127,51 +126,62 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
@Override @Override
public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper) { public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper) {
statusHelper.switchToIndeterminate();
statusHelper.progress(Bundle.ILeappAnalyzerIngestModule_running_iLeapp());
Case currentCase = Case.getCurrentCase(); Case currentCase = Case.getCurrentCase();
Path tempOutputPath = Paths.get(currentCase.getTempDirectory(), ILEAPP, ILEAPP_FS + dataSource.getId()); Path tempOutputPath = Paths.get(currentCase.getTempDirectory(), ILEAPP, ILEAPP_FS + dataSource.getId());
try { try {
Files.createDirectories(tempOutputPath); Files.createDirectories(tempOutputPath);
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.SEVERE, String.format("Error creating iLeapp output directory %s", tempOutputPath.toString()), ex); logger.log(Level.SEVERE, String.format("Error creating iLeapp output directory %s", tempOutputPath.toString()), ex);
writeErrorMsgToIngestInbox();
return ProcessResult.ERROR; return ProcessResult.ERROR;
} }
List<String> iLeappPathsToProcess = new ArrayList<>(); List<String> iLeappPathsToProcess;
ProcessBuilder iLeappCommand = buildiLeappListCommand(tempOutputPath); ProcessBuilder iLeappCommand = buildiLeappListCommand(tempOutputPath);
try { try {
int result = ExecUtil.execute(iLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true)); int result = ExecUtil.execute(iLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true));
if (result != 0) { if (result != 0) {
logger.log(Level.SEVERE, String.format("Error when trying to execute iLeapp program getting file paths to search for result is %d", result)); logger.log(Level.SEVERE, String.format("Error when trying to execute iLeapp program getting file paths to search for result is %d", result));
writeErrorMsgToIngestInbox();
return ProcessResult.ERROR; return ProcessResult.ERROR;
} }
iLeappPathsToProcess = loadIleappPathFile(tempOutputPath); iLeappPathsToProcess = loadIleappPathFile(tempOutputPath);
if (iLeappPathsToProcess.isEmpty()) {
logger.log(Level.SEVERE, String.format("Error getting file paths to search, list is empty"));
writeErrorMsgToIngestInbox();
return ProcessResult.ERROR;
}
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.SEVERE, String.format("Error when trying to execute iLeapp program getting file paths to search"), ex); logger.log(Level.SEVERE, String.format("Error when trying to execute iLeapp program getting file paths to search"), ex);
writeErrorMsgToIngestInbox();
return ProcessResult.ERROR; return ProcessResult.ERROR;
} }
statusHelper.progress(Bundle.ILeappAnalyzerIngestModule_starting_iLeapp(), 0); if ((context.getDataSource() instanceof LocalFilesDataSource)) {
/*
List<AbstractFile> iLeappFilesToProcess = new ArrayList<>(); * The data source may be local files from an iOS file system, or it
* may be a tarred/ZIP of an iOS file system. If it is the latter,
if (!(context.getDataSource() instanceof LocalFilesDataSource)) { * extract the files we need to process.
extractFilesFromImage(dataSource, iLeappPathsToProcess, tempOutputPath); */
statusHelper.switchToDeterminate(iLeappFilesToProcess.size()); List<AbstractFile> iLeappFilesToProcess = LeappFileProcessor.findLeappFilesToProcess(dataSource);
processILeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString()); if (!iLeappFilesToProcess.isEmpty()) {
} else { statusHelper.switchToDeterminate(iLeappFilesToProcess.size());
iLeappFilesToProcess = LeappFileProcessor.findLeappFilesToProcess(dataSource); Integer filesProcessedCount = 0;
statusHelper.switchToDeterminate(iLeappFilesToProcess.size()); for (AbstractFile iLeappFile : iLeappFilesToProcess) {
processILeappFile(dataSource, currentCase, statusHelper, filesProcessedCount, iLeappFile);
Integer filesProcessedCount = 0; filesProcessedCount++;
for (AbstractFile iLeappFile : iLeappFilesToProcess) { }
processILeappFile(dataSource, currentCase, statusHelper, filesProcessedCount, iLeappFile);
filesProcessedCount++;
} }
// Process the logical image as a fs in iLeapp to make sure this is not a logical fs that was added
extractFilesFromImage(dataSource, iLeappPathsToProcess, tempOutputPath);
processILeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString());
} }
statusHelper.switchToIndeterminate();
statusHelper.progress(Bundle.ILeappAnalyzerIngestModule_processing_iLeapp_results());
extractFilesFromDataSource(dataSource, iLeappPathsToProcess, tempOutputPath);
processILeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString());
IngestMessage message = IngestMessage.createMessage(IngestMessage.MessageType.DATA, IngestMessage message = IngestMessage.createMessage(IngestMessage.MessageType.DATA,
Bundle.ILeappAnalyzerIngestModule_has_run(), Bundle.ILeappAnalyzerIngestModule_has_run(),
Bundle.ILeappAnalyzerIngestModule_completed()); Bundle.ILeappAnalyzerIngestModule_completed());
@ -180,15 +190,19 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
} }
/** /**
* Process each tar/zip file that is found in a logical image that contains xLeapp data * Process each tar/zip file that is found in a logical image that contains
* @param dataSource Datasource where the file has been found * xLeapp data
* @param currentCase current case *
* @param statusHelper Progress bar for messages to show user * @param dataSource Datasource where the file has been found
* @param currentCase current case
* @param statusHelper Progress bar for messages to show user
* @param filesProcessedCount count that is incremented for progress bar * @param filesProcessedCount count that is incremented for progress bar
* @param iLeappFile abstract file that will be processed * @param iLeappFile abstract file that will be processed
*/ */
private void processILeappFile(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, int filesProcessedCount, private void processILeappFile(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, int filesProcessedCount,
AbstractFile iLeappFile) { AbstractFile iLeappFile) {
statusHelper.progress(NbBundle.getMessage(this.getClass(), "ILeappAnalyzerIngestModule.processing.file", iLeappFile.getName()), filesProcessedCount);
String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS
Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ILEAPP, currentTime); Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ILEAPP, currentTime);
try { try {
@ -198,7 +212,6 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
return; return;
} }
statusHelper.progress(NbBundle.getMessage(this.getClass(), "ILeappAnalyzerIngestModule.processing.file", iLeappFile.getName()), filesProcessedCount);
ProcessBuilder iLeappCommand = buildiLeappCommand(moduleOutputPath, iLeappFile.getLocalAbsPath(), iLeappFile.getNameExtension()); ProcessBuilder iLeappCommand = buildiLeappCommand(moduleOutputPath, iLeappFile.getLocalAbsPath(), iLeappFile.getNameExtension());
try { try {
int result = ExecUtil.execute(iLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true)); int result = ExecUtil.execute(iLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true));
@ -219,21 +232,19 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
return; return;
} }
ProcessResult fileProcessorResult = iLeappFileProcessor.processFiles(dataSource, moduleOutputPath, iLeappFile); iLeappFileProcessor.processFiles(dataSource, moduleOutputPath, iLeappFile);
if (fileProcessorResult == ProcessResult.ERROR) {
return;
}
} }
/** /**
* Process extracted files from a disk image using xLeapp * Process extracted files from a disk image using xLeapp
* @param dataSource Datasource where the file has been found *
* @param currentCase current case * @param dataSource Datasource where the file has been found
* @param statusHelper Progress bar for messages to show user * @param currentCase current case
* @param directoryToProcess * @param statusHelper Progress bar for messages to show user
* @param directoryToProcess
*/ */
private void processILeappFs(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, String directoryToProcess) { private void processILeappFs(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, String directoryToProcess) {
statusHelper.progress(NbBundle.getMessage(this.getClass(), "ILeappAnalyzerIngestModule.processing.filesystem"));
String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS
Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ILEAPP, currentTime); Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ILEAPP, currentTime);
try { try {
@ -243,7 +254,6 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
return; return;
} }
statusHelper.progress(NbBundle.getMessage(this.getClass(), "ILeappAnalyzerIngestModule.processing.filesystem"));
ProcessBuilder iLeappCommand = buildiLeappCommand(moduleOutputPath, directoryToProcess, "fs"); ProcessBuilder iLeappCommand = buildiLeappCommand(moduleOutputPath, directoryToProcess, "fs");
try { try {
int result = ExecUtil.execute(iLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true)); int result = ExecUtil.execute(iLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true));
@ -264,19 +274,16 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
return; return;
} }
ProcessResult fileProcessorResult = iLeappFileProcessor.processFileSystem(dataSource, moduleOutputPath); iLeappFileProcessor.processFileSystem(dataSource, moduleOutputPath);
if (fileProcessorResult == ProcessResult.ERROR) {
return;
}
} }
/** /**
* Build the command to run xLeapp * Build the command to run xLeapp
* @param moduleOutputPath output path for xLeapp *
* @param sourceFilePath path where the xLeapp file is * @param moduleOutputPath output path for xLeapp
* @param sourceFilePath path where the xLeapp file is
* @param iLeappFileSystemType type of file to process tar/zip/fs * @param iLeappFileSystemType type of file to process tar/zip/fs
*
* @return process to run * @return process to run
*/ */
private ProcessBuilder buildiLeappCommand(Path moduleOutputPath, String sourceFilePath, String iLeappFileSystemType) { private ProcessBuilder buildiLeappCommand(Path moduleOutputPath, String sourceFilePath, String iLeappFileSystemType) {
@ -294,7 +301,9 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
/** /**
* Command to run xLeapp using the path option * Command to run xLeapp using the path option
*
* @param moduleOutputPath path where the file paths output will reside * @param moduleOutputPath path where the file paths output will reside
*
* @return process to run * @return process to run
*/ */
private ProcessBuilder buildiLeappListCommand(Path moduleOutputPath) { private ProcessBuilder buildiLeappListCommand(Path moduleOutputPath) {
@ -311,8 +320,8 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
static private ProcessBuilder buildProcessWithRunAsInvoker(String... commandLine) { static private ProcessBuilder buildProcessWithRunAsInvoker(String... commandLine) {
ProcessBuilder processBuilder = new ProcessBuilder(commandLine); ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
/* /*
* Add an environment variable to force iLeapp to run with * Add an environment variable to force iLeapp to run with the same
* the same permissions Autopsy uses. * permissions Autopsy uses.
*/ */
processBuilder.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS processBuilder.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS
return processBuilder; return processBuilder;
@ -335,7 +344,7 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
private void addILeappReportToReports(Path iLeappOutputDir, Case currentCase) { private void addILeappReportToReports(Path iLeappOutputDir, Case currentCase) {
List<String> allIndexFiles; List<String> allIndexFiles;
try (Stream<Path> walk = Files.walk(iLeappOutputDir)) { try (Stream<Path> walk = Files.walk(iLeappOutputDir)) {
allIndexFiles = walk.map(x -> x.toString()) allIndexFiles = walk.map(x -> x.toString())
.filter(f -> f.toLowerCase().endsWith("index.html")).collect(Collectors.toList()); .filter(f -> f.toLowerCase().endsWith("index.html")).collect(Collectors.toList());
@ -383,11 +392,12 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
/** /**
* Extract files from a disk image to process with xLeapp * Extract files from a disk image to process with xLeapp
* @param dataSource Datasource of the image *
* @param iLeappPathsToProcess List of paths to extract content from * @param dataSource Datasource of the image
* @param moduleOutputPath path to write content to * @param iLeappPathsToProcess List of paths to extract content from
* @param moduleOutputPath path to write content to
*/ */
private void extractFilesFromImage(Content dataSource, List<String> iLeappPathsToProcess, Path moduleOutputPath) { private void extractFilesFromDataSource(Content dataSource, List<String> iLeappPathsToProcess, Path moduleOutputPath) {
FileManager fileManager = getCurrentCase().getServices().getFileManager(); FileManager fileManager = getCurrentCase().getServices().getFileManager();
for (String fullFilePath : iLeappPathsToProcess) { for (String fullFilePath : iLeappPathsToProcess) {
@ -425,42 +435,44 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
/** /**
* Create path and file from datasource in temp * Create path and file from datasource in temp
* @param dataSource datasource of the image *
* @param iLeappFile abstract file to write out * @param dataSource datasource of the image
* @param iLeappFile abstract file to write out
* @param fileParentPath parent file path * @param fileParentPath parent file path
* @param parentPath parent file * @param parentPath parent file
*/ */
private void extractFileToOutput(Content dataSource, AbstractFile iLeappFile, File fileParentPath, Path parentPath) { private void extractFileToOutput(Content dataSource, AbstractFile iLeappFile, File fileParentPath, Path parentPath) {
if (fileParentPath.exists()) { if (fileParentPath.exists()) {
if (!iLeappFile.isDir()) { if (!iLeappFile.isDir()) {
writeiLeappFile(dataSource, iLeappFile, fileParentPath.toString()); writeiLeappFile(dataSource, iLeappFile, fileParentPath.toString());
} else { } else {
try { try {
Files.createDirectories(Paths.get(parentPath.toString(), iLeappFile.getName())); Files.createDirectories(Paths.get(parentPath.toString(), iLeappFile.getName()));
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.INFO, String.format("Error creating iLeapp output directory %s", parentPath.toString()), ex); logger.log(Level.INFO, String.format("Error creating iLeapp output directory %s", parentPath.toString()), ex);
}
}
} else {
try {
Files.createDirectories(parentPath);
} catch (IOException ex) {
logger.log(Level.INFO, String.format("Error creating iLeapp output directory %s", parentPath.toString()), ex);
}
if (!iLeappFile.isDir()) {
writeiLeappFile(dataSource, iLeappFile, fileParentPath.toString());
} else {
try {
Files.createDirectories(Paths.get(parentPath.toString(), iLeappFile.getName()));
} catch (IOException ex) {
logger.log(Level.INFO, String.format("Error creating iLeapp output directory %s", parentPath.toString()), ex);
}
}
} }
}
} else {
try {
Files.createDirectories(parentPath);
} catch (IOException ex) {
logger.log(Level.INFO, String.format("Error creating iLeapp output directory %s", parentPath.toString()), ex);
}
if (!iLeappFile.isDir()) {
writeiLeappFile(dataSource, iLeappFile, fileParentPath.toString());
} else {
try {
Files.createDirectories(Paths.get(parentPath.toString(), iLeappFile.getName()));
} catch (IOException ex) {
logger.log(Level.INFO, String.format("Error creating iLeapp output directory %s", parentPath.toString()), ex);
}
}
}
} }
/** /**
* Write out file to output * Write out file to output
*
* @param dataSource datasource of disk image * @param dataSource datasource of disk image
* @param iLeappFile acstract file to write out * @param iLeappFile acstract file to write out
* @param parentPath path to write file to * @param parentPath path to write file to
@ -481,4 +493,16 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule {
} }
} }
} }
/**
* Writes a generic error message to the ingest inbox, directing the user to
* consult the application log fpor more details.
*/
private void writeErrorMsgToIngestInbox() {
IngestMessage message = IngestMessage.createMessage(IngestMessage.MessageType.ERROR,
MODULE_NAME,
Bundle.ILeappAnalyzerIngestModule_error_running_iLeapp());
IngestServices.getInstance().postMessage(message);
}
} }

View File

@ -18,8 +18,6 @@
*/ */
package org.sleuthkit.autopsy.progress; package org.sleuthkit.autopsy.progress;
import org.sleuthkit.autopsy.progress.ProgressIndicator;
/** /**
* A "silent" or "null" progress indicator. * A "silent" or "null" progress indicator.
*/ */

View File

@ -42,8 +42,8 @@ file.reference.javassist-3.12.1.GA.jar=release/modules/ext/javassist-3.12.1.GA.j
file.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4.jar file.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4.jar
file.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4.jar file.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4.jar
file.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4.jar file.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4.jar
file.reference.jna-5.9.0.jar=release/modules/ext/jna-5.10.0.jar file.reference.jna-5.10.0.jar=release/modules/ext/jna-5.10.0.jar
file.reference.jna-platform-5.9.0.jar=release/modules/ext/jna-platform-5.10.0.jar file.reference.jna-platform-5.10.0.jar=release/modules/ext/jna-platform-5.10.0.jar
file.reference.joda-time-2.4.jar=release/modules/ext/joda-time-2.4.jar file.reference.joda-time-2.4.jar=release/modules/ext/joda-time-2.4.jar
file.reference.jsr305-1.3.9.jar=release/modules/ext/jsr305-1.3.9.jar file.reference.jsr305-1.3.9.jar=release/modules/ext/jsr305-1.3.9.jar
file.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar file.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar

View File

@ -2814,10 +2814,13 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
/* /*
* Block until notified by the ingest job event listener * Block until notified by the ingest job event listener
* or until interrupted because auto ingest is shutting * or until interrupted because auto ingest is shutting
* down. * down. For very small jobs, it is possible that ingest has
* completed by the time we get here, so check periodically
* in case the event was missed.
*/ */
ingestLock.wait(); while (IngestManager.getInstance().isIngestRunning()) {
sysLogger.log(Level.INFO, "Finished ingest modules analysis for {0} ", manifestPath); ingestLock.wait(300000); // Check every five minutes
}
IngestJob.ProgressSnapshot jobSnapshot = ingestJob.getSnapshot(); IngestJob.ProgressSnapshot jobSnapshot = ingestJob.getSnapshot();
IngestJob.ProgressSnapshot.DataSourceProcessingSnapshot snapshot = jobSnapshot.getDataSourceProcessingSnapshot(); IngestJob.ProgressSnapshot.DataSourceProcessingSnapshot snapshot = jobSnapshot.getDataSourceProcessingSnapshot();
AutoIngestJobLogger nestedJobLogger = new AutoIngestJobLogger(manifestPath, snapshot.getDataSource(), caseDirectoryPath); AutoIngestJobLogger nestedJobLogger = new AutoIngestJobLogger(manifestPath, snapshot.getDataSource(), caseDirectoryPath);

View File

@ -158,7 +158,7 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer):
phoneNumber, # phoneNumber, phoneNumber, # phoneNumber,
None, # homePhoneNumber, None, # homePhoneNumber,
None, # mobilePhoneNumber, None, # mobilePhoneNumber,
emailAddr, context.getJobId()) # emailAddr emailAddr) # emailAddr
except SQLException as ex: except SQLException as ex:
self._logger.log(Level.WARNING, "Error processing query result for Android messages.", ex) self._logger.log(Level.WARNING, "Error processing query result for Android messages.", ex)

View File

@ -16,10 +16,10 @@
<dependencies> <dependencies>
<!-- Solr --> <!-- Solr -->
<dependency conf="solr-war->default" org="org.apache.solr" name="solr" rev="4.9.1" transitive="false" /> <!-- the war file for embedded Solr 4 --> <dependency conf="solr-war->default" org="org.apache.solr" name="solr" rev="4.9.1" transitive="false" /> <!-- the war file for embedded Solr 4 -->
<dependency name="solr-cell" rev="8.6.3" org="org.apache.solr" conf="solr-libs->default"/> <dependency name="solr-cell" rev="8.11.1" org="org.apache.solr" conf="solr-libs->default"/>
<!-- Autopsy --> <!-- Autopsy -->
<dependency conf="autopsy->*" org="org.apache.solr" name="solr-solrj" rev="8.6.3"/> <dependency conf="autopsy->*" org="org.apache.solr" name="solr-solrj" rev="8.11.1"/>
<dependency conf="autopsy->*" org="commons-lang" name="commons-lang" rev="2.4"/> <dependency conf="autopsy->*" org="commons-lang" name="commons-lang" rev="2.4"/>
<dependency conf="autopsy->*" org="commons-validator" name="commons-validator" rev="1.5.1"/> <dependency conf="autopsy->*" org="commons-validator" name="commons-validator" rev="1.5.1"/>
<dependency conf="autopsy->*" org="com.optimaize.languagedetector" name="language-detector" rev="0.6"/> <dependency conf="autopsy->*" org="com.optimaize.languagedetector" name="language-detector" rev="0.6"/>

View File

@ -44,8 +44,7 @@ file.reference.poi-scratchpad-4.0.1.jar=release/modules/ext/poi-scratchpad-4.0.1
file.reference.protobuf-java-2.5.0.jar=release/modules/ext/protobuf-java-2.5.0.jar file.reference.protobuf-java-2.5.0.jar=release/modules/ext/protobuf-java-2.5.0.jar
file.reference.quartz-2.2.0.jar=release/modules/ext/quartz-2.2.0.jar file.reference.quartz-2.2.0.jar=release/modules/ext/quartz-2.2.0.jar
file.reference.slf4j-api-1.7.25.jar=release/modules/ext/slf4j-api-1.7.25.jar file.reference.slf4j-api-1.7.25.jar=release/modules/ext/slf4j-api-1.7.25.jar
file.reference.solr-solrj-8.6.2.jar=release/modules/ext/solr-solrj-8.6.2.jar file.reference.solr-solrj-8.11.1.jar=release/modules/ext/solr-solrj-8.11.1.jar
file.reference.solr-solrj-8.6.3.jar=release/modules/ext/solr-solrj-8.6.3.jar
file.reference.sqlwrapper-0.0.1.jar=release/modules/ext/sqlwrapper-0.0.1.jar file.reference.sqlwrapper-0.0.1.jar=release/modules/ext/sqlwrapper-0.0.1.jar
file.reference.stax2-api-3.1.4.jar=release/modules/ext/stax2-api-3.1.4.jar file.reference.stax2-api-3.1.4.jar=release/modules/ext/stax2-api-3.1.4.jar
file.reference.tagsoup-1.2.1.jar=release/modules/ext/tagsoup-1.2.1.jar file.reference.tagsoup-1.2.1.jar=release/modules/ext/tagsoup-1.2.1.jar
@ -57,7 +56,7 @@ file.reference.vorbis-java-tika-0.8.jar=release/modules/ext/vorbis-java-tika-0.8
file.reference.woodstox-core-asl-4.4.1.jar=release/modules/ext/woodstox-core-asl-4.4.1.jar file.reference.woodstox-core-asl-4.4.1.jar=release/modules/ext/woodstox-core-asl-4.4.1.jar
file.reference.xmlbeans-2.6.0.jar=release/modules/ext/xmlbeans-2.6.0.jar file.reference.xmlbeans-2.6.0.jar=release/modules/ext/xmlbeans-2.6.0.jar
file.reference.xmpcore-5.1.3.jar=release/modules/ext/xmpcore-5.1.3.jar file.reference.xmpcore-5.1.3.jar=release/modules/ext/xmpcore-5.1.3.jar
file.reference.zookeeper-3.5.7.jar=release/modules/ext/zookeeper-3.5.7.jar file.reference.zookeeper-3.6.2.jar=release/modules/ext/zookeeper-3.6.2.jar
file.reference.annotations-12.0.jar=release\\modules\\ext\\annotations-12.0.jar file.reference.annotations-12.0.jar=release\\modules\\ext\\annotations-12.0.jar
file.reference.jsonic-1.2.11.jar=release\\modules\\ext\\jsonic-1.2.11.jar file.reference.jsonic-1.2.11.jar=release\\modules\\ext\\jsonic-1.2.11.jar
javac.source=1.8 javac.source=1.8
@ -66,5 +65,5 @@ license.file=../LICENSE-2.0.txt
nbm.homepage=http://www.sleuthkit.org/autopsy/ nbm.homepage=http://www.sleuthkit.org/autopsy/
nbm.needs.restart=true nbm.needs.restart=true
source.reference.commons-validator-1.5.1.jar=release/modules/ext/commons-validator-1.5.1-sources.jar source.reference.commons-validator-1.5.1.jar=release/modules/ext/commons-validator-1.5.1-sources.jar
source.reference.solr-solrj-8.6.2.jar=release/modules/ext/solr-solrj-8.6.2-sources.jar source.reference.solr-solrj-8.11.1.jar=release/modules/ext/solr-solrj-8.11.1-sources.jar
spec.version.base=6.6 spec.version.base=6.6

View File

@ -357,8 +357,8 @@
<binary-origin>release/modules/ext/poi-ooxml-schemas-4.0.1.jar</binary-origin> <binary-origin>release/modules/ext/poi-ooxml-schemas-4.0.1.jar</binary-origin>
</class-path-extension> </class-path-extension>
<class-path-extension> <class-path-extension>
<runtime-relative-path>ext/zookeeper-3.5.7.jar</runtime-relative-path> <runtime-relative-path>ext/zookeeper-3.6.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/zookeeper-3.5.7.jar</binary-origin> <binary-origin>release/modules/ext/zookeeper-3.6.2.jar</binary-origin>
</class-path-extension> </class-path-extension>
<class-path-extension> <class-path-extension>
<runtime-relative-path>ext/commons-collections-3.2.2.jar</runtime-relative-path> <runtime-relative-path>ext/commons-collections-3.2.2.jar</runtime-relative-path>
@ -385,8 +385,8 @@
<binary-origin>release/modules/ext/httpclient-4.5.10.jar</binary-origin> <binary-origin>release/modules/ext/httpclient-4.5.10.jar</binary-origin>
</class-path-extension> </class-path-extension>
<class-path-extension> <class-path-extension>
<runtime-relative-path>ext/solr-solrj-8.6.3.jar</runtime-relative-path> <runtime-relative-path>ext/solr-solrj-8.11.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/solr-solrj-8.6.3.jar</binary-origin> <binary-origin>release/modules/ext/solr-solrj-8.11.1.jar</binary-origin>
</class-path-extension> </class-path-extension>
<class-path-extension> <class-path-extension>
<runtime-relative-path>ext/vorbis-java-tika-0.8.jar</runtime-relative-path> <runtime-relative-path>ext/vorbis-java-tika-0.8.jar</runtime-relative-path>

View File

@ -93,8 +93,8 @@ statements in the solrconfig.xml file to reference plugin jars outside of
this directory for loading "contrib" plugins via relative paths. this directory for loading "contrib" plugins via relative paths.
If you make a copy of this example server and wish to use the If you make a copy of this example server and wish to use the
ExtractingRequestHandler (SolrCell), DataImportHandler (DIH), the ExtractingRequestHandler (SolrCell), DataImportHandler (DIH),
clustering component, or any other modules in "contrib", you will need to or any other modules in "contrib", you will need to
copy the required jars or update the paths to those jars in your copy the required jars or update the paths to those jars in your
solrconfig.xml. solrconfig.xml.

View File

@ -0,0 +1,32 @@
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- =============================================================== -->
<!-- Mixin the GZIP Handler -->
<!-- This applies the GZIP Handler to the entire server -->
<!-- If a GZIP handler is required for an individual context, then -->
<!-- use a context XML (see test.xml example in distribution) -->
<!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="insertHandler">
<Arg>
<New id="GzipHandler" class="org.eclipse.jetty.server.handler.gzip.GzipHandler">
<Set name="minGzipSize"><Property name="jetty.gzip.minGzipSize" deprecated="gzip.minGzipSize" default="2048"/></Set>
<Set name="checkGzExists"><Property name="jetty.gzip.checkGzExists" deprecated="gzip.checkGzExists" default="false"/></Set>
<Set name="compressionLevel"><Property name="jetty.gzip.compressionLevel" deprecated="gzip.compressionLevel" default="-1"/></Set>
<Set name="inflateBufferSize"><Property name="jetty.gzip.inflateBufferSize" default="0"/></Set>
<Set name="deflaterPoolCapacity"><Property name="jetty.gzip.deflaterPoolCapacity" default="-1"/></Set>
<Set name="syncFlush"><Property name="jetty.gzip.syncFlush" default="false" /></Set>
<Set name="excludedAgentPatterns">
<Array type="String">
<Item><Property name="jetty.gzip.excludedUserAgent" deprecated="gzip.excludedUserAgent" default=".*MSIE.6\.0.*"/></Item>
</Array>
</Set>
<Set name="includedMethodList"><Property name="jetty.gzip.includedMethodList" default="GET,POST" /></Set>
<Set name="excludedMethodList"><Property name="jetty.gzip.excludedMethodList" default="" /></Set>
</New>
</Arg>
</Call>
</Configure>

View File

@ -93,7 +93,7 @@
<Call name="addRule"> <Call name="addRule">
<Arg> <Arg>
<New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule"> <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<Set name="pattern">*</Set> <Set name="pattern">/solr/*</Set>
<Set name="name">Content-Security-Policy</Set> <Set name="name">Content-Security-Policy</Set>
<Set name="value">default-src 'none'; base-uri 'none'; connect-src 'self'; form-action 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self'; media-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self'; worker-src 'self';</Set> <Set name="value">default-src 'none'; base-uri 'none'; connect-src 'self'; form-action 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self'; media-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self'; worker-src 'self';</Set>
</New> </New>
@ -102,7 +102,7 @@
<Call name="addRule"> <Call name="addRule">
<Arg> <Arg>
<New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule"> <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<Set name="pattern">*</Set> <Set name="pattern">/solr/*</Set>
<Set name="name">X-Content-Type-Options</Set> <Set name="name">X-Content-Type-Options</Set>
<Set name="value">nosniff</Set> <Set name="value">nosniff</Set>
</New> </New>
@ -111,7 +111,7 @@
<Call name="addRule"> <Call name="addRule">
<Arg> <Arg>
<New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule"> <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<Set name="pattern">*</Set> <Set name="pattern">/solr/*</Set>
<Set name="name">X-Frame-Options</Set> <Set name="name">X-Frame-Options</Set>
<Set name="value">SAMEORIGIN</Set> <Set name="value">SAMEORIGIN</Set>
</New> </New>
@ -120,7 +120,7 @@
<Call name="addRule"> <Call name="addRule">
<Arg> <Arg>
<New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule"> <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<Set name="pattern">*</Set> <Set name="pattern">/solr/*</Set>
<Set name="name">X-XSS-Protection</Set> <Set name="name">X-XSS-Protection</Set>
<Set name="value">1; mode=block</Set> <Set name="value">1; mode=block</Set>
</New> </New>

View File

@ -103,6 +103,9 @@ grant {
permission java.lang.RuntimePermission "writeFileDescriptor"; permission java.lang.RuntimePermission "writeFileDescriptor";
// needed by hadoop http // needed by hadoop http
permission java.lang.RuntimePermission "getProtectionDomain"; permission java.lang.RuntimePermission "getProtectionDomain";
// needed by aws s3 sdk (Apache HTTP Client)
permission java.lang.RuntimePermission "setFactory";
permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.reflect";
// These two *have* to be spelled out a separate // These two *have* to be spelled out a separate
permission java.lang.management.ManagementPermission "control"; permission java.lang.management.ManagementPermission "control";
@ -198,6 +201,11 @@ grant {
permission java.io.FilePermission "${log4j.configurationFile}", "read,write,delete,readlink"; permission java.io.FilePermission "${log4j.configurationFile}", "read,write,delete,readlink";
// Credentials for S3 Repository
permission java.io.FilePermission "${aws.sharedCredentialsFile}", "read,readlink";
permission java.io.FilePermission "${aws.configFile}", "read,readlink";
permission java.io.FilePermission "${user.home}${/}.aws${/}-", "read,readlink";
// expanded to a wildcard if set, allows all networking everywhere // expanded to a wildcard if set, allows all networking everywhere
permission java.net.SocketPermission "${solr.internal.network.permission}", "accept,listen,connect,resolve"; permission java.net.SocketPermission "${solr.internal.network.permission}", "accept,listen,connect,resolve";
}; };

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,12 @@
[description]
Enable GzipHandler for dynamic gzip compression
for the entire server.
[tags]
handler
[depend]
server
[xml]
etc/jetty-gzip.xml

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