mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
Merge branch 'develop' of github.com:sleuthkit/autopsy into 7680-ocrOnly
This commit is contained in:
commit
2fe876eb84
@ -22,6 +22,7 @@ import org.sleuthkit.autopsy.featureaccess.FeatureAccessUtils;
|
|||||||
import com.google.common.annotations.Beta;
|
import com.google.common.annotations.Beta;
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
|
import java.awt.Cursor;
|
||||||
import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData;
|
import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData;
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
@ -1324,12 +1325,14 @@ public class Case {
|
|||||||
* opened via the DirectoryTreeTopComponent 'propertyChange()'
|
* opened via the DirectoryTreeTopComponent 'propertyChange()'
|
||||||
* method on a DATA_SOURCE_ADDED event.
|
* method on a DATA_SOURCE_ADDED event.
|
||||||
*/
|
*/
|
||||||
|
mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
if (hasData) {
|
if (hasData) {
|
||||||
CoreComponentControl.openCoreWindows();
|
CoreComponentControl.openCoreWindows();
|
||||||
} else {
|
} else {
|
||||||
//ensure that the DirectoryTreeTopComponent is open so that it's listener can open the core windows including making it visible.
|
//ensure that the DirectoryTreeTopComponent is open so that it's listener can open the core windows including making it visible.
|
||||||
DirectoryTreeTopComponent.findInstance();
|
DirectoryTreeTopComponent.findInstance();
|
||||||
}
|
}
|
||||||
|
mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset the main window title to:
|
* Reset the main window title to:
|
||||||
|
@ -26,6 +26,7 @@ import java.util.Date;
|
|||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
@ -167,6 +168,8 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
} catch (InterruptedException | ExecutionException ex) {
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
logger.log(Level.WARNING, "Error getting results from Ingest Job Info Panel's refresh worker", ex);
|
logger.log(Level.WARNING, "Error getting results from Ingest Job Info Panel's refresh worker", ex);
|
||||||
|
} catch (CancellationException ignored){
|
||||||
|
logger.log(Level.INFO, "The refreshing of the IngestJobInfoPanel was cancelled");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -90,17 +90,17 @@ public final class DataContentViewerOtherCases extends JPanel implements DataCon
|
|||||||
public boolean isSupported(Node node) {
|
public boolean isSupported(Node node) {
|
||||||
|
|
||||||
// Is supported if one of the following is true:
|
// Is supported if one of the following is true:
|
||||||
// - The central repo is enabled and the node has correlatable content
|
// - The central repo is enabled and the node is not null
|
||||||
// (either through the MD5 hash of the associated file or through a BlackboardArtifact)
|
|
||||||
// - The central repo is disabled and the backing file has a valid MD5 hash
|
// - The central repo is disabled and the backing file has a valid MD5 hash
|
||||||
AbstractFile file = OtherOccurrences.getAbstractFileFromNode(node);
|
if (CentralRepository.isEnabled() && node != null) {
|
||||||
if (CentralRepository.isEnabled()) {
|
return true;
|
||||||
return !OtherOccurrences.getCorrelationAttributesFromNode(node, file).isEmpty();
|
} else if (node != null){
|
||||||
} else {
|
AbstractFile file = OtherOccurrences.getAbstractFileFromNode(node);
|
||||||
return file != null
|
return file != null
|
||||||
&& file.getSize() > 0
|
&& file.getSize() > 0
|
||||||
&& ((file.getMd5Hash() != null) && (!file.getMd5Hash().isEmpty()));
|
&& ((file.getMd5Hash() != null) && (!file.getMd5Hash().isEmpty()));
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -34,8 +34,6 @@
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Container>
|
</Container>
|
||||||
<Component class="javax.swing.JFileChooser" name="CSVFileChooser">
|
|
||||||
</Component>
|
|
||||||
</NonVisualComponents>
|
</NonVisualComponents>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
@ -35,6 +35,9 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.FutureTask;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
@ -46,7 +49,6 @@ import javax.swing.SwingWorker;
|
|||||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||||
import javax.swing.table.TableModel;
|
import javax.swing.table.TableModel;
|
||||||
import javax.swing.table.TableRowSorter;
|
import javax.swing.table.TableRowSorter;
|
||||||
import org.openide.util.Exceptions;
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
@ -71,7 +73,6 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
private static final CorrelationCaseWrapper NO_ARTIFACTS_CASE = new CorrelationCaseWrapper(Bundle.OtherOccurrencesPanel_table_noArtifacts());
|
private static final CorrelationCaseWrapper NO_ARTIFACTS_CASE = new CorrelationCaseWrapper(Bundle.OtherOccurrencesPanel_table_noArtifacts());
|
||||||
private static final CorrelationCaseWrapper NO_RESULTS_CASE = new CorrelationCaseWrapper(Bundle.OtherOccurrencesPanel_table_noResultsFound());
|
private static final CorrelationCaseWrapper NO_RESULTS_CASE = new CorrelationCaseWrapper(Bundle.OtherOccurrencesPanel_table_noResultsFound());
|
||||||
private static final CorrelationCaseWrapper LOADING_CASE = new CorrelationCaseWrapper(Bundle.OtherOccurrencesPanel_table_loadingResults());
|
|
||||||
private static final Logger logger = Logger.getLogger(OtherOccurrencesPanel.class.getName());
|
private static final Logger logger = Logger.getLogger(OtherOccurrencesPanel.class.getName());
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private final OtherOccurrencesFilesTableModel filesTableModel;
|
private final OtherOccurrencesFilesTableModel filesTableModel;
|
||||||
@ -84,6 +85,11 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
|||||||
private AbstractFile file = null;
|
private AbstractFile file = null;
|
||||||
|
|
||||||
private SwingWorker<?, ?> worker;
|
private SwingWorker<?, ?> worker;
|
||||||
|
|
||||||
|
// Initializing the JFileChooser in a thread to prevent a block on the EDT
|
||||||
|
// see https://stackoverflow.com/questions/49792375/jfilechooser-is-very-slow-when-using-windows-look-and-feel
|
||||||
|
private final FutureTask<JFileChooser> futureFileChooser = new FutureTask<>(JFileChooser::new);
|
||||||
|
private JFileChooser CSVFileChooser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new form OtherOccurrencesPanel
|
* Creates new form OtherOccurrencesPanel
|
||||||
@ -93,9 +99,11 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
|||||||
this.casesTableModel = new OtherOccurrencesCasesTableModel();
|
this.casesTableModel = new OtherOccurrencesCasesTableModel();
|
||||||
this.dataSourcesTableModel = new OtherOccurrencesDataSourcesTableModel();
|
this.dataSourcesTableModel = new OtherOccurrencesDataSourcesTableModel();
|
||||||
this.correlationAttributes = new ArrayList<>();
|
this.correlationAttributes = new ArrayList<>();
|
||||||
occurrencePanel = new OccurrencePanel();
|
|
||||||
initComponents();
|
initComponents();
|
||||||
customizeComponents();
|
customizeComponents();
|
||||||
|
|
||||||
|
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||||
|
executor.execute(futureFileChooser);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void customizeComponents() {
|
private void customizeComponents() {
|
||||||
@ -245,6 +253,18 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
private void saveToCSV() throws NoCurrentCaseException {
|
private void saveToCSV() throws NoCurrentCaseException {
|
||||||
if (casesTableModel.getRowCount() > 0) {
|
if (casesTableModel.getRowCount() > 0) {
|
||||||
|
|
||||||
|
if(CSVFileChooser == null) {
|
||||||
|
try{
|
||||||
|
CSVFileChooser = futureFileChooser.get();
|
||||||
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
|
// If something happened with the thread try and
|
||||||
|
// initalized the chooser now
|
||||||
|
logger.log(Level.WARNING, "A failure occurred in the JFileChooser background thread");
|
||||||
|
CSVFileChooser = new JFileChooser();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Calendar now = Calendar.getInstance();
|
Calendar now = Calendar.getInstance();
|
||||||
String fileName = String.format("%1$tY%1$tm%1$te%1$tI%1$tM%1$tS_other_data_sources.csv", now);
|
String fileName = String.format("%1$tY%1$tm%1$te%1$tI%1$tM%1$tS_other_data_sources.csv", now);
|
||||||
CSVFileChooser.setCurrentDirectory(new File(Case.getCurrentCaseThrows().getExportDirectory()));
|
CSVFileChooser.setCurrentDirectory(new File(Case.getCurrentCaseThrows().getExportDirectory()));
|
||||||
@ -258,8 +278,8 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
|||||||
if (!selectedFile.getName().endsWith(".csv")) { // NON-NLS
|
if (!selectedFile.getName().endsWith(".csv")) { // NON-NLS
|
||||||
selectedFile = new File(selectedFile.toString() + ".csv"); // NON-NLS
|
selectedFile = new File(selectedFile.toString() + ".csv"); // NON-NLS
|
||||||
}
|
}
|
||||||
CSVWorker worker = new CSVWorker(selectedFile, file, dataSourceName, deviceId, Collections.unmodifiableCollection(correlationAttributes));
|
CSVWorker csvWorker = new CSVWorker(selectedFile, file, dataSourceName, deviceId, Collections.unmodifiableCollection(correlationAttributes));
|
||||||
worker.execute();
|
csvWorker.execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -685,7 +705,6 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
|||||||
exportToCSVMenuItem = new javax.swing.JMenuItem();
|
exportToCSVMenuItem = new javax.swing.JMenuItem();
|
||||||
showCaseDetailsMenuItem = new javax.swing.JMenuItem();
|
showCaseDetailsMenuItem = new javax.swing.JMenuItem();
|
||||||
showCommonalityMenuItem = new javax.swing.JMenuItem();
|
showCommonalityMenuItem = new javax.swing.JMenuItem();
|
||||||
CSVFileChooser = new javax.swing.JFileChooser();
|
|
||||||
tableContainerPanel = new javax.swing.JPanel();
|
tableContainerPanel = new javax.swing.JPanel();
|
||||||
tablesViewerSplitPane = new javax.swing.JSplitPane();
|
tablesViewerSplitPane = new javax.swing.JSplitPane();
|
||||||
caseDatasourceFileSplitPane = new javax.swing.JSplitPane();
|
caseDatasourceFileSplitPane = new javax.swing.JSplitPane();
|
||||||
@ -704,12 +723,12 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
|||||||
filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
|
filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
|
||||||
|
|
||||||
rightClickPopupMenu.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
|
rightClickPopupMenu.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
|
||||||
public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
|
public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
|
||||||
rightClickPopupMenuPopupMenuWillBecomeVisible(evt);
|
|
||||||
}
|
}
|
||||||
public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
|
public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
|
||||||
}
|
}
|
||||||
public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
|
public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
|
||||||
|
rightClickPopupMenuPopupMenuWillBecomeVisible(evt);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -857,7 +876,6 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JFileChooser CSVFileChooser;
|
|
||||||
private javax.swing.JSplitPane caseDatasourceFileSplitPane;
|
private javax.swing.JSplitPane caseDatasourceFileSplitPane;
|
||||||
private javax.swing.JSplitPane caseDatasourceSplitPane;
|
private javax.swing.JSplitPane caseDatasourceSplitPane;
|
||||||
private javax.swing.JScrollPane caseScrollPane;
|
private javax.swing.JScrollPane caseScrollPane;
|
||||||
|
@ -130,25 +130,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSupported(Node node) {
|
public boolean isSupported(Node node) {
|
||||||
BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class);
|
return node != null && node.getLookup().lookup(AbstractFile.class) != null;
|
||||||
|
|
||||||
try {
|
|
||||||
if (artifact != null) {
|
|
||||||
if (artifact.getSleuthkitCase().getAbstractFileById(artifact.getObjectID()) != null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (node.getLookup().lookup(AbstractFile.class) != null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
logger.log(Level.SEVERE, String.format(
|
|
||||||
"Exception while trying to retrieve a Content instance from the BlackboardArtifact '%s' (id=%d).",
|
|
||||||
artifact.getDisplayName(), artifact.getArtifactID()), ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -34,6 +34,9 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import static java.util.Objects.nonNull;
|
import static java.util.Objects.nonNull;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.FutureTask;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
@ -150,7 +153,7 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
|||||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||||
private final JMenuItem exportTagsMenuItem;
|
private final JMenuItem exportTagsMenuItem;
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||||
private final JFileChooser exportChooser;
|
private JFileChooser exportChooser;
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||||
private final JFXPanel fxPanel;
|
private final JFXPanel fxPanel;
|
||||||
|
|
||||||
@ -189,10 +192,10 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
|||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
private Task<Image> readImageFileTask;
|
private Task<Image> readImageFileTask;
|
||||||
private volatile ImageTransforms imageTransforms;
|
private volatile ImageTransforms imageTransforms;
|
||||||
|
|
||||||
static {
|
// Initializing the JFileChooser in a thread to prevent a block on the EDT
|
||||||
ImageIO.scanForPlugins();
|
// see https://stackoverflow.com/questions/49792375/jfilechooser-is-very-slow-when-using-windows-look-and-feel
|
||||||
}
|
private final FutureTask<JFileChooser> futureFileChooser = new FutureTask<>(JFileChooser::new);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a media image file viewer implemented as a Swing panel that
|
* Constructs a media image file viewer implemented as a Swing panel that
|
||||||
@ -210,9 +213,9 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
|||||||
initComponents();
|
initComponents();
|
||||||
|
|
||||||
imageTransforms = new ImageTransforms(0, 0, true);
|
imageTransforms = new ImageTransforms(0, 0, true);
|
||||||
|
|
||||||
exportChooser = new JFileChooser();
|
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||||
exportChooser.setDialogTitle(Bundle.MediaViewImagePanel_fileChooserTitle());
|
executor.execute(futureFileChooser);
|
||||||
|
|
||||||
//Build popupMenu when Tags Menu button is pressed.
|
//Build popupMenu when Tags Menu button is pressed.
|
||||||
imageTaggingOptions = new JPopupMenu();
|
imageTaggingOptions = new JPopupMenu();
|
||||||
@ -1043,6 +1046,18 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
|||||||
final AbstractFile file = imageFile;
|
final AbstractFile file = imageFile;
|
||||||
tagsGroup.clearFocus();
|
tagsGroup.clearFocus();
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
|
||||||
|
if(exportChooser == null) {
|
||||||
|
try {
|
||||||
|
exportChooser = futureFileChooser.get();
|
||||||
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
|
// If something happened with the thread try and
|
||||||
|
// initalized the chooser now
|
||||||
|
logger.log(Level.WARNING, "A failure occurred in the JFileChooser background thread");
|
||||||
|
exportChooser = new JFileChooser();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
exportChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
exportChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||||
//Always base chooser location to export folder
|
//Always base chooser location to export folder
|
||||||
exportChooser.setCurrentDirectory(new File(Case.getCurrentCase().getExportDirectory()));
|
exportChooser.setCurrentDirectory(new File(Case.getCurrentCase().getExportDirectory()));
|
||||||
|
@ -150,7 +150,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
|||||||
ContentViewerHtmlStyles.getTextClassName(),
|
ContentViewerHtmlStyles.getTextClassName(),
|
||||||
EscapeUtil.escapeHtml(key),
|
EscapeUtil.escapeHtml(key),
|
||||||
ContentViewerHtmlStyles.getTextClassName(),
|
ContentViewerHtmlStyles.getTextClassName(),
|
||||||
EscapeUtil.escapeHtml(key)
|
EscapeUtil.escapeHtml(value)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2019 Basis Technology Corp.
|
* Copyright 2019-2021 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -79,9 +79,9 @@ public class TextContentViewerPanel extends javax.swing.JPanel implements DataCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the content viewer which displays this panel isSupported.
|
* Determine whether the content viewer which displays this panel
|
||||||
* This panel is supported if any of the TextViewer's displayed in it are
|
* isSupported. This panel is supported if any of the TextViewer's displayed
|
||||||
* supported.
|
* in it are supported.
|
||||||
*
|
*
|
||||||
* @param node
|
* @param node
|
||||||
*
|
*
|
||||||
@ -213,7 +213,7 @@ public class TextContentViewerPanel extends javax.swing.JPanel implements DataCo
|
|||||||
|
|
||||||
// Get and set current selected tab
|
// Get and set current selected tab
|
||||||
int currentTab = pane.getSelectedIndex();
|
int currentTab = pane.getSelectedIndex();
|
||||||
if (currentTab != -1) {
|
if (currentTab != -1 && pane.isEnabledAt(currentTab)) {
|
||||||
UpdateWrapper dcv = textViewers.get(currentTab);
|
UpdateWrapper dcv = textViewers.get(currentTab);
|
||||||
if (dcv.isOutdated()) {
|
if (dcv.isOutdated()) {
|
||||||
// change the cursor to "waiting cursor" for this operation
|
// change the cursor to "waiting cursor" for this operation
|
||||||
|
@ -33,6 +33,7 @@ import java.util.logging.Handler;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.embed.swing.JFXPanel;
|
import javafx.embed.swing.JFXPanel;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
import net.sf.sevenzipjbinding.SevenZip;
|
import net.sf.sevenzipjbinding.SevenZip;
|
||||||
import net.sf.sevenzipjbinding.SevenZipNativeInitializationException;
|
import net.sf.sevenzipjbinding.SevenZipNativeInitializationException;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
@ -44,6 +45,7 @@ import org.openide.windows.WindowManager;
|
|||||||
import org.sleuthkit.autopsy.actions.IngestRunningCheck;
|
import org.sleuthkit.autopsy.actions.IngestRunningCheck;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import static org.sleuthkit.autopsy.core.UserPreferences.SETTINGS_PROPERTIES;
|
import static org.sleuthkit.autopsy.core.UserPreferences.SETTINGS_PROPERTIES;
|
||||||
|
import org.sleuthkit.autopsy.corelibs.OpenCvLoader;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
||||||
@ -66,6 +68,13 @@ public class Installer extends ModuleInstall {
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
loadDynLibraries();
|
loadDynLibraries();
|
||||||
|
|
||||||
|
// This call was moved from MediaViewImagePanel so that it is
|
||||||
|
// not called during top level component construction.
|
||||||
|
ImageIO.scanForPlugins();
|
||||||
|
|
||||||
|
// This will cause OpenCvLoader to load its library instead of
|
||||||
|
OpenCvLoader.openCvIsLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadDynLibraries() {
|
private static void loadDynLibraries() {
|
||||||
|
@ -194,7 +194,7 @@ public class ImageUtils {
|
|||||||
public static SortedSet<String> getSupportedImageMimeTypes() {
|
public static SortedSet<String> getSupportedImageMimeTypes() {
|
||||||
return Collections.unmodifiableSortedSet(SUPPORTED_IMAGE_MIME_TYPES);
|
return Collections.unmodifiableSortedSet(SUPPORTED_IMAGE_MIME_TYPES);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the default thumbnail, which is the icon for a file. Used when we can
|
* Get the default thumbnail, which is the icon for a file. Used when we can
|
||||||
* not generate a content based thumbnail.
|
* not generate a content based thumbnail.
|
||||||
|
@ -80,6 +80,7 @@ import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.NO_DESCR;
|
|||||||
import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
|
import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
|
||||||
import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask;
|
import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask;
|
||||||
import org.sleuthkit.datamodel.AnalysisResult;
|
import org.sleuthkit.datamodel.AnalysisResult;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact.Category;
|
||||||
import org.sleuthkit.datamodel.Score;
|
import org.sleuthkit.datamodel.Score;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,17 +110,6 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
|||||||
Case.Events.CR_COMMENT_CHANGED,
|
Case.Events.CR_COMMENT_CHANGED,
|
||||||
Case.Events.CURRENT_CASE);
|
Case.Events.CURRENT_CASE);
|
||||||
|
|
||||||
/*
|
|
||||||
* Artifact types for which the unique path of the artifact's source content
|
|
||||||
* should be displayed in the node's property sheet.
|
|
||||||
*/
|
|
||||||
private static final Integer[] SHOW_UNIQUE_PATH = new Integer[]{
|
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(),
|
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(),
|
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),
|
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Artifact types for which the file metadata of the artifact's source file
|
* Artifact types for which the file metadata of the artifact's source file
|
||||||
* should be displayed in the node's property sheet.
|
* should be displayed in the node's property sheet.
|
||||||
@ -129,6 +119,7 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
|||||||
};
|
};
|
||||||
|
|
||||||
private final BlackboardArtifact artifact;
|
private final BlackboardArtifact artifact;
|
||||||
|
private final BlackboardArtifact.Type artifactType;
|
||||||
private Content srcContent;
|
private Content srcContent;
|
||||||
private volatile String translatedSourceName;
|
private volatile String translatedSourceName;
|
||||||
|
|
||||||
@ -237,6 +228,8 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
|||||||
public BlackboardArtifactNode(BlackboardArtifact artifact, String iconPath) {
|
public BlackboardArtifactNode(BlackboardArtifact artifact, String iconPath) {
|
||||||
super(artifact, createLookup(artifact, false));
|
super(artifact, createLookup(artifact, false));
|
||||||
this.artifact = artifact;
|
this.artifact = artifact;
|
||||||
|
this.artifactType = getType(artifact);
|
||||||
|
|
||||||
for (Content lookupContent : this.getLookup().lookupAll(Content.class)) {
|
for (Content lookupContent : this.getLookup().lookupAll(Content.class)) {
|
||||||
if ((lookupContent != null) && (!(lookupContent instanceof BlackboardArtifact))) {
|
if ((lookupContent != null) && (!(lookupContent instanceof BlackboardArtifact))) {
|
||||||
srcContent = lookupContent;
|
srcContent = lookupContent;
|
||||||
@ -278,6 +271,8 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
|||||||
public BlackboardArtifactNode(BlackboardArtifact artifact, boolean lookupIsAssociatedFile) {
|
public BlackboardArtifactNode(BlackboardArtifact artifact, boolean lookupIsAssociatedFile) {
|
||||||
super(artifact, createLookup(artifact, lookupIsAssociatedFile));
|
super(artifact, createLookup(artifact, lookupIsAssociatedFile));
|
||||||
this.artifact = artifact;
|
this.artifact = artifact;
|
||||||
|
this.artifactType = getType(artifact);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//The lookup for a file may or may not exist so we define the srcContent as the parent.
|
//The lookup for a file may or may not exist so we define the srcContent as the parent.
|
||||||
srcContent = artifact.getParent();
|
srcContent = artifact.getParent();
|
||||||
@ -317,6 +312,20 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
|||||||
public BlackboardArtifactNode(BlackboardArtifact artifact) {
|
public BlackboardArtifactNode(BlackboardArtifact artifact) {
|
||||||
this(artifact, IconsUtil.getIconFilePath(artifact.getArtifactTypeID()));
|
this(artifact, IconsUtil.getIconFilePath(artifact.getArtifactTypeID()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the artifact type of the artifact.
|
||||||
|
* @param artifact The artifact.
|
||||||
|
* @return The artifact type or null if no type could be retrieved.
|
||||||
|
*/
|
||||||
|
private static BlackboardArtifact.Type getType(BlackboardArtifact artifact) {
|
||||||
|
try {
|
||||||
|
return artifact.getType();
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.WARNING, MessageFormat.format("Error getting the artifact type for artifact (artifact objID={0})", artifact.getId()), ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Lookup object for this node and populates it with both the
|
* Creates a Lookup object for this node and populates it with both the
|
||||||
@ -655,7 +664,7 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
|||||||
* If the type of the artifact represented by this node dictates the
|
* If the type of the artifact represented by this node dictates the
|
||||||
* addition of the source content's unique path, add it to the sheet.
|
* addition of the source content's unique path, add it to the sheet.
|
||||||
*/
|
*/
|
||||||
if (Arrays.asList(SHOW_UNIQUE_PATH).contains(artifactTypeId)) {
|
if (artifactType != null && artifactType.getCategory() == Category.ANALYSIS_RESULT) {
|
||||||
String sourcePath = ""; //NON-NLS
|
String sourcePath = ""; //NON-NLS
|
||||||
try {
|
try {
|
||||||
sourcePath = srcContent.getUniquePath();
|
sourcePath = srcContent.getUniquePath();
|
||||||
|
@ -193,6 +193,8 @@ public class HostNode extends DisplayableItemNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(hostChangePcl, null);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the host name or 'unknown host' if null.
|
* Get the host name or 'unknown host' if null.
|
||||||
@ -251,8 +253,7 @@ public class HostNode extends DisplayableItemNode {
|
|||||||
host == null ? Lookups.fixed(displayName) : Lookups.fixed(host, displayName));
|
host == null ? Lookups.fixed(displayName) : Lookups.fixed(host, displayName));
|
||||||
|
|
||||||
hostId = host == null ? null : host.getHostId();
|
hostId = host == null ? null : host.getHostId();
|
||||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.HOSTS_UPDATED),
|
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.HOSTS_UPDATED), weakPcl);
|
||||||
WeakListeners.propertyChange(hostChangePcl, this));
|
|
||||||
super.setName(displayName);
|
super.setName(displayName);
|
||||||
super.setDisplayName(displayName);
|
super.setDisplayName(displayName);
|
||||||
this.setIconBaseWithExtension(ICON_PATH);
|
this.setIconBaseWithExtension(ICON_PATH);
|
||||||
|
@ -177,6 +177,8 @@ public class PersonNode extends DisplayableItemNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(personChangePcl, null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the display name for this person or "Unknown Persons".
|
* Gets the display name for this person or "Unknown Persons".
|
||||||
@ -214,8 +216,7 @@ public class PersonNode extends DisplayableItemNode {
|
|||||||
this.setIconBaseWithExtension(ICON_PATH);
|
this.setIconBaseWithExtension(ICON_PATH);
|
||||||
this.person = person;
|
this.person = person;
|
||||||
this.personId = person == null ? null : person.getPersonId();
|
this.personId = person == null ? null : person.getPersonId();
|
||||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.PERSONS_UPDATED),
|
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.PERSONS_UPDATED), weakPcl);
|
||||||
WeakListeners.propertyChange(personChangePcl, this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[650, 250]"/>
|
<Dimension value="[834, 374]"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
@ -24,13 +24,11 @@
|
|||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="reportModulesLabel" min="-2" max="-2" attributes="0"/>
|
<Group type="102" attributes="0">
|
||||||
<Component id="modulesScrollPane" min="-2" pref="190" max="-2" attributes="0"/>
|
<Component id="reportModulesLabel" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
</Group>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Component id="modulesSplitPane" alignment="0" max="32767" attributes="0"/>
|
||||||
<Component id="configurationPanel" max="32767" attributes="0"/>
|
|
||||||
<Component id="descriptionScrollPane" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
@ -42,14 +40,7 @@
|
|||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="reportModulesLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="reportModulesLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Component id="modulesSplitPane" max="32767" attributes="0"/>
|
||||||
<Group type="102" attributes="0">
|
|
||||||
<Component id="descriptionScrollPane" min="-2" pref="32" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
<Component id="configurationPanel" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<Component id="modulesScrollPane" pref="208" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
@ -63,78 +54,140 @@
|
|||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
<Container class="javax.swing.JPanel" name="configurationPanel">
|
<Container class="javax.swing.JSplitPane" name="modulesSplitPane">
|
||||||
<Properties>
|
|
||||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
|
||||||
<Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
|
|
||||||
<LineBorder>
|
|
||||||
<Color PropertyName="color" blue="7d" green="7d" red="7d" type="rgb"/>
|
|
||||||
</LineBorder>
|
|
||||||
</Border>
|
|
||||||
</Property>
|
|
||||||
<Property name="opaque" type="boolean" value="false"/>
|
|
||||||
</Properties>
|
|
||||||
|
|
||||||
<Layout>
|
|
||||||
<DimensionLayout dim="0">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<EmptySpace min="0" pref="432" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
<DimensionLayout dim="1">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<EmptySpace min="0" pref="168" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
</Layout>
|
|
||||||
</Container>
|
|
||||||
<Container class="javax.swing.JScrollPane" name="descriptionScrollPane">
|
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
<Border info="null"/>
|
<Border info="null"/>
|
||||||
</Property>
|
</Property>
|
||||||
|
<Property name="dividerSize" type="int" value="8"/>
|
||||||
|
<Property name="resizeWeight" type="double" value="0.5"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
<AuxValue name="JavaCodeGenerator_InitCodePre" type="java.lang.String" value="//Make border on split pane invisible to maintain previous style
modulesSplitPane.setUI(new javax.swing.plaf.basic.BasicSplitPaneUI() {
 @Override
 public javax.swing.plaf.basic.BasicSplitPaneDivider createDefaultDivider() {
 javax.swing.plaf.basic.BasicSplitPaneDivider divider = new javax.swing.plaf.basic.BasicSplitPaneDivider(this) {
 @Override
 public void setBorder(Border border){
 //do nothing so border is not visible
 }
 };
 return divider;
}
});"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
</AuxValues>
|
</AuxValues>
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Component class="javax.swing.JTextPane" name="descriptionTextPane">
|
<Container class="javax.swing.JPanel" name="detailsPanel">
|
||||||
<Properties>
|
|
||||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
|
||||||
<Color blue="f0" green="f0" red="f0" type="rgb"/>
|
|
||||||
</Property>
|
|
||||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
|
||||||
<Border info="null"/>
|
|
||||||
</Property>
|
|
||||||
<Property name="opaque" type="boolean" value="false"/>
|
|
||||||
</Properties>
|
|
||||||
</Component>
|
|
||||||
</SubComponents>
|
|
||||||
</Container>
|
|
||||||
<Container class="javax.swing.JScrollPane" name="modulesScrollPane">
|
|
||||||
<AuxValues>
|
|
||||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
|
||||||
</AuxValues>
|
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
|
||||||
<SubComponents>
|
|
||||||
<Component class="javax.swing.JList" name="modulesJList">
|
|
||||||
<Properties>
|
|
||||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
|
||||||
<Color blue="f0" green="f0" red="f0" type="rgb"/>
|
|
||||||
</Property>
|
|
||||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
|
||||||
<Connection code="new javax.swing.AbstractListModel<ReportModule>() {
 ReportModule[] modules = {};
 public int getSize() { return modules.length; }
 public ReportModule getElementAt(int i) { return modules[i]; }
}" type="code"/>
|
|
||||||
</Property>
|
|
||||||
<Property name="opaque" type="boolean" value="false"/>
|
|
||||||
</Properties>
|
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JList<>()"/>
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<ReportModule>"/>
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
</AuxValues>
|
</AuxValues>
|
||||||
</Component>
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
||||||
|
<JSplitPaneConstraints position="right"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="descriptionScrollPane" max="32767" attributes="0"/>
|
||||||
|
<Component id="configurationPanel" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||||
|
<Component id="descriptionScrollPane" min="-2" pref="32" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="configurationPanel" max="32767" attributes="0"/>
|
||||||
|
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JPanel" name="configurationPanel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
|
<Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
|
||||||
|
<LineBorder>
|
||||||
|
<Color PropertyName="color" blue="7d" green="7d" red="7d" type="rgb"/>
|
||||||
|
</LineBorder>
|
||||||
|
</Border>
|
||||||
|
</Property>
|
||||||
|
<Property name="opaque" type="boolean" value="false"/>
|
||||||
|
</Properties>
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<EmptySpace min="0" pref="546" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<EmptySpace min="0" pref="290" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
</Container>
|
||||||
|
<Container class="javax.swing.JScrollPane" name="descriptionScrollPane">
|
||||||
|
<Properties>
|
||||||
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
|
<Border info="null"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JTextPane" name="descriptionTextPane">
|
||||||
|
<Properties>
|
||||||
|
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||||
|
<Color blue="f0" green="f0" red="f0" type="rgb"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
|
<Border info="null"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="opaque" type="boolean" value="false"/>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
<Container class="javax.swing.JScrollPane" name="modulesScrollPane">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||||
|
</AuxValues>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
||||||
|
<JSplitPaneConstraints position="left"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JList" name="modulesJList">
|
||||||
|
<Properties>
|
||||||
|
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||||
|
<Color blue="f0" green="f0" red="f0" type="rgb"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
|
<Connection code="new javax.swing.AbstractListModel<ReportModule>() {
 ReportModule[] modules = {};
 public int getSize() { return modules.length; }
 public ReportModule getElementAt(int i) { return modules[i]; }
}" type="code"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="opaque" type="boolean" value="false"/>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JList<>()"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<ReportModule>"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Container>
|
</Container>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
|
@ -36,6 +36,7 @@ import javax.swing.JPanel;
|
|||||||
import javax.swing.JRadioButton;
|
import javax.swing.JRadioButton;
|
||||||
import javax.swing.ListCellRenderer;
|
import javax.swing.ListCellRenderer;
|
||||||
import javax.swing.ListSelectionModel;
|
import javax.swing.ListSelectionModel;
|
||||||
|
import javax.swing.border.Border;
|
||||||
import javax.swing.event.ListSelectionEvent;
|
import javax.swing.event.ListSelectionEvent;
|
||||||
import javax.swing.event.ListSelectionListener;
|
import javax.swing.event.ListSelectionListener;
|
||||||
import org.openide.DialogDisplayer;
|
import org.openide.DialogDisplayer;
|
||||||
@ -271,16 +272,35 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener {
|
|||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
|
||||||
reportModulesLabel = new javax.swing.JLabel();
|
reportModulesLabel = new javax.swing.JLabel();
|
||||||
|
javax.swing.JSplitPane modulesSplitPane = new javax.swing.JSplitPane();
|
||||||
|
javax.swing.JPanel detailsPanel = new javax.swing.JPanel();
|
||||||
configurationPanel = new javax.swing.JPanel();
|
configurationPanel = new javax.swing.JPanel();
|
||||||
descriptionScrollPane = new javax.swing.JScrollPane();
|
descriptionScrollPane = new javax.swing.JScrollPane();
|
||||||
descriptionTextPane = new javax.swing.JTextPane();
|
descriptionTextPane = new javax.swing.JTextPane();
|
||||||
modulesScrollPane = new javax.swing.JScrollPane();
|
modulesScrollPane = new javax.swing.JScrollPane();
|
||||||
modulesJList = new javax.swing.JList<>();
|
modulesJList = new javax.swing.JList<>();
|
||||||
|
|
||||||
setPreferredSize(new java.awt.Dimension(650, 250));
|
setPreferredSize(new java.awt.Dimension(834, 374));
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(reportModulesLabel, org.openide.util.NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.reportModulesLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(reportModulesLabel, org.openide.util.NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.reportModulesLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
//Make border on split pane invisible to maintain previous style
|
||||||
|
modulesSplitPane.setUI(new javax.swing.plaf.basic.BasicSplitPaneUI() {
|
||||||
|
@Override
|
||||||
|
public javax.swing.plaf.basic.BasicSplitPaneDivider createDefaultDivider() {
|
||||||
|
javax.swing.plaf.basic.BasicSplitPaneDivider divider = new javax.swing.plaf.basic.BasicSplitPaneDivider(this) {
|
||||||
|
@Override
|
||||||
|
public void setBorder(Border border){
|
||||||
|
//do nothing so border is not visible
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return divider;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
modulesSplitPane.setBorder(null);
|
||||||
|
modulesSplitPane.setDividerSize(8);
|
||||||
|
modulesSplitPane.setResizeWeight(0.5);
|
||||||
|
|
||||||
configurationPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(125, 125, 125)));
|
configurationPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(125, 125, 125)));
|
||||||
configurationPanel.setOpaque(false);
|
configurationPanel.setOpaque(false);
|
||||||
|
|
||||||
@ -288,11 +308,11 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener {
|
|||||||
configurationPanel.setLayout(configurationPanelLayout);
|
configurationPanel.setLayout(configurationPanelLayout);
|
||||||
configurationPanelLayout.setHorizontalGroup(
|
configurationPanelLayout.setHorizontalGroup(
|
||||||
configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGap(0, 432, Short.MAX_VALUE)
|
.addGap(0, 546, Short.MAX_VALUE)
|
||||||
);
|
);
|
||||||
configurationPanelLayout.setVerticalGroup(
|
configurationPanelLayout.setVerticalGroup(
|
||||||
configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGap(0, 168, Short.MAX_VALUE)
|
.addGap(0, 290, Short.MAX_VALUE)
|
||||||
);
|
);
|
||||||
|
|
||||||
descriptionScrollPane.setBorder(null);
|
descriptionScrollPane.setBorder(null);
|
||||||
@ -302,6 +322,29 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener {
|
|||||||
descriptionTextPane.setOpaque(false);
|
descriptionTextPane.setOpaque(false);
|
||||||
descriptionScrollPane.setViewportView(descriptionTextPane);
|
descriptionScrollPane.setViewportView(descriptionTextPane);
|
||||||
|
|
||||||
|
javax.swing.GroupLayout detailsPanelLayout = new javax.swing.GroupLayout(detailsPanel);
|
||||||
|
detailsPanel.setLayout(detailsPanelLayout);
|
||||||
|
detailsPanelLayout.setHorizontalGroup(
|
||||||
|
detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(detailsPanelLayout.createSequentialGroup()
|
||||||
|
.addGap(0, 0, 0)
|
||||||
|
.addGroup(detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(descriptionScrollPane)
|
||||||
|
.addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||||
|
.addGap(0, 0, 0))
|
||||||
|
);
|
||||||
|
detailsPanelLayout.setVerticalGroup(
|
||||||
|
detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(detailsPanelLayout.createSequentialGroup()
|
||||||
|
.addGap(0, 0, 0)
|
||||||
|
.addComponent(descriptionScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addGap(0, 0, 0))
|
||||||
|
);
|
||||||
|
|
||||||
|
modulesSplitPane.setRightComponent(detailsPanel);
|
||||||
|
|
||||||
modulesJList.setBackground(new java.awt.Color(240, 240, 240));
|
modulesJList.setBackground(new java.awt.Color(240, 240, 240));
|
||||||
modulesJList.setModel(new javax.swing.AbstractListModel<ReportModule>() {
|
modulesJList.setModel(new javax.swing.AbstractListModel<ReportModule>() {
|
||||||
ReportModule[] modules = {};
|
ReportModule[] modules = {};
|
||||||
@ -311,6 +354,8 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener {
|
|||||||
modulesJList.setOpaque(false);
|
modulesJList.setOpaque(false);
|
||||||
modulesScrollPane.setViewportView(modulesJList);
|
modulesScrollPane.setViewportView(modulesJList);
|
||||||
|
|
||||||
|
modulesSplitPane.setLeftComponent(modulesScrollPane);
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
@ -318,12 +363,10 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener {
|
|||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(reportModulesLabel)
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(modulesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 190, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(reportModulesLabel)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addGap(0, 0, Short.MAX_VALUE))
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addComponent(modulesSplitPane))
|
||||||
.addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
|
||||||
.addComponent(descriptionScrollPane))
|
|
||||||
.addContainerGap())
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
@ -332,12 +375,7 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener {
|
|||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addComponent(reportModulesLabel)
|
.addComponent(reportModulesLabel)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addComponent(modulesSplitPane)
|
||||||
.addGroup(layout.createSequentialGroup()
|
|
||||||
.addComponent(descriptionScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
||||||
.addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
||||||
.addComponent(modulesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 208, Short.MAX_VALUE))
|
|
||||||
.addContainerGap())
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
</NonVisualComponents>
|
</NonVisualComponents>
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[650, 275]"/>
|
<Dimension value="[834, 374]"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
|
@ -311,7 +311,7 @@ final class ReportVisualPanel2 extends JPanel {
|
|||||||
advancedButton = new javax.swing.JButton();
|
advancedButton = new javax.swing.JButton();
|
||||||
allTaggedResultsRadioButton = new javax.swing.JRadioButton();
|
allTaggedResultsRadioButton = new javax.swing.JRadioButton();
|
||||||
|
|
||||||
setPreferredSize(new java.awt.Dimension(650, 275));
|
setPreferredSize(new java.awt.Dimension(834, 374));
|
||||||
|
|
||||||
optionsButtonGroup.add(specificTaggedResultsRadioButton);
|
optionsButtonGroup.add(specificTaggedResultsRadioButton);
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(specificTaggedResultsRadioButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.specificTaggedResultsRadioButton.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(specificTaggedResultsRadioButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.specificTaggedResultsRadioButton.text")); // NOI18N
|
||||||
|
@ -62,6 +62,7 @@ import org.sleuthkit.autopsy.report.ReportProgressPanel;
|
|||||||
import org.sleuthkit.caseuco.CaseUcoExporter;
|
import org.sleuthkit.caseuco.CaseUcoExporter;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.Account;
|
import org.sleuthkit.datamodel.Account;
|
||||||
|
import org.sleuthkit.datamodel.AnalysisResult;
|
||||||
import org.sleuthkit.datamodel.Blackboard.BlackboardException;
|
import org.sleuthkit.datamodel.Blackboard.BlackboardException;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifactTag;
|
import org.sleuthkit.datamodel.BlackboardArtifactTag;
|
||||||
@ -69,12 +70,19 @@ import org.sleuthkit.datamodel.BlackboardAttribute;
|
|||||||
import org.sleuthkit.datamodel.CaseDbAccessManager;
|
import org.sleuthkit.datamodel.CaseDbAccessManager;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.ContentTag;
|
import org.sleuthkit.datamodel.ContentTag;
|
||||||
|
import org.sleuthkit.datamodel.DataArtifact;
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
import org.sleuthkit.datamodel.FileSystem;
|
import org.sleuthkit.datamodel.FileSystem;
|
||||||
import org.sleuthkit.datamodel.Host;
|
import org.sleuthkit.datamodel.Host;
|
||||||
import org.sleuthkit.datamodel.Image;
|
import org.sleuthkit.datamodel.Image;
|
||||||
import org.sleuthkit.datamodel.LocalFilesDataSource;
|
import org.sleuthkit.datamodel.LocalFilesDataSource;
|
||||||
|
import org.sleuthkit.datamodel.OsAccount;
|
||||||
|
import org.sleuthkit.datamodel.OsAccountManager;
|
||||||
|
import org.sleuthkit.datamodel.OsAccountManager.NotUserSIDException;
|
||||||
|
import org.sleuthkit.datamodel.OsAccountRealm;
|
||||||
|
import org.sleuthkit.datamodel.OsAccountRealmManager;
|
||||||
import org.sleuthkit.datamodel.Pool;
|
import org.sleuthkit.datamodel.Pool;
|
||||||
|
import org.sleuthkit.datamodel.Score;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction;
|
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction;
|
||||||
import org.sleuthkit.datamodel.TagName;
|
import org.sleuthkit.datamodel.TagName;
|
||||||
@ -132,6 +140,12 @@ public class PortableCaseReportModule implements ReportModule {
|
|||||||
|
|
||||||
// Map of old artifact ID to new artifact
|
// Map of old artifact ID to new artifact
|
||||||
private final Map<Long, BlackboardArtifact> oldArtifactIdToNewArtifact = new HashMap<>();
|
private final Map<Long, BlackboardArtifact> oldArtifactIdToNewArtifact = new HashMap<>();
|
||||||
|
|
||||||
|
// Map of old OS account id to new OS account id
|
||||||
|
private final Map<Long, Long> oldOsAccountIdToNewOsAccountId = new HashMap<>();
|
||||||
|
|
||||||
|
// Map of old OS account realm id to new OS account ream id
|
||||||
|
private final Map<Long, OsAccountRealm> oldRealmIdToNewRealm = new HashMap<>();
|
||||||
|
|
||||||
public PortableCaseReportModule() {
|
public PortableCaseReportModule() {
|
||||||
}
|
}
|
||||||
@ -392,8 +406,8 @@ public class PortableCaseReportModule implements ReportModule {
|
|||||||
// Copy interesting files and results
|
// Copy interesting files and results
|
||||||
if (!setNames.isEmpty()) {
|
if (!setNames.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
List<BlackboardArtifact> interestingFiles = currentCase.getSleuthkitCase().getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT);
|
List<AnalysisResult> interestingFiles = currentCase.getSleuthkitCase().getBlackboard().getAnalysisResultsByType(BlackboardArtifact.Type.TSK_INTERESTING_FILE_HIT.getTypeID());
|
||||||
for (BlackboardArtifact art : interestingFiles) {
|
for (AnalysisResult art : interestingFiles) {
|
||||||
// Check for cancellation
|
// Check for cancellation
|
||||||
if (progressPanel.getStatus() == ReportProgressPanel.ReportStatus.CANCELED) {
|
if (progressPanel.getStatus() == ReportProgressPanel.ReportStatus.CANCELED) {
|
||||||
handleCancellation(progressPanel);
|
handleCancellation(progressPanel);
|
||||||
@ -411,8 +425,8 @@ public class PortableCaseReportModule implements ReportModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<BlackboardArtifact> interestingResults = currentCase.getSleuthkitCase().getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT);
|
List<AnalysisResult> interestingResults = currentCase.getSleuthkitCase().getBlackboard().getAnalysisResultsByType(BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT.getTypeID());
|
||||||
for (BlackboardArtifact art : interestingResults) {
|
for (AnalysisResult art : interestingResults) {
|
||||||
// Check for cancellation
|
// Check for cancellation
|
||||||
if (progressPanel.getStatus() == ReportProgressPanel.ReportStatus.CANCELED) {
|
if (progressPanel.getStatus() == ReportProgressPanel.ReportStatus.CANCELED) {
|
||||||
handleCancellation(progressPanel);
|
handleCancellation(progressPanel);
|
||||||
@ -936,9 +950,6 @@ public class PortableCaseReportModule implements ReportModule {
|
|||||||
String.join(",", oldAssociatedAttribute.getSources()), newAssociatedArtifact.getArtifactID()));
|
String.join(",", oldAssociatedAttribute.getSources()), newAssociatedArtifact.getArtifactID()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the new artifact
|
|
||||||
int newArtifactTypeId = getNewArtifactTypeId(artifactToCopy);
|
|
||||||
BlackboardArtifact newArtifact = portableSkCase.newBlackboardArtifact(newArtifactTypeId, newContentId);
|
|
||||||
List<BlackboardAttribute> oldAttrs = artifactToCopy.getAttributes();
|
List<BlackboardAttribute> oldAttrs = artifactToCopy.getAttributes();
|
||||||
|
|
||||||
// Copy over each attribute, making sure the type is in the new case.
|
// Copy over each attribute, making sure the type is in the new case.
|
||||||
@ -977,8 +988,62 @@ public class PortableCaseReportModule implements ReportModule {
|
|||||||
throw new TskCoreException("Unexpected attribute value type found: " + oldAttr.getValueType().getLabel()); // NON-NLS
|
throw new TskCoreException("Unexpected attribute value type found: " + oldAttr.getValueType().getLabel()); // NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Create the new artifact
|
||||||
newArtifact.addAttributes(newAttrs);
|
int newArtifactTypeId = getNewArtifactTypeId(artifactToCopy);
|
||||||
|
BlackboardArtifact.Type newArtifactType = portableSkCase.getBlackboard().getArtifactType(newArtifactTypeId);
|
||||||
|
BlackboardArtifact newArtifact;
|
||||||
|
|
||||||
|
// First, check if the artifact being copied is an AnalysisResult or a DataArtifact. If it
|
||||||
|
// is neither, attempt to reload it as the appropriate subclass.
|
||||||
|
if (!((artifactToCopy instanceof AnalysisResult) || (artifactToCopy instanceof DataArtifact))) {
|
||||||
|
try {
|
||||||
|
if (newArtifactType.getCategory().equals(BlackboardArtifact.Category.ANALYSIS_RESULT)) {
|
||||||
|
AnalysisResult ar = currentCase.getSleuthkitCase().getBlackboard().getAnalysisResultById(artifactToCopy.getId());
|
||||||
|
if (ar != null) {
|
||||||
|
artifactToCopy = ar;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DataArtifact da = currentCase.getSleuthkitCase().getBlackboard().getDataArtifactById(artifactToCopy.getId());
|
||||||
|
if (da != null) {
|
||||||
|
artifactToCopy = da;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
// If the lookup failed, just use the orginal BlackboardArtifact
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (artifactToCopy instanceof AnalysisResult) {
|
||||||
|
AnalysisResult analysisResultToCopy = (AnalysisResult) artifactToCopy;
|
||||||
|
newArtifact = portableSkCase.getBlackboard().newAnalysisResult(newArtifactType, newContentId,
|
||||||
|
newIdToContent.get(newContentId).getDataSource().getId(), analysisResultToCopy.getScore(),
|
||||||
|
analysisResultToCopy.getConclusion(), analysisResultToCopy.getConfiguration(),
|
||||||
|
analysisResultToCopy.getJustification(), newAttrs).getAnalysisResult();
|
||||||
|
} else if (artifactToCopy instanceof DataArtifact) {
|
||||||
|
DataArtifact dataArtifactToCopy = (DataArtifact) artifactToCopy;
|
||||||
|
Long newOsAccountId = null;
|
||||||
|
if (dataArtifactToCopy.getOsAccountObjectId().isPresent()) {
|
||||||
|
copyOsAccount(dataArtifactToCopy.getOsAccountObjectId().get());
|
||||||
|
newOsAccountId = oldOsAccountIdToNewOsAccountId.get((dataArtifactToCopy.getOsAccountObjectId().get()));
|
||||||
|
}
|
||||||
|
newArtifact = portableSkCase.getBlackboard().newDataArtifact(newArtifactType, newContentId,
|
||||||
|
newIdToContent.get(newContentId).getDataSource().getId(),
|
||||||
|
newAttrs, newOsAccountId);
|
||||||
|
} else {
|
||||||
|
if (newArtifactType.getCategory().equals(BlackboardArtifact.Category.ANALYSIS_RESULT)) {
|
||||||
|
newArtifact = portableSkCase.getBlackboard().newAnalysisResult(newArtifactType, newContentId,
|
||||||
|
newIdToContent.get(newContentId).getDataSource().getId(), Score.SCORE_NONE,
|
||||||
|
null, null, null, newAttrs).getAnalysisResult();
|
||||||
|
} else {
|
||||||
|
newArtifact = portableSkCase.getBlackboard().newDataArtifact(newArtifactType, newContentId,
|
||||||
|
newIdToContent.get(newContentId).getDataSource().getId(),
|
||||||
|
newAttrs, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (BlackboardException ex) {
|
||||||
|
throw new TskCoreException("Error copying artifact with ID: " + artifactToCopy.getId());
|
||||||
|
}
|
||||||
|
|
||||||
oldArtifactIdToNewArtifact.put(artifactToCopy.getArtifactID(), newArtifact);
|
oldArtifactIdToNewArtifact.put(artifactToCopy.getArtifactID(), newArtifact);
|
||||||
return newArtifact;
|
return newArtifact;
|
||||||
@ -1088,6 +1153,14 @@ public class PortableCaseReportModule implements ReportModule {
|
|||||||
newHost = portableSkCase.getHostManager().newHost(oldHost.getName());
|
newHost = portableSkCase.getHostManager().newHost(oldHost.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy the associated OS account (if needed) before beginning transaction.
|
||||||
|
if (content instanceof AbstractFile) {
|
||||||
|
AbstractFile file = (AbstractFile) content;
|
||||||
|
if (file.getOsAccountObjectId().isPresent()) {
|
||||||
|
copyOsAccount(file.getOsAccountObjectId().get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CaseDbTransaction trans = portableSkCase.beginTransaction();
|
CaseDbTransaction trans = portableSkCase.beginTransaction();
|
||||||
try {
|
try {
|
||||||
if (content instanceof Image) {
|
if (content instanceof Image) {
|
||||||
@ -1140,10 +1213,16 @@ public class PortableCaseReportModule implements ReportModule {
|
|||||||
// Construct the relative path to the copied file
|
// Construct the relative path to the copied file
|
||||||
String relativePath = FILE_FOLDER_NAME + File.separator + exportSubFolder + File.separator + fileName;
|
String relativePath = FILE_FOLDER_NAME + File.separator + exportSubFolder + File.separator + fileName;
|
||||||
|
|
||||||
|
Long newOsAccountId = null;
|
||||||
|
if (abstractFile.getOsAccountObjectId().isPresent()) {
|
||||||
|
newOsAccountId = oldOsAccountIdToNewOsAccountId.get(abstractFile.getOsAccountObjectId().get());
|
||||||
|
}
|
||||||
|
|
||||||
newContent = portableSkCase.addLocalFile(abstractFile.getName(), relativePath, abstractFile.getSize(),
|
newContent = portableSkCase.addLocalFile(abstractFile.getName(), relativePath, abstractFile.getSize(),
|
||||||
abstractFile.getCtime(), abstractFile.getCrtime(), abstractFile.getAtime(), abstractFile.getMtime(),
|
abstractFile.getCtime(), abstractFile.getCrtime(), abstractFile.getAtime(), abstractFile.getMtime(),
|
||||||
abstractFile.getMd5Hash(), abstractFile.getSha256Hash(), abstractFile.getKnown(), abstractFile.getMIMEType(),
|
abstractFile.getMd5Hash(), abstractFile.getSha256Hash(), abstractFile.getKnown(), abstractFile.getMIMEType(),
|
||||||
true, TskData.EncodingType.NONE,
|
true, TskData.EncodingType.NONE,
|
||||||
|
newOsAccountId, abstractFile.getOwnerUid().orElse(null),
|
||||||
newParent, trans);
|
newParent, trans);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new TskCoreException("Error copying file " + abstractFile.getName() + " with original obj ID "
|
throw new TskCoreException("Error copying file " + abstractFile.getName() + " with original obj ID "
|
||||||
@ -1166,6 +1245,72 @@ public class PortableCaseReportModule implements ReportModule {
|
|||||||
newIdToContent.put(newContent.getId(), newContent);
|
newIdToContent.put(newContent.getId(), newContent);
|
||||||
return oldIdToNewContent.get(content.getId()).getId();
|
return oldIdToNewContent.get(content.getId()).getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy an OS Account to the new case and add it to the oldOsAccountIdToNewOsAccountId map.
|
||||||
|
* Will also copy the associated realm.
|
||||||
|
*
|
||||||
|
* @param oldOsAccountId The OS account id in the current case.
|
||||||
|
*/
|
||||||
|
private void copyOsAccount(Long oldOsAccountId) throws TskCoreException {
|
||||||
|
// If it has already been copied, we're done.
|
||||||
|
if (oldOsAccountIdToNewOsAccountId.containsKey(oldOsAccountId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the OS account from the current case.
|
||||||
|
OsAccountManager oldOsAcctManager = currentCase.getSleuthkitCase().getOsAccountManager();
|
||||||
|
OsAccount oldOsAccount = oldOsAcctManager.getOsAccountByObjectId(oldOsAccountId);
|
||||||
|
|
||||||
|
// Load the realm associated with the OS account.
|
||||||
|
OsAccountRealmManager oldRealmManager = currentCase.getSleuthkitCase().getOsAccountRealmManager();
|
||||||
|
OsAccountRealm oldRealm = oldRealmManager.getRealmByRealmId(oldOsAccount.getRealmId());
|
||||||
|
|
||||||
|
// Copy the realm to the portable case if necessary.
|
||||||
|
if (!oldRealmIdToNewRealm.containsKey(oldOsAccount.getRealmId())) {
|
||||||
|
OsAccountRealmManager newRealmManager = portableSkCase.getOsAccountRealmManager();
|
||||||
|
|
||||||
|
Host host = null;
|
||||||
|
if (oldRealm.getScopeHost().isPresent()) {
|
||||||
|
host = oldRealm.getScopeHost().get();
|
||||||
|
} else {
|
||||||
|
if (oldRealm.getScope().equals(OsAccountRealm.RealmScope.DOMAIN)) {
|
||||||
|
// This is a workaround to get around needing a new method for copying the realm.
|
||||||
|
// The host won't be stored since it's a domain-scoped realm.
|
||||||
|
List<Host> hosts = portableSkCase.getHostManager().getAllHosts();
|
||||||
|
if (hosts.isEmpty()) {
|
||||||
|
throw new TskCoreException("Failed to copy OsAccountRealm with ID=" + oldOsAccount.getRealmId() + " because there are no hosts in the case");
|
||||||
|
}
|
||||||
|
host = hosts.get(0);
|
||||||
|
} else {
|
||||||
|
throw new TskCoreException("Failed to copy OsAccountRealm with ID=" + oldOsAccount.getRealmId() + " because it is non-domain scoped but has no scope host");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We currently only support one realm name.
|
||||||
|
String realmName = null;
|
||||||
|
List<String> names = oldRealm.getRealmNames();
|
||||||
|
if (!names.isEmpty()) {
|
||||||
|
realmName = names.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
OsAccountRealm newRealm = newRealmManager.newWindowsRealm(oldRealm.getRealmAddr().orElse(null), realmName, host, oldRealm.getScope());
|
||||||
|
oldRealmIdToNewRealm.put(oldOsAccount.getRealmId(), newRealm);
|
||||||
|
} catch (NotUserSIDException ex) {
|
||||||
|
throw new TskCoreException("Failed to copy OsAccountRealm with ID=" + oldOsAccount.getRealmId(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OsAccountManager newOsAcctManager = portableSkCase.getOsAccountManager();
|
||||||
|
try {
|
||||||
|
OsAccount newOsAccount = newOsAcctManager.newWindowsOsAccount(oldOsAccount.getAddr().orElse(null),
|
||||||
|
oldOsAccount.getLoginName().orElse(null), oldRealmIdToNewRealm.get(oldOsAccount.getRealmId()));
|
||||||
|
oldOsAccountIdToNewOsAccountId.put(oldOsAccountId, newOsAccount.getId());
|
||||||
|
} catch (NotUserSIDException ex) {
|
||||||
|
throw new TskCoreException("Failed to copy OsAccount with ID=" + oldOsAccount.getId(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy path ID attribute to new case along with the referenced file.
|
* Copy path ID attribute to new case along with the referenced file.
|
||||||
@ -1344,6 +1489,8 @@ public class PortableCaseReportModule implements ReportModule {
|
|||||||
oldArtTypeIdToNewArtTypeId.clear();
|
oldArtTypeIdToNewArtTypeId.clear();
|
||||||
oldAttrTypeIdToNewAttrType.clear();
|
oldAttrTypeIdToNewAttrType.clear();
|
||||||
oldArtifactIdToNewArtifact.clear();
|
oldArtifactIdToNewArtifact.clear();
|
||||||
|
oldOsAccountIdToNewOsAccountId.clear();
|
||||||
|
oldRealmIdToNewRealm.clear();
|
||||||
|
|
||||||
closePortableCaseDatabase();
|
closePortableCaseDatabase();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user