diff --git a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties index 1cbc4b70b6..84f64f3190 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties @@ -36,10 +36,10 @@ GetTagNameDialog.tagNameExistsTskCore.msg=The {0} tag name already exists in the OpenLogFolder.error1=Log File Not Found: {0} OpenLogFolder.CouldNotOpenLogFolder=Could not open log folder CTL_OpenLogFolder=Open Log Folder -CTL_OpenOutputFolder=Open Output Folder -OpenOutputFolder.error1=Output Folder Not Found\: {0} -OpenOutputFolder.noCaseOpen=No open case, therefore no current output folder available. -OpenOutputFolder.CouldNotOpenOutputFolder=Could not open output folder +CTL_OpenOutputFolder=Open Case Folder +OpenOutputFolder.error1=Case Output Folder Not Found\: {0} +OpenOutputFolder.noCaseOpen=No open case, therefore no current case output folder available. +OpenOutputFolder.CouldNotOpenOutputFolder=Could not open case output folder ShowIngestProgressSnapshotAction.actionName.text=Get Ingest Progress Snapshot OpenPythonModulesFolderAction.actionName.text=Python Plugins OpenPythonModulesFolderAction.errorMsg.folderNotFound=Python plugins folder not found: {0} diff --git a/Core/src/org/sleuthkit/autopsy/actions/OpenOutputFolderAction.java b/Core/src/org/sleuthkit/autopsy/actions/OpenOutputFolderAction.java index c3477859e6..24370b5a73 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/OpenOutputFolderAction.java +++ b/Core/src/org/sleuthkit/autopsy/actions/OpenOutputFolderAction.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,7 +35,7 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; /** - * The action associated with the Tools/Open Output Folder menu item. It opens a + * The action associated with the Tools/Open Case Folder menu item. It opens a * file explorer window for the root output directory for the currently open * case. If the case is a single-user case, this is the case directory. If the * case is a multi-user case, this is a subdirectory of the case directory @@ -44,7 +44,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; * This action should only be invoked in the event dispatch thread (EDT). */ @ActionRegistration(displayName = "#CTL_OpenOutputFolder", iconInMenu = true, lazy = false) -@ActionReference(path = "Menu/Tools", position = 1850, separatorBefore = 1849) +@ActionReference(path = "Menu/Case", position = 302) @ActionID(id = "org.sleuthkit.autopsy.actions.OpenOutputFolderAction", category = "Help") public final class OpenOutputFolderAction extends CallableSystemAction { @@ -61,7 +61,7 @@ public final class OpenOutputFolderAction extends CallableSystemAction { try { Desktop.getDesktop().open(outputDir); } catch (IOException ex) { - logger.log(Level.SEVERE, String.format("Failed to open output folder %s", outputDir), ex); //NON-NLS + logger.log(Level.SEVERE, String.format("Failed to open case output folder %s", outputDir), ex); //NON-NLS NotifyDescriptor descriptor = new NotifyDescriptor.Message( NbBundle.getMessage(this.getClass(), "OpenOutputFolder.CouldNotOpenOutputFolder", outputDir.getAbsolutePath()), NotifyDescriptor.ERROR_MESSAGE); DialogDisplayer.getDefault().notify(descriptor); diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.java index b03a17920e..2a460d5c46 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -61,6 +61,11 @@ class CaseInformationPanel extends javax.swing.JPanel { @Override public void stateChanged(ChangeEvent e) { tabbedPane.getSelectedComponent().setSize(tabbedPane.getSelectedComponent().getPreferredSize()); + if (tabbedPane.getSelectedComponent() instanceof CasePropertiesPanel) { + editDetailsButton.setVisible(true); + } else { + editDetailsButton.setVisible(false); + } } }); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 2cac9b4927..87478529f7 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -2172,7 +2172,7 @@ public abstract class AbstractSqlEamDb implements EamDb { } CorrelationAttributeInstance eamArtifactInstance = new CorrelationAttributeInstance( new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name")), - new CorrelationDataSource(-1, resultSet.getInt("case_id"), resultSet.getString("device_id"), resultSet.getString("name")), + new CorrelationDataSource(resultSet.getInt("case_id"), -1, resultSet.getString("device_id"), resultSet.getString("name")), resultSet.getString("file_path"), resultSet.getString("comment"), TskData.FileKnown.valueOf(resultSet.getByte("known_status")) diff --git a/Core/src/org/sleuthkit/autopsy/core/layer.xml b/Core/src/org/sleuthkit/autopsy/core/layer.xml index 465529fa9f..fa78fe5485 100644 --- a/Core/src/org/sleuthkit/autopsy/core/layer.xml +++ b/Core/src/org/sleuthkit/autopsy/core/layer.xml @@ -198,10 +198,10 @@ - + - + @@ -213,7 +213,7 @@ --> - + diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index 95c5f50c23..792252605a 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -202,7 +202,7 @@ public class ViewContextAction extends AbstractAction { undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(content)); TreeView treeView = treeViewTopComponent.getTree(); treeView.expandNode(parentTreeViewNode); - if (treeViewTopComponent.getSelectedNode().getDisplayName().equals(parentTreeViewNode.getDisplayName())) { + if (treeViewTopComponent.getSelectedNode().equals(parentTreeViewNode)) { //In the case where our tree view already has the destination directory selected //due to an optimization in the ExplorerManager.setExploredContextAndSelection method //the property change we listen for to call DirectoryTreeTopComponent.respondSelection diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java b/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java index 19526a0a19..9158790ad6 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java @@ -34,6 +34,7 @@ class ReportExcel implements TableReportModule { private static final Logger logger = Logger.getLogger(ReportExcel.class.getName()); private static ReportExcel instance; + private static final int EXCEL_CELL_MAXIMUM_SIZE = 36767; //Specified at:https://poi.apache.org/apidocs/org/apache/poi/ss/SpreadsheetVersion.html private Workbook wb; private Sheet sheet; @@ -236,10 +237,24 @@ class ReportExcel implements TableReportModule { * @param row cells to add */ @Override + @NbBundle.Messages({ + "ReportExcel.exceptionMessage.dataTooLarge=Value is too long to fit into an Excel cell. ", + "ReportExcel.exceptionMessage.errorText=Error showing data into an Excel cell." + }) + public void addRow(List rowData) { Row row = sheet.createRow(rowIndex); for (int i = 0; i < rowData.size(); ++i) { - row.createCell(i).setCellValue(rowData.get(i)); + Cell excelCell = row.createCell(i); + try { + excelCell.setCellValue(rowData.get(i)); + } catch (Exception e) { + if (e instanceof java.lang.IllegalArgumentException && rowData.get(i).length() > EXCEL_CELL_MAXIMUM_SIZE) { + excelCell.setCellValue(Bundle.ReportExcel_exceptionMessage_dataTooLarge() + e.getMessage()); + } else { + excelCell.setCellValue(Bundle.ReportExcel_exceptionMessage_errorText()); + } + } } ++rowIndex; } diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java b/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java index 88d9fe44b1..01a179a370 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java @@ -51,6 +51,7 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.services.Services; import org.sleuthkit.autopsy.casemodule.services.TagsManager; +import org.sleuthkit.autopsy.coreutils.EscapeUtil; import org.sleuthkit.autopsy.coreutils.ImageUtils; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.ContentUtils.ExtractFscContentVisitor; @@ -554,7 +555,8 @@ class ReportHTML implements TableReportModule { StringBuilder builder = new StringBuilder(); builder.append("\t\n"); //NON-NLS for (String cell : row) { - builder.append("\t\t").append(cell).append("\n"); //NON-NLS + String escapeHTMLCell = EscapeUtil.escapeHtml(cell); + builder.append("\t\t").append(escapeHTMLCell).append("\n"); //NON-NLS } builder.append("\t\n"); //NON-NLS rowCount++; diff --git a/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java b/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java index 93894022b3..499f848d54 100644 --- a/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-16 Basis Technology Corp. + * Copyright 2013-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -40,7 +40,6 @@ import java.util.logging.Level; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.services.TagsManager; -import org.sleuthkit.autopsy.coreutils.EscapeUtil; import org.sleuthkit.autopsy.coreutils.ImageUtils; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.ContentUtils; @@ -666,8 +665,7 @@ class TableReportGenerator { tableModule.startTable(columnHeaderNames); } - String previewreplace = EscapeUtil.escapeHtml(preview); - tableModule.addRow(Arrays.asList(new String[]{previewreplace.replaceAll(" sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,13 +28,14 @@ import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; @ActionID(category = "Tools", id = "org.sleuthkit.autopsy.experimental.autoingest.AutoIngestDashboardOpenAction") -@ActionReference(path = "Menu/Tools", position = 104) +@ActionReference(path = "Menu/Tools", position = 201) @ActionRegistration(displayName = "#CTL_AutoIngestDashboardOpenAction", lazy = false) @Messages({"CTL_AutoIngestDashboardOpenAction=Auto Ingest Dashboard"}) public final class AutoIngestDashboardOpenAction extends CallableSystemAction { private static final Logger LOGGER = Logger.getLogger(AutoIngestDashboardOpenAction.class.getName()); private static final String DISPLAY_NAME = Bundle.CTL_AutoIngestDashboardOpenAction(); + private static final long serialVersionUID = 1L; @Override public boolean isEnabled() { diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/GlobalListsManagementPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/GlobalListsManagementPanel.java index aebf606380..6aae71be33 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/GlobalListsManagementPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/GlobalListsManagementPanel.java @@ -365,81 +365,84 @@ class GlobalListsManagementPanel extends javax.swing.JPanel implements OptionsPa chooser.addChoosableFileFilter(autopsyFilter); chooser.addChoosableFileFilter(encaseFilter); chooser.setAcceptAllFileFilterUsed(false); + chooser.setMultiSelectionEnabled(true); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); String listName = null; int returnVal = chooser.showOpenDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { - File selFile = chooser.getSelectedFile(); - if (selFile == null) { - return; - } + File[] selFiles = chooser.getSelectedFiles(); - //force append extension if not given - String fileAbs = selFile.getAbsolutePath(); - - final KeywordSearchList reader; - - if (KeywordSearchUtil.isXMLList(fileAbs)) { - reader = new XmlKeywordSearchList(fileAbs); - } else { - reader = new EnCaseKeywordSearchList(fileAbs); - } - - if (!reader.load()) { - KeywordSearchUtil.displayDialog( - NbBundle.getMessage(this.getClass(), "KeywordSearch.listImportFeatureTitle"), NbBundle.getMessage(this.getClass(), "KeywordSearch.importListFileDialogMsg", fileAbs), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR); - return; - } - - List toImport = reader.getListsL(); - List toImportConfirmed = new ArrayList<>(); - - final XmlKeywordSearchList writer = XmlKeywordSearchList.getCurrent(); - - for (KeywordList list : toImport) { - //check name collisions - listName = list.getName(); - if (writer.listExists(listName)) { - String[] options; - if (toImport.size() == 1) { //only give them cancel and yes buttons for single list imports - options = new String[]{NbBundle.getMessage(this.getClass(), "KeywordSearch.yesOwMsg"), - NbBundle.getMessage(this.getClass(), "KeywordSearch.cancelImportMsg")}; - } else { - options = new String[]{NbBundle.getMessage(this.getClass(), "KeywordSearch.yesOwMsg"), - NbBundle.getMessage(this.getClass(), "KeywordSearch.noSkipMsg"), - NbBundle.getMessage(this.getClass(), "KeywordSearch.cancelImportMsg")}; - } - int choice = JOptionPane.showOptionDialog(this, - NbBundle.getMessage(this.getClass(), "KeywordSearch.overwriteListPrompt", listName), - NbBundle.getMessage(this.getClass(), "KeywordSearch.importOwConflict"), - JOptionPane.YES_NO_CANCEL_OPTION, - JOptionPane.QUESTION_MESSAGE, - null, - options, - options[0]); - if (choice == JOptionPane.OK_OPTION) { - toImportConfirmed.add(list); - } else if (choice == JOptionPane.CANCEL_OPTION) { - break; - } + for (File file : selFiles) { + if (file == null) { + continue; + } + + //force append extension if not given + String fileAbs = file.getAbsolutePath(); + final KeywordSearchList reader; + if (KeywordSearchUtil.isXMLList(fileAbs)) { + reader = new XmlKeywordSearchList(fileAbs); } else { - //no conflict - toImportConfirmed.add(list); + reader = new EnCaseKeywordSearchList(fileAbs); } - } + if (!reader.load()) { + KeywordSearchUtil.displayDialog( + NbBundle.getMessage(this.getClass(), "KeywordSearch.listImportFeatureTitle"), NbBundle.getMessage(this.getClass(), "KeywordSearch.importListFileDialogMsg", fileAbs), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR); + return; + } - if (toImportConfirmed.isEmpty()) { - return; - } + List toImport = reader.getListsL(); + List toImportConfirmed = new ArrayList<>(); - if (!writer.writeLists(toImportConfirmed)) { - KeywordSearchUtil.displayDialog( - NbBundle.getMessage(this.getClass(), "KeywordSearch.listImportFeatureTitle"), NbBundle.getMessage(this.getClass(), "KeywordSearch.kwListFailImportMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO); + final XmlKeywordSearchList writer = XmlKeywordSearchList.getCurrent(); + + for (KeywordList list : toImport) { + //check name collisions + listName = list.getName(); + if (writer.listExists(listName)) { + String[] options; + if (toImport.size() == 1) { //only give them cancel and yes buttons for single list imports + options = new String[]{NbBundle.getMessage(this.getClass(), "KeywordSearch.yesOwMsg"), + NbBundle.getMessage(this.getClass(), "KeywordSearch.cancelImportMsg")}; + } else { + options = new String[]{NbBundle.getMessage(this.getClass(), "KeywordSearch.yesOwMsg"), + NbBundle.getMessage(this.getClass(), "KeywordSearch.noSkipMsg"), + NbBundle.getMessage(this.getClass(), "KeywordSearch.cancelImportMsg")}; + } + int choice = JOptionPane.showOptionDialog(this, + NbBundle.getMessage(this.getClass(), "KeywordSearch.overwriteListPrompt", listName), + NbBundle.getMessage(this.getClass(), "KeywordSearch.importOwConflict"), + JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, + options, + options[0]); + if (choice == JOptionPane.OK_OPTION) { + toImportConfirmed.add(list); + } else if (choice == JOptionPane.CANCEL_OPTION) { + break; + } + + } else { + //no conflict + toImportConfirmed.add(list); + } + + } + + if (toImportConfirmed.isEmpty()) { + return; + } + + if (!writer.writeLists(toImportConfirmed)) { + KeywordSearchUtil.displayDialog( + NbBundle.getMessage(this.getClass(), "KeywordSearch.listImportFeatureTitle"), NbBundle.getMessage(this.getClass(), "KeywordSearch.kwListFailImportMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO); + } + ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_KEYWORD_LIST_PATH_KEY, file.getParent()); } - ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_KEYWORD_LIST_PATH_KEY, selFile.getParent()); } tableModel.resync(); diff --git a/build.xml b/build.xml index 4eaa7df1c8..d044f68f06 100644 --- a/build.xml +++ b/build.xml @@ -32,7 +32,10 @@ - + + + + @@ -82,7 +85,13 @@ - + + + + + + + @@ -91,8 +100,17 @@ + - + + + + + + + + + diff --git a/docs/doxygen-user/images/case-properties-history-tab.PNG b/docs/doxygen-user/images/case-properties-history-tab.PNG index fc0a4da441..0a5d8f25b7 100644 Binary files a/docs/doxygen-user/images/case-properties-history-tab.PNG and b/docs/doxygen-user/images/case-properties-history-tab.PNG differ diff --git a/docs/doxygen-user/images/live_triage_case.png b/docs/doxygen-user/images/live_triage_case.png new file mode 100644 index 0000000000..fee49485f5 Binary files /dev/null and b/docs/doxygen-user/images/live_triage_case.png differ diff --git a/docs/doxygen-user/images/live_triage_dialog.png b/docs/doxygen-user/images/live_triage_dialog.png new file mode 100644 index 0000000000..4768ec8245 Binary files /dev/null and b/docs/doxygen-user/images/live_triage_dialog.png differ diff --git a/docs/doxygen-user/images/live_triage_ds.png b/docs/doxygen-user/images/live_triage_ds.png new file mode 100644 index 0000000000..f21a50aa82 Binary files /dev/null and b/docs/doxygen-user/images/live_triage_ds.png differ diff --git a/docs/doxygen-user/images/live_triage_script.png b/docs/doxygen-user/images/live_triage_script.png new file mode 100644 index 0000000000..2bdf7f12ae Binary files /dev/null and b/docs/doxygen-user/images/live_triage_script.png differ diff --git a/docs/doxygen-user/images/multi_user_case_select.png b/docs/doxygen-user/images/multi_user_case_select.png index f87baa555a..c4ca377fc6 100644 Binary files a/docs/doxygen-user/images/multi_user_case_select.png and b/docs/doxygen-user/images/multi_user_case_select.png differ diff --git a/docs/doxygen-user/live_triage.dox b/docs/doxygen-user/live_triage.dox new file mode 100644 index 0000000000..d85b54a20a --- /dev/null +++ b/docs/doxygen-user/live_triage.dox @@ -0,0 +1,33 @@ +/*! \page live_triage_page Live Triage + +\section live_triage_overview Overview + +The Live Triage feature allows you to load Autopsy onto a removable drive to run on target systems while making minimal changes to that target system. This will currently only work on Windows systems. + +\section live_triage_create_drive Creating a live triage drive + +To create a live triage drive, go to Tools->Make Live Triage Drive to bring up the main dialog. + +\image html live_triage_dialog.png + +Select the drive you want to use - any type of USB storage device will work. For best results use the fastest drive available. Once the process is complete the root folder will contain an Autopsy folder and a RunFromUSB.bat file. + +\section live_triage_usage Running Autopsy from the live triage drive + +Insert the drive into the target machine and browse to it in Windows Explorer. Right click on RunFromUSB.bat and select "Run as administrator". This is necessary to analyze the local drives. + +\image html live_triage_script.png + +Running the script will generate a few more directories on the USB drive. The configData directory stores all the data used by Autopsy - primarily configuration files and temporary files. You can make changes to the Autopsy settings and they will persist between runs. The cases directory is created as a recommended place to save your case data. You will need to browse to it when creating a case in Autopsy. + +Once Autopsy is running, proceed to create a case as normal, making sure to save it on the USB drive. + +\image html live_triage_case.png + +Then choose the Local Disk data source and select the desired drive. + +\image html live_triage_ds.png + +See the \ref ds_local page for more information on local disk data sources. + +*/ \ No newline at end of file diff --git a/docs/doxygen-user/main.dox b/docs/doxygen-user/main.dox index e4a1e2b3a9..a72256c7f6 100644 --- a/docs/doxygen-user/main.dox +++ b/docs/doxygen-user/main.dox @@ -60,6 +60,7 @@ The following topics are available here: - \subpage windows_authentication - \subpage multiuser_sec_page - \subpage multiuser_page +- \subpage live_triage_page - \subpage advanced_page If the topic you need is not listed, refer to the Autopsy Wiki or join the SleuthKit User List at SourceForge. diff --git a/ruleset.xml b/ruleset.xml index d4f2f075fc..9c8f7e34c2 100644 --- a/ruleset.xml +++ b/ruleset.xml @@ -1,13 +1,280 @@ - + xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd"> - Ruleset used by Autopsy + Ruleset used by Autopsy - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +