Merge branch 'develop' of github.com:sleuthkit/autopsy into 7404-tskApiChange

This commit is contained in:
Greg DiCristofaro 2021-04-15 14:54:31 -04:00
commit 801799695f
132 changed files with 617 additions and 219 deletions

View File

@ -31,6 +31,17 @@
</target>
<target name="get-thirdparty-dependencies" description="get third-party dependencies">
<!--
Copy netbeans localization jars:
This contains jars provided in Netbeans 8 RCP that provide localization bundles.
They do not appear to be included in Netbeans >= 9.
See VIK-7434 for more information.
-->
<mkdir dir="${modules.dir}/locale"/>
<copy todir="${modules.dir}/locale" >
<fileset dir="${thirdparty.dir}/NetbeansLocalization"/>
</copy>
<!--Copy photorec to release-->
<copy todir="${basedir}/release/photorec_exec" >
<fileset dir="${thirdparty.dir}/photorec_exec"/>

View File

@ -45,3 +45,4 @@ OpenPythonModulesFolderAction.actionName.text=Python Plugins
OpenPythonModulesFolderAction.errorMsg.folderNotFound=Python plugins folder not found: {0}
CTL_OpenPythonModulesFolderAction=Python Plugins
GetTagNameAndCommentDialog.tagCombo.toolTipText=Select tag to use
CTL_ExitAction=Exit

View File

@ -96,3 +96,4 @@ OpenPythonModulesFolderAction.actionName.text=Python Plugins
OpenPythonModulesFolderAction.errorMsg.folderNotFound=Python plugins folder not found: {0}
CTL_OpenPythonModulesFolderAction=Python Plugins
GetTagNameAndCommentDialog.tagCombo.toolTipText=Select tag to use
CTL_ExitAction=Exit

View File

@ -40,7 +40,7 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
* The action associated with the Case/Exit menu item. It closes the current
* case, if any, and shuts down the application.
*/
@ActionRegistration(displayName = "Exit", iconInMenu = true)
@ActionRegistration(displayName = "#CTL_ExitAction", iconInMenu = true)
@ActionReference(path = "Menu/Case", position = 1000, separatorBefore = 999)
@ActionID(id = "org.sleuthkit.autopsy.casemodule.ExitAction", category = "Case")
final public class ExitAction implements ActionListener {

View File

@ -1,3 +1,4 @@
CTL_ResetWindowsAction=Reset Windows
ResetWindowAction.confirm.text=The program will close and restart to perform the resetting of window locations.\n\nAre you sure you want to reset all window locations?
ResetWindowAction.confirm.title=Reset Windows
ResetWindowAction.caseCloseFailure.text=Unable to close the current case, the software will restart and the windows locations will reset the next time the software is closed.
ResetWindowAction.caseSaveMetadata.text=Unable to save current case path, the software will restart and the windows locations will reset but the current case will not be opened upon restart.
ResetWindowAction.confirm.text=In order to perform the resetting of window locations the software will close and restart. If a case is currently open, it will be closed. If ingest or a search is currently running, it will be terminated. Are you sure you want to restart the software to reset all window locations?

View File

@ -20,8 +20,8 @@ package org.sleuthkit.autopsy.apputils;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.apache.commons.io.FileUtils;
import org.openide.LifecycleManager;
@ -32,9 +32,10 @@ import org.openide.awt.ActionRegistration;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.CaseActionException;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
/**
@ -51,39 +52,66 @@ public final class ResetWindowsAction extends CallableSystemAction {
private static final String DISPLAY_NAME = Bundle.CTL_ResetWindowsAction();
private static final long serialVersionUID = 1L;
private final static Logger logger = Logger.getLogger(ResetWindowsAction.class.getName());
private final static String WINDOWS2LOCAL = "Windows2Local";
private final static String CASE_TO_REOPEN_FILE = "caseToOpen.txt";
@Override
public boolean isEnabled() {
return !Case.isCaseOpen();
return true;
}
@NbBundle.Messages({"ResetWindowAction.confirm.title=Reset Windows",
"ResetWindowAction.confirm.text=The program will close and restart to perform the resetting of window locations.\n\nAre you sure you want to reset all window locations?"})
@NbBundle.Messages({"ResetWindowAction.confirm.text=In order to perform the resetting of window locations the software will close and restart. "
+ "If a case is currently open, it will be closed. If ingest or a search is currently running, it will be terminated. "
+ "Are you sure you want to restart the software to reset all window locations?",
"ResetWindowAction.caseCloseFailure.text=Unable to close the current case, "
+ "the software will restart and the windows locations will reset the next time the software is closed.",
"ResetWindowAction.caseSaveMetadata.text=Unable to save current case path, "
+ "the software will restart and the windows locations will reset but the current case will not be opened upon restart."})
@Override
public void performAction() {
SwingUtilities.invokeLater(() -> {
int response = JOptionPane.showConfirmDialog(
WindowManager.getDefault().getMainWindow(),
Bundle.ResetWindowAction_confirm_text(),
Bundle.ResetWindowAction_confirm_title(),
JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE);
if (response == JOptionPane.YES_OPTION) {
boolean response = MessageNotifyUtil.Message.confirm(Bundle.ResetWindowAction_confirm_text());
if (response) {
//adding the shutdown hook, closing the current case, and marking for restart can be re-ordered if slightly different behavior is desired
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
try {
FileUtils.deleteDirectory(new File(PlatformUtil.getUserConfigDirectory() + File.separator + "Windows2Local"));
FileUtils.deleteDirectory(new File(PlatformUtil.getUserConfigDirectory() + File.separator + WINDOWS2LOCAL));
} catch (IOException ex) {
logger.log(Level.WARNING, "Unable to delete config directory, window locations will not be reset.", ex);
//While we would like the user to be aware of this in the unlikely event that the directory can not be deleted
//Because our deletion is being attempted in a shutdown hook I don't know that we can pop up UI elements during the shutdown proces
logger.log(Level.SEVERE, "Unable to delete config directory, window locations will not be reset. To manually reset the windows please delete the following directory while the software is closed. " + PlatformUtil.getUserConfigDirectory() + File.separator + "Windows2Local", ex);
}
}
});
LifecycleManager.getDefault().markForRestart();
LifecycleManager.getDefault().exit();
try {
if (Case.isCaseOpen()) {
String caseMetadataFilePath = Case.getCurrentCase().getMetadata().getFilePath().toString();
File caseToOpenFile = new File(ResetWindowsAction.getCaseToReopenFilePath());
Charset encoding = null; //prevents writeStringToFile from having ambiguous arguments
FileUtils.writeStringToFile(caseToOpenFile, caseMetadataFilePath, encoding);
Case.closeCurrentCase();
}
// The method markForRestart can not be undone once it is called.
LifecycleManager.getDefault().markForRestart();
//we need to call exit last
LifecycleManager.getDefault().exit();
} catch (CaseActionException ex) {
logger.log(Level.WARNING, Bundle.ResetWindowAction_caseCloseFailure_text(), ex);
MessageNotifyUtil.Message.show(Bundle.ResetWindowAction_caseCloseFailure_text(), MessageNotifyUtil.MessageType.ERROR);
} catch (IOException ex) {
logger.log(Level.WARNING, Bundle.ResetWindowAction_caseSaveMetadata_text(), ex);
MessageNotifyUtil.Message.show(Bundle.ResetWindowAction_caseSaveMetadata_text(), MessageNotifyUtil.MessageType.ERROR);
}
}
});
}
public static String getCaseToReopenFilePath(){
return PlatformUtil.getUserConfigDirectory() + File.separator + CASE_TO_REOPEN_FILE;
}
/**
* Set this action to be enabled/disabled
@ -91,6 +119,7 @@ public final class ResetWindowsAction extends CallableSystemAction {
* @param value whether to enable this action or not
*/
@Override
public void setEnabled(boolean value) {
super.setEnabled(value);
}

View File

@ -4,7 +4,6 @@ CTL_CaseCloseAct=Close Case
CTL_CaseNewAction=New Case
CTL_CaseDetailsAction=Case Details
CTL_CaseDeleteAction=Delete Case
Menu/Case/OpenRecentCase=Open Recent Case
CTL_CaseDeleteAction=Delete Case
OpenIDE-Module-Name=Case
NewCaseVisualPanel1.caseNameLabel.text_1=Case Name:

View File

@ -128,6 +128,7 @@ CTL_CaseCloseAct=Close Case
CTL_CaseNewAction=New Case
CTL_CaseDetailsAction=Case Details
CTL_CaseDeleteAction=Delete Case
CTL_CaseDeleteAction=Delete Case
CTL_CaseOpenAction=Open Case
CTL_UnpackagePortableCaseAction=Unpack and Open Portable Case
DeleteDataSourceAction.confirmationDialog.message=Are you sure you want to remove the selected data source from the case?\nNote that the case will be closed and re-opened during the removal.
@ -186,8 +187,6 @@ LogicalEvidenceFilePanel.pathValidation.getOpenCase.Error=Warning: Exception whi
LogicalEvidenceFilePanel.validatePanel.nonL01Error.text=Only files with the .l01 file extension are supported here.
LogicalFilesDspPanel.subTypeComboBox.l01FileOption.text=Logical evidence file (L01)
LogicalFilesDspPanel.subTypeComboBox.localFilesOption.text=Local files and folders
Menu/Case/OpenRecentCase=Open Recent Case
CTL_CaseDeleteAction=Delete Case
OpenIDE-Module-Name=Case
NewCaseVisualPanel1.caseNameLabel.text_1=Case Name:
NewCaseVisualPanel1.caseDirLabel.text=Base Directory:
@ -346,6 +345,12 @@ RecentCases.getName.text=Clear Recent Cases
RecentItems.openRecentCase.msgDlg.text=Case {0} no longer exists.
SelectDataSourceProcessorPanel.name.text=Select Data Source Type
StartupWindow.title.text=Welcome
# {0} - autFilePath
StartupWindowProvider.openCase.cantOpen=Unable to open previously open case with metadata file: {0}
# {0} - reOpenFilePath
StartupWindowProvider.openCase.deleteOpenFailure=Unable to open or delete file containing path {0} to previously open case. The previous case will not be opened.
# {0} - autFilePath
StartupWindowProvider.openCase.noFile=Unable to open previously open case because metadata file not found at: {0}
UnpackagePortableCaseDialog.title.text=Unpackage Portable Case
UnpackagePortableCaseDialog.UnpackagePortableCaseDialog.extensions=Portable case package (.zip, .zip.001)
UnpackagePortableCaseDialog.validatePaths.badExtension=File extension must be .zip or .zip.001

View File

@ -1923,7 +1923,7 @@ public class Case {
*
* @return A CaseMetaData object.
*/
CaseMetadata getMetadata() {
public CaseMetadata getMetadata() {
return metadata;
}

View File

@ -218,7 +218,7 @@ public final class CaseMetadata {
*
* @return The path to the metadata file
*/
Path getFilePath() {
public Path getFilePath() {
return metadataFilePath;
}

View File

@ -284,10 +284,10 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
ingestStream = IngestManager.getInstance().openIngestStream(image, settings);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error starting ingest modules", ex);
final List<String> errors = new ArrayList<>();
errors.add(ex.getMessage());
callBack.done(DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS, errors, new ArrayList<>());
return;
// There was an error with ingest, but the data source has already been added
// so proceed with the defaultIngestStream. Code in openIngestStream
// should have caused a dialog to popup with the errors.
ingestStream = new DefaultIngestStream();
}
doAddImageProcess(deviceId, imagePath, sectorSize, timeZone, ignoreFatOrphanFiles, md5, sha1, sha256, progress, callBack);

View File

@ -18,12 +18,18 @@
*/
package org.sleuthkit.autopsy.casemodule;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Iterator;
import java.util.logging.Level;
import org.netbeans.spi.sendopts.OptionProcessor;
import javax.swing.SwingUtilities;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.apputils.ResetWindowsAction;
import org.sleuthkit.autopsy.commandlineingest.CommandLineIngestManager;
import org.sleuthkit.autopsy.commandlineingest.CommandLineOpenCaseManager;
import org.sleuthkit.autopsy.commandlineingest.CommandLineOptionProcessor;
@ -61,15 +67,22 @@ public class StartupWindowProvider implements StartupWindowInterface {
return instance;
}
@NbBundle.Messages({
"# {0} - autFilePath",
"StartupWindowProvider.openCase.noFile=Unable to open previously open case because metadata file not found at: {0}",
"# {0} - reOpenFilePath",
"StartupWindowProvider.openCase.deleteOpenFailure=Unable to open or delete file containing path {0} to previously open case. The previous case will not be opened.",
"# {0} - autFilePath",
"StartupWindowProvider.openCase.cantOpen=Unable to open previously open case with metadata file: {0}"})
private void init() {
if (startupWindowToUse == null) {
// first check whether we are running from command line
if (isRunningFromCommandLine()) {
String defaultArg = getDefaultArgument();
if(defaultArg != null) {
new CommandLineOpenCaseManager(defaultArg).start();
return;
if (defaultArg != null) {
new CommandLineOpenCaseManager(defaultArg).start();
return;
} else {
// Autopsy is running from command line
logger.log(Level.INFO, "Running from command line"); //NON-NLS
@ -83,36 +96,41 @@ public class StartupWindowProvider implements StartupWindowInterface {
if (RuntimeProperties.runningWithGUI()) {
checkSolr();
}
//discover the registered windows
Collection<? extends StartupWindowInterface> startupWindows
= Lookup.getDefault().lookupAll(StartupWindowInterface.class);
int windowsCount = startupWindows.size();
if (windowsCount == 1) {
startupWindowToUse = startupWindows.iterator().next();
logger.log(Level.INFO, "Will use the default startup window: " + startupWindowToUse.toString()); //NON-NLS
} else if (windowsCount == 2) {
//pick the non default one
Iterator<? extends StartupWindowInterface> it = startupWindows.iterator();
while (it.hasNext()) {
StartupWindowInterface window = it.next();
if (!org.sleuthkit.autopsy.casemodule.StartupWindow.class.isInstance(window)) {
startupWindowToUse = window;
logger.log(Level.INFO, "Will use the custom startup window: " + startupWindowToUse.toString()); //NON-NLS
break;
switch (windowsCount) {
case 1:
startupWindowToUse = startupWindows.iterator().next();
logger.log(Level.INFO, "Will use the default startup window: {0}", startupWindowToUse.toString()); //NON-NLS
break;
case 2: {
//pick the non default one
Iterator<? extends StartupWindowInterface> it = startupWindows.iterator();
while (it.hasNext()) {
StartupWindowInterface window = it.next();
if (!org.sleuthkit.autopsy.casemodule.StartupWindow.class.isInstance(window)) {
startupWindowToUse = window;
logger.log(Level.INFO, "Will use the custom startup window: {0}", startupWindowToUse.toString()); //NON-NLS
break;
}
}
break;
}
} else {
// select first non-Autopsy start up window
Iterator<? extends StartupWindowInterface> it = startupWindows.iterator();
while (it.hasNext()) {
StartupWindowInterface window = it.next();
if (!window.getClass().getCanonicalName().startsWith("org.sleuthkit.autopsy")) {
startupWindowToUse = window;
logger.log(Level.INFO, "Will use the custom startup window: " + startupWindowToUse.toString()); //NON-NLS
break;
default: {
// select first non-Autopsy start up window
Iterator<? extends StartupWindowInterface> it = startupWindows.iterator();
while (it.hasNext()) {
StartupWindowInterface window = it.next();
if (!window.getClass().getCanonicalName().startsWith("org.sleuthkit.autopsy")) {
startupWindowToUse = window;
logger.log(Level.INFO, "Will use the custom startup window: {0}", startupWindowToUse.toString()); //NON-NLS
break;
}
}
break;
}
}
@ -121,6 +139,45 @@ public class StartupWindowProvider implements StartupWindowInterface {
startupWindowToUse = new org.sleuthkit.autopsy.casemodule.StartupWindow();
}
}
File openPreviousCaseFile = new File(ResetWindowsAction.getCaseToReopenFilePath());
if (openPreviousCaseFile.exists()) {
//do actual opening on another thread
new Thread(() -> {
String caseFilePath = "";
String unableToOpenMessage = null;
try {
//avoid readFileToString having ambiguous arguments
Charset encoding = null;
caseFilePath = FileUtils.readFileToString(openPreviousCaseFile, encoding);
if (new File(caseFilePath).exists()) {
FileUtils.forceDelete(openPreviousCaseFile);
//close the startup window as we attempt to open the case
close();
Case.openAsCurrentCase(caseFilePath);
} else {
unableToOpenMessage = Bundle.StartupWindowProvider_openCase_noFile(caseFilePath);
logger.log(Level.WARNING, unableToOpenMessage);
}
} catch (IOException ex) {
unableToOpenMessage = Bundle.StartupWindowProvider_openCase_deleteOpenFailure(ResetWindowsAction.getCaseToReopenFilePath());
logger.log(Level.WARNING, unableToOpenMessage, ex);
} catch (CaseActionException ex) {
unableToOpenMessage = Bundle.StartupWindowProvider_openCase_cantOpen(caseFilePath);
logger.log(Level.WARNING, unableToOpenMessage, ex);
}
if (RuntimeProperties.runningWithGUI() && !StringUtils.isBlank(unableToOpenMessage)) {
final String message = unableToOpenMessage;
SwingUtilities.invokeLater(() -> {
MessageNotifyUtil.Message.warn(message);
//the case was not opened restore the startup window
open();
});
}
}).start();
}
}
private void checkSolr() {
@ -147,9 +204,9 @@ public class StartupWindowProvider implements StartupWindowInterface {
* @return True if running from command line, false otherwise
*/
private boolean isRunningFromCommandLine() {
CommandLineOptionProcessor processor = Lookup.getDefault().lookup(CommandLineOptionProcessor.class);
if(processor != null) {
if (processor != null) {
return processor.isRunFromCommandLine();
}
return false;
@ -157,12 +214,12 @@ public class StartupWindowProvider implements StartupWindowInterface {
/**
* Get the default argument from the CommandLineOptionProcessor.
*
* @return If set, the default argument otherwise null.
*
* @return If set, the default argument otherwise null.
*/
private String getDefaultArgument() {
private String getDefaultArgument() {
CommandLineOptionProcessor processor = Lookup.getDefault().lookup(CommandLineOptionProcessor.class);
if(processor != null) {
if (processor != null) {
return processor.getDefaultArgument();
}
return null;

View File

@ -12,7 +12,7 @@ CentralRepoDbChoice.PostgreSQL.Text=Custom PostgreSQL
CentralRepoDbChoice.PostgreSQL_Multiuser.Text=PostgreSQL using multi-user settings
CentralRepoDbChoice.Sqlite.Text=SQLite
CentralRepoDbManager.connectionErrorMsg.text=Failed to connect to central repository database.
CentralRepositoryService.progressMsg.updatingSchema=Updating schema...
CentralRepositoryService.progressMsg.updatingSchema=Checking for schema updates...
CentralRepositoryService.progressMsg.waitingForListeners=Finishing adding data to central repository database....
CentralRepositoryService.serviceName=Central Repository Service
CorrelationAttributeInstance.invalidName.message=Invalid database table name. Name must start with a lowercase letter and can only contain lowercase letters, numbers, and '_'.

View File

@ -47,7 +47,7 @@ public class CentralRepositoryService implements AutopsyService {
}
@NbBundle.Messages({
"CentralRepositoryService.progressMsg.updatingSchema=Updating schema..."
"CentralRepositoryService.progressMsg.updatingSchema=Checking for schema updates..."
})
@Override
public void openCaseResources(CaseContext context) throws AutopsyServiceException {

View File

@ -27,3 +27,7 @@ ServicesMonitor.remoteKeywordSearch.displayName.text=Multi-user keyword search s
ServicesMonitor.messaging.displayName.text=Messaging service
ServicesMonitor.databaseConnectionInfo.error.msg=Error accessing case database connection info
ServicesMonitor.messagingService.connErr.text=Error accessing messaging service connection info
Actions/Case=Case
Menu/Case=Case
Toolbars/Case=Case
Menu/Case/OpenRecentCase=Open Recent Case

View File

@ -31,3 +31,7 @@ ServicesMonitor.remoteKeywordSearch.displayName.text=Multi-user keyword search s
ServicesMonitor.messaging.displayName.text=Messaging service
ServicesMonitor.databaseConnectionInfo.error.msg=Error accessing case database connection info
ServicesMonitor.messagingService.connErr.text=Error accessing messaging service connection info
Actions/Case=Case
Menu/Case=Case
Toolbars/Case=Case
Menu/Case/OpenRecentCase=Open Recent Case

View File

@ -40,6 +40,7 @@
====================================================== -->
<folder name="Actions">
<folder name="Case">
<attr name="SystemFileSystem.localizingBundle" stringvalue="org.sleuthkit.autopsy.core.Bundle"/>
<file name="org-sleuthkit-autopsy-casemodule-AddImageAction.instance"/>
<file name="org-sleuthkit-autopsy-casemodule-CaseCloseAction.instance"/>
<file name="org-sleuthkit-autopsy-casemodule-CaseNewAction.instance">
@ -140,13 +141,14 @@
<file name="Edit_hidden"/>
<file name="File_hidden"/>
<folder name="Case">
<attr name="SystemFileSystem.localizingBundle" stringvalue="org.sleuthkit.autopsy.core.Bundle"/>
<file name="org-sleuthkit-autopsy-casemodule-CaseNewAction.shadow">
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-CaseNewAction.instance"/>
<attr name="position" intvalue="100"/>
</file>
<folder name="Open Recent Case">
<folder name="OpenRecentCase">
<attr name="SystemFileSystem.localizingBundle" stringvalue="org.sleuthkit.autopsy.core.Bundle"/>
<attr name="position" intvalue="101"/>
<attr name="SystemFileSystem.localizingBundle" stringvalue="org.sleuthkit.autopsy.casemodule.Bundle"/>
<file name="org-sleuthkit-autopsy-casemodule-RecentCasesAction.shadow">
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-RecentCases.instance"/>
</file>
@ -281,7 +283,6 @@
<folder name="Help">
<file name="org-netbeans-core-actions-AboutAction.shadow_hidden"/>
<file name="org-netbeans-modules-autoupdate-ui-actions-CheckForUpdatesAction.shadow_hidden"/>
<attr name="master-help.xml/org-sleuthkit-autopsy-corecomponents-CustomAboutAction.shadow" boolvalue="true"/>
</folder>
</folder>
@ -378,6 +379,7 @@
<file name="UndoRedo_hidden"/>
<file name="File_hidden"/>
<folder name="Case">
<attr name="SystemFileSystem.localizingBundle" stringvalue="org.sleuthkit.autopsy.core.Bundle"/>
<attr name="position" intvalue="90"/>
<!--<file name="org-sleuthkit-autopsy-casemodule-AddImageAction.instance">
<attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.AddImageAction"/>

View File

@ -24,15 +24,14 @@ import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
/**
* Action to open custom implementation of the "About" window from the Help
* menu.
*/
@ActionID(id = "org.sleuthkit.autopsy.corecomponents.AboutWindowAction", category = "Help")
@ActionRegistration(displayName = "#CTL_CustomAboutAction", iconInMenu = true, lazy = false)
@ActionReference(path = "Menu/Help", position = 3000, separatorBefore = 2999)
public class AboutWindowAction extends AboutAction {

View File

@ -301,7 +301,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
/**
* Values for configuration located in the /etc/*.conf file.
* Values for configuration located in the /etc/\*.conf file.
*/
private static class ConfValues {
private final String XmxVal;
@ -335,7 +335,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
}
/**
* Retrieve the /etc/*.conf file values pertinent to settings.
* Retrieve the /etc/\*.conf file values pertinent to settings.
* @return The conf file values.
* @throws IOException
*/

View File

@ -1,6 +1,5 @@
CTL_DataContentAction=DataContent
CTL_DataContentTopComponent=Data Content
CTL_CustomAboutAction=About
OptionsCategory_Name_General=Application
OptionsCategory_Keywords_General=Autopsy Options
HINT_DataContentTopComponent=This is a DataContent window

View File

@ -28,7 +28,6 @@ AutopsyOptionsPanel_tempDirectoryBrowseButtonActionPerformed_onInvalidPath_descr
AutopsyOptionsPanel_tempDirectoryBrowseButtonActionPerformed_onInvalidPath_title=Path cannot be used
CTL_DataContentAction=DataContent
CTL_DataContentTopComponent=Data Content
CTL_CustomAboutAction=About
CTL_OfflineHelpAction=Offline Autopsy Documentation
CTL_OnlineHelpAction=Online Autopsy Documentation
DataContentViewerArtifact.failedToGetAttributes.message=Failed to get some or all attributes from case database

View File

@ -376,6 +376,10 @@ TagNode.propertySheet.origNameDisplayName=Original Name
TagsNode.displayName.text=Tags
TagsNode.createSheet.name.name=Name
TagsNode.createSheet.name.displayName=Name
UnsupportedContentNode.createSheet.name.desc=no description
UnsupportedContentNode.createSheet.name.displayName=Name
UnsupportedContentNode.createSheet.name.name=Name
UnsupportedContentNode.displayName=Unsupported Content
ViewsNode.name.text=Views
ViewsNode.createSheet.name.name=Name
ViewsNode.createSheet.name.displayName=Name

View File

@ -52,8 +52,9 @@ interface ContentNodeVisitor<T> {
T visit(BlackboardArtifactNode bban);
T visit(UnsupportedContentNode ucn);
T visit(OsAccountNode bban);
/**
* Visitor with an implementable default behavior for all types. Override
@ -126,6 +127,11 @@ interface ContentNodeVisitor<T> {
public T visit(BlackboardArtifactNode bban) {
return defaultVisit(bban);
}
@Override
public T visit(UnsupportedContentNode ucn) {
return defaultVisit(ucn);
}
@Override
public T visit(OsAccountNode bban) {

View File

@ -32,6 +32,7 @@ import org.sleuthkit.datamodel.Pool;
import org.sleuthkit.datamodel.SlackFile;
import org.sleuthkit.datamodel.SleuthkitItemVisitor;
import org.sleuthkit.datamodel.SleuthkitVisitableItem;
import org.sleuthkit.datamodel.UnsupportedContent;
import org.sleuthkit.datamodel.VirtualDirectory;
import org.sleuthkit.datamodel.Volume;
@ -99,6 +100,11 @@ public class CreateSleuthkitNodeVisitor extends SleuthkitItemVisitor.Default<Abs
public AbstractContentNode<? extends Content> visit(BlackboardArtifact art) {
return new BlackboardArtifactNode(art);
}
@Override
public AbstractContentNode<? extends Content> visit(UnsupportedContent uc) {
return new UnsupportedContentNode(uc);
}
@Override
protected AbstractContentNode<? extends Content> defaultVisit(SleuthkitVisitableItem di) {

View File

@ -202,6 +202,11 @@ public interface DisplayableItemNodeVisitor<T> {
T visit(HostNode node);
T visit(DataSourcesByTypeNode node);
/*
* Unsupported node
*/
T visit(UnsupportedContentNode ucn);
/**
* Visitor with an implementable default behavior for all types. Override
@ -574,5 +579,10 @@ public interface DisplayableItemNodeVisitor<T> {
public T visit(PersonGroupingNode node) {
return defaultVisit(node);
}
@Override
public T visit(UnsupportedContentNode node) {
return defaultVisit(node);
}
}
}

View File

@ -0,0 +1,186 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.datamodel;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Action;
import org.apache.commons.lang3.tuple.Pair;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.NO_DESCR;
import org.sleuthkit.datamodel.UnsupportedContent;
import org.sleuthkit.datamodel.Tag;
/**
* This class is used to represent the "Node" for an unsupported content object.
*/
public class UnsupportedContentNode extends AbstractContentNode<UnsupportedContent> {
/**
*
* @param unsupportedContent underlying Content instance
*/
@NbBundle.Messages({
"UnsupportedContentNode.displayName=Unsupported Content",
})
public UnsupportedContentNode(UnsupportedContent unsupportedContent) {
super(unsupportedContent);
// set name, display name, and icon
this.setDisplayName(Bundle.UnsupportedContentNode_displayName());
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-icon.png"); //NON-NLS
}
/**
* Right click action for UnsupportedContentNode node
*
* @param popup
*
* @return
*/
@Override
public Action[] getActions(boolean popup) {
List<Action> actionsList = new ArrayList<>();
for (Action a : super.getActions(true)) {
actionsList.add(a);
}
return actionsList.toArray(new Action[actionsList.size()]);
}
@NbBundle.Messages({
"UnsupportedContentNode.createSheet.name.name=Name",
"UnsupportedContentNode.createSheet.name.displayName=Name",
"UnsupportedContentNode.createSheet.name.desc=no description",
})
@Override
protected Sheet createSheet() {
Sheet sheet = super.createSheet();
Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
if (sheetSet == null) {
sheetSet = Sheet.createPropertiesSet();
sheet.put(sheetSet);
}
sheetSet.put(new NodeProperty<>(Bundle.UnsupportedContentNode_createSheet_name_name(),
Bundle.UnsupportedContentNode_createSheet_name_displayName(),
Bundle.UnsupportedContentNode_createSheet_name_desc(),
this.getDisplayName()));
return sheet;
}
@Override
public <T> T accept(ContentNodeVisitor<T> visitor) {
return visitor.visit(this);
}
@Override
public boolean isLeafTypeNode() {
return false;
}
@Override
public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
return visitor.visit(this);
}
@Override
public String getItemType() {
return getClass().getName();
}
/**
* Reads and returns a list of all tags associated with this content node.
*
* Null implementation of an abstract method.
*
* @return list of tags associated with the node.
*/
@Override
protected List<Tag> getAllTagsFromDatabase() {
return new ArrayList<>();
}
/**
* Returns correlation attribute instance for the underlying content of the
* node.
*
* Null implementation of an abstract method.
*
* @return correlation attribute instance for the underlying content of the
* node.
*/
@Override
protected CorrelationAttributeInstance getCorrelationAttributeInstance() {
return null;
}
/**
* Returns Score property for the node.
*
* Null implementation of an abstract method.
*
* @param tags list of tags.
*
* @return Score property for the underlying content of the node.
*/
@Override
protected Pair<DataResultViewerTable.Score, String> getScorePropertyAndDescription(List<Tag> tags) {
return Pair.of(DataResultViewerTable.Score.NO_SCORE, NO_DESCR);
}
/**
* Returns comment property for the node.
*
* Null implementation of an abstract method.
*
* @param tags list of tags
* @param attribute correlation attribute instance
*
* @return Comment property for the underlying content of the node.
*/
@Override
protected DataResultViewerTable.HasCommentStatus getCommentProperty(List<Tag> tags, CorrelationAttributeInstance attribute) {
return DataResultViewerTable.HasCommentStatus.NO_COMMENT;
}
/**
* Returns occurrences/count property for the node.
*
* Null implementation of an abstract method.
*
* @param attributeType the type of the attribute to count
* @param attributeValue the value of the attribute to coun
* @param defaultDescription a description to use when none is determined by
* the getCountPropertyAndDescription method
*
* @return count property for the underlying content of the node.
*/
@Override
protected Pair<Long, String> getCountPropertyAndDescription(CorrelationAttributeInstance.Type attributeType, String attributeValue, String defaultDescription) {
return Pair.of(-1L, NO_DESCR);
}
}

View File

@ -59,6 +59,7 @@ SelectionContext.views=Views
ViewContextAction.errorMessage.cannotFindDirectory=Failed to locate directory.
ViewContextAction.errorMessage.cannotFindNode=Failed to locate data source node in tree.
ViewContextAction.errorMessage.cannotSelectDirectory=Failed to select directory in tree.
ViewContextAction.errorMessage.unsupportedParent=Unable to navigate to content not supported in this release.
VolumeDetailsPanel.volumeIDLabel.text=Volume ID:
VolumeDetailsPanel.volumeIDValue.text=...
VolumeDetailsPanel.startValue.text=...

View File

@ -304,7 +304,6 @@ public class DataResultFilterNode extends FilterNode {
NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewFileInDir.text"), c));
}
// action to go to the source file of the artifact
// action to go to the source file of the artifact
Content fileContent = ban.getLookup().lookup(AbstractFile.class);
if (fileContent == null) {
Content content = ban.getLookup().lookup(Content.class);

View File

@ -63,6 +63,7 @@ import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.TskDataException;
import org.sleuthkit.datamodel.UnsupportedContent;
import org.sleuthkit.datamodel.VolumeSystem;
/**
@ -161,7 +162,8 @@ public class ViewContextAction extends AbstractAction {
@Messages({
"ViewContextAction.errorMessage.cannotFindDirectory=Failed to locate directory.",
"ViewContextAction.errorMessage.cannotSelectDirectory=Failed to select directory in tree.",
"ViewContextAction.errorMessage.cannotFindNode=Failed to locate data source node in tree."
"ViewContextAction.errorMessage.cannotFindNode=Failed to locate data source node in tree.",
"ViewContextAction.errorMessage.unsupportedParent=Unable to navigate to content not supported in this release."
})
public void actionPerformed(ActionEvent event) {
EventQueue.invokeLater(() -> {
@ -181,6 +183,13 @@ public class ViewContextAction extends AbstractAction {
logger.log(Level.SEVERE, String.format("Could not get parent of Content object: %s", content), ex); //NON-NLS
return;
}
if ((parentContent != null)
&& (parentContent instanceof UnsupportedContent)) {
MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_unsupportedParent());
logger.log(Level.WARNING, String.format("Could not navigate to unsupported content with id: %d", parentContent.getId())); //NON-NLS
return;
}
/*
* Get the "Data Sources" node from the tree view.

View File

@ -1,4 +1,3 @@
CTL_OpenGeolocation=Geolocation
CTL_GeolocationTopComponentAction=GeolocationTopComponent
CTL_GeolocationTopComponent=Geolocation
RefreshPanel.refreshLabel.text=The geolocation data has been updated, the visualization may be out of date.

View File

@ -1,6 +1,6 @@
CTL_OpenGeolocation=Geolocation
CTL_GeolocationTopComponentAction=GeolocationTopComponent
CTL_GeolocationTopComponent=Geolocation
CTL_OpenGeolocation=Geolocation
GeoFilterPanel_ArtifactType_List_Title=Types
GeoFilterPanel_DataSource_List_Title=Data Sources
GeoFilterPanel_empty_artifactType=Unable to apply filter, please select one or more artifact types.
@ -40,8 +40,6 @@ HidingPane_default_title=Filters
MapPanel_connection_failure_message=Failed to connect to new geolocation map tile source.
MapPanel_connection_failure_message_title=Connection Failure
MayWaypoint_ExternalViewer_label=Open in ExternalViewer
OpenGeolocationAction_displayName=Geolocation
OpenGeolocationAction_name=Geolocation
RefreshPanel.refreshLabel.text=The geolocation data has been updated, the visualization may be out of date.
RefreshPanel.refreshButton.text=Refresh View
RefreshPanel.closeButton.text=

View File

@ -46,17 +46,13 @@ import org.sleuthkit.autopsy.core.RuntimeProperties;
@ActionReferences(value = {
@ActionReference(path = "Menu/Tools", position = 103),
@ActionReference(path = "Toolbars/Case", position = 103)})
@Messages({"CTL_OpenGeolocation=Geolocation"})
public class OpenGeolocationAction extends CallableSystemAction {
private static final long serialVersionUID = 1L;
private final JButton toolbarButton = new JButton(getName(),
new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/blueGeo24.png"))); //NON-NLS
@Messages({
"OpenGeolocationAction_name=Geolocation",
"OpenGeolocationAction_displayName=Geolocation"
})
/**
* Constructs the new action of opening the Geolocation window.
*/
@ -98,7 +94,7 @@ public class OpenGeolocationAction extends CallableSystemAction {
@Override
public String getName() {
return Bundle.OpenGeolocationAction_displayName();
return Bundle.CTL_OpenGeolocation();
}
/**

View File

@ -31,6 +31,7 @@ import org.sleuthkit.datamodel.LocalFile;
import org.sleuthkit.datamodel.LocalDirectory;
import org.sleuthkit.datamodel.OsAccount;
import org.sleuthkit.datamodel.SlackFile;
import org.sleuthkit.datamodel.UnsupportedContent;
import org.sleuthkit.datamodel.VirtualDirectory;
/**
@ -113,4 +114,9 @@ final class GetRootDirectoryVisitor extends GetFilesContentVisitor {
public Collection<AbstractFile> visit(OsAccount art) {
return getAllFromChildren(art);
}
@Override
public Collection<AbstractFile> visit(UnsupportedContent uc) {
return getAllFromChildren(uc);
}
}

View File

@ -34,7 +34,11 @@ ILeappAnalyzerIngestModule.running.iLeapp=Running iLeapp
ILeappAnalyzerIngestModule.starting.iLeapp=Starting iLeapp
ILeappAnalyzerModuleFactory_moduleDesc=Uses iLEAPP to analyze logical acquisitions of iOS devices.
ILeappAnalyzerModuleFactory_moduleName=iOS Analyzer (iLEAPP)
LeappFileProcessor.cannot.create.calllog.relationship=Cannot create TSK_CALLLOG Relationship.
LeappFileProcessor.cannot.create.contact.relationship=Cannot create TSK_CONTACT Relationship.
LeappFileProcessor.cannot.create.message.relationship=Cannot create TSK_MESSAGE Relationship.
LeappFileProcessor.cannot.create.trackpoint.relationship=Cannot create TSK_TRACK_POINT artifact.
LeappFileProcessor.cannot.create.waypoint.relationship=Cannot create TSK_WAYPOINT artifact.
LeappFileProcessor.cannot.load.artifact.xml=Cannot load xml artifact file.
LeappFileProcessor.cannotBuildXmlParser=Cannot buld an XML parser.
LeappFileProcessor.completed=Leapp Processing Completed

View File

@ -13,6 +13,7 @@ ChromeCacheExtractor.progressMsg={0}: Extracting cache entry {1} of {2} entries
DataSourceUsage_AndroidMedia=Android Media Card
DataSourceUsage_DJU_Drone_DAT=DJI Internal SD Card
DataSourceUsage_FlashDrive=Flash Drive
# {0} - OS name
DataSourceUsageAnalyzer.customVolume.label=OS Drive ({0})
DataSourceUsageAnalyzer.parentModuleName=Recent Activity
DefaultPriorityDomainCategorizer_searchEngineCategory=Search Engine

View File

@ -175,8 +175,8 @@ final class ChromeCacheExtractor {
fileManager = currentCase.getServices().getFileManager();
// Create an output folder to save any derived files
absOutputFolderName = RAImageIngestModule.getRAOutputPath(currentCase, moduleName);
relOutputFolderName = Paths.get( RAImageIngestModule.getRelModuleOutputPath(), moduleName).normalize().toString();
absOutputFolderName = RAImageIngestModule.getRAOutputPath(currentCase, moduleName, context.getJobId());
relOutputFolderName = Paths.get(RAImageIngestModule.getRelModuleOutputPath(currentCase, moduleName, context.getJobId())).normalize().toString();
File dir = new File(absOutputFolderName);
if (dir.exists() == false) {
@ -206,7 +206,7 @@ final class ChromeCacheExtractor {
outDir.mkdirs();
}
String cacheTempPath = RAImageIngestModule.getRATempPath(currentCase, moduleName) + cachePath;
String cacheTempPath = RAImageIngestModule.getRATempPath(currentCase, moduleName, context.getJobId()) + cachePath;
File tempDir = new File(cacheTempPath);
if (tempDir.exists() == false) {
tempDir.mkdirs();
@ -222,7 +222,7 @@ final class ChromeCacheExtractor {
private void cleanup () {
for (Entry<String, FileWrapper> entry : this.fileCopyCache.entrySet()) {
Path tempFilePath = Paths.get(RAImageIngestModule.getRATempPath(currentCase, moduleName), entry.getKey() );
Path tempFilePath = Paths.get(RAImageIngestModule.getRATempPath(currentCase, moduleName, context.getJobId()), entry.getKey() );
try {
entry.getValue().getFileCopy().getChannel().close();
entry.getValue().getFileCopy().close();
@ -652,7 +652,7 @@ final class ChromeCacheExtractor {
// write the file to disk so that we can have a memory-mapped ByteBuffer
AbstractFile cacheFile = abstractFileOptional.get();
RandomAccessFile randomAccessFile = null;
String tempFilePathname = RAImageIngestModule.getRATempPath(currentCase, moduleName) + cacheFolderName + cacheFile.getName(); //NON-NLS
String tempFilePathname = RAImageIngestModule.getRATempPath(currentCase, moduleName, context.getJobId()) + cacheFolderName + cacheFile.getName(); //NON-NLS
try {
File newFile = new File(tempFilePathname);
ContentUtils.writeToFile(cacheFile, newFile, context::dataSourceIngestIsCancelled);

View File

@ -130,42 +130,43 @@ class Chromium extends Extract {
this.dataSource = dataSource;
this.context = context;
dataFound = false;
long ingestJobId = context.getJobId();
for (Map.Entry<String, String> browser : BROWSERS_MAP.entrySet()) {
String browserName = browser.getKey();
String browserLocation = browser.getValue();
progressBar.progress(NbBundle.getMessage(this.getClass(), "Progress_Message_Chrome_History", browserName));
this.getHistory(browser.getKey(), browser.getValue());
this.getHistory(browser.getKey(), browser.getValue(), ingestJobId);
if (context.dataSourceIngestIsCancelled()) {
return;
}
progressBar.progress(NbBundle.getMessage(this.getClass(), "Progress_Message_Chrome_Bookmarks", browserName));
this.getBookmark(browser.getKey(), browser.getValue());
this.getBookmark(browser.getKey(), browser.getValue(), ingestJobId);
if (context.dataSourceIngestIsCancelled()) {
return;
}
progressBar.progress(NbBundle.getMessage(this.getClass(), "Progress_Message_Chrome_Cookies", browserName));
this.getCookie(browser.getKey(), browser.getValue());
this.getCookie(browser.getKey(), browser.getValue(), ingestJobId);
if (context.dataSourceIngestIsCancelled()) {
return;
}
progressBar.progress(NbBundle.getMessage(this.getClass(), "Progress_Message_Chrome_Logins", browserName));
this.getLogins(browser.getKey(), browser.getValue());
this.getLogins(browser.getKey(), browser.getValue(), ingestJobId);
if (context.dataSourceIngestIsCancelled()) {
return;
}
progressBar.progress(NbBundle.getMessage(this.getClass(), "Progress_Message_Chrome_AutoFill", browserName));
this.getAutofill(browser.getKey(), browser.getValue());
this.getAutofill(browser.getKey(), browser.getValue(), ingestJobId);
if (context.dataSourceIngestIsCancelled()) {
return;
}
progressBar.progress(NbBundle.getMessage(this.getClass(), "Progress_Message_Chrome_Downloads", browserName));
this.getDownload(browser.getKey(), browser.getValue());
this.getDownload(browser.getKey(), browser.getValue(), ingestJobId);
if (context.dataSourceIngestIsCancelled()) {
return;
}
@ -179,8 +180,11 @@ class Chromium extends Extract {
/**
* Query for history databases and add artifacts
* @param browser
* @param browserLocation
* @param ingestJobId The ingest job id.
*/
private void getHistory(String browser, String browserLocation) {
private void getHistory(String browser, String browserLocation, long ingestJobId) {
FileManager fileManager = currentCase.getServices().getFileManager();
List<AbstractFile> historyFiles;
String historyFileName = HISTORY_FILE_NAME;
@ -215,7 +219,7 @@ class Chromium extends Extract {
Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
int j = 0;
while (j < allocatedHistoryFiles.size()) {
String temps = RAImageIngestModule.getRATempPath(currentCase, browser) + File.separator + allocatedHistoryFiles.get(j).getName() + j + ".db"; //NON-NLS
String temps = RAImageIngestModule.getRATempPath(currentCase, browser, ingestJobId) + File.separator + allocatedHistoryFiles.get(j).getName() + j + ".db"; //NON-NLS
final AbstractFile historyFile = allocatedHistoryFiles.get(j++);
if ((historyFile.getSize() == 0) || (historyFile.getName().toLowerCase().contains("-slack"))
|| (historyFile.getName().toLowerCase().contains("cache")) || (historyFile.getName().toLowerCase().contains("media"))
@ -281,8 +285,11 @@ class Chromium extends Extract {
/**
* Search for bookmark files and make artifacts.
* @param browser
* @param browserLocation
* @param ingestJobId The ingest job id.
*/
private void getBookmark(String browser, String browserLocation) {
private void getBookmark(String browser, String browserLocation, long ingestJobId) {
FileManager fileManager = currentCase.getServices().getFileManager();
List<AbstractFile> bookmarkFiles;
String bookmarkFileName = BOOKMARK_FILE_NAME;
@ -315,7 +322,7 @@ class Chromium extends Extract {
|| (bookmarkFile.getName().toLowerCase().contains("bak")) || (bookmarkFile.getParentPath().toLowerCase().contains("backup"))) {
continue;
}
String temps = RAImageIngestModule.getRATempPath(currentCase, browser) + File.separator + bookmarkFile.getName() + j + ".db"; //NON-NLS
String temps = RAImageIngestModule.getRATempPath(currentCase, browser, ingestJobId) + File.separator + bookmarkFile.getName() + j + ".db"; //NON-NLS
try {
ContentUtils.writeToFile(bookmarkFile, new File(temps), context::dataSourceIngestIsCancelled);
} catch (ReadContentInputStreamException ex) {
@ -423,8 +430,11 @@ class Chromium extends Extract {
/**
* Queries for cookie files and adds artifacts
* @param browser
* @param browserLocation
* @param ingestJobId The ingest job id.
*/
private void getCookie(String browser, String browserLocation) {
private void getCookie(String browser, String browserLocation, long ingestJobId) {
FileManager fileManager = currentCase.getServices().getFileManager();
List<AbstractFile> cookiesFiles;
@ -456,7 +466,7 @@ class Chromium extends Extract {
if ((cookiesFile.getSize() == 0) || (cookiesFile.getName().toLowerCase().contains("-slack"))) {
continue;
}
String temps = RAImageIngestModule.getRATempPath(currentCase, browser) + File.separator + cookiesFile.getName() + j + ".db"; //NON-NLS
String temps = RAImageIngestModule.getRATempPath(currentCase, browser, ingestJobId) + File.separator + cookiesFile.getName() + j + ".db"; //NON-NLS
try {
ContentUtils.writeToFile(cookiesFile, new File(temps), context::dataSourceIngestIsCancelled);
} catch (ReadContentInputStreamException ex) {
@ -519,8 +529,11 @@ class Chromium extends Extract {
/**
* Queries for download files and adds artifacts
* @param browser
* @param browserLocation
* @param ingestJobId The ingest job id.
*/
private void getDownload(String browser, String browserLocation) {
private void getDownload(String browser, String browserLocation, long ingestJobId) {
FileManager fileManager = currentCase.getServices().getFileManager();
List<AbstractFile> downloadFiles;
String historyFileName = HISTORY_FILE_NAME;
@ -551,7 +564,7 @@ class Chromium extends Extract {
continue;
}
String temps = RAImageIngestModule.getRATempPath(currentCase, browser) + File.separator + downloadFile.getName() + j + ".db"; //NON-NLS
String temps = RAImageIngestModule.getRATempPath(currentCase, browser, ingestJobId) + File.separator + downloadFile.getName() + j + ".db"; //NON-NLS
try {
ContentUtils.writeToFile(downloadFile, new File(temps), context::dataSourceIngestIsCancelled);
} catch (ReadContentInputStreamException ex) {
@ -633,8 +646,11 @@ class Chromium extends Extract {
/**
* Gets user logins from Login Data sqlite database
* @param browser
* @param browserLocation
* @param ingestJobId The ingest job id.
*/
private void getLogins(String browser, String browserLocation) {
private void getLogins(String browser, String browserLocation, long ingestJobId) {
FileManager fileManager = currentCase.getServices().getFileManager();
List<AbstractFile> loginDataFiles;
@ -665,7 +681,7 @@ class Chromium extends Extract {
if ((loginDataFile.getSize() == 0) || (loginDataFile.getName().toLowerCase().contains("-slack"))) {
continue;
}
String temps = RAImageIngestModule.getRATempPath(currentCase, browser) + File.separator + loginDataFile.getName() + j + ".db"; //NON-NLS
String temps = RAImageIngestModule.getRATempPath(currentCase, browser, ingestJobId) + File.separator + loginDataFile.getName() + j + ".db"; //NON-NLS
try {
ContentUtils.writeToFile(loginDataFile, new File(temps), context::dataSourceIngestIsCancelled);
} catch (ReadContentInputStreamException ex) {
@ -736,8 +752,11 @@ class Chromium extends Extract {
/**
* Gets and parses Autofill data from 'Web Data' database, and creates
* TSK_WEB_FORM_AUTOFILL, TSK_WEB_FORM_ADDRESS artifacts
* @param browser
* @param browserLocation
* @param ingestJobId The ingest job id.
*/
private void getAutofill(String browser, String browserLocation) {
private void getAutofill(String browser, String browserLocation, long ingestJobId) {
FileManager fileManager = currentCase.getServices().getFileManager();
List<AbstractFile> webDataFiles;
@ -768,7 +787,7 @@ class Chromium extends Extract {
if ((webDataFile.getSize() == 0) || (webDataFile.getName().toLowerCase().contains("-slack"))) {
continue;
}
String tempFilePath = RAImageIngestModule.getRATempPath(currentCase, browser) + File.separator + webDataFile.getName() + j + ".db"; //NON-NLS
String tempFilePath = RAImageIngestModule.getRATempPath(currentCase, browser, ingestJobId) + File.separator + webDataFile.getName() + j + ".db"; //NON-NLS
try {
ContentUtils.writeToFile(webDataFile, new File(tempFilePath), context::dataSourceIngestIsCancelled);
} catch (ReadContentInputStreamException ex) {

View File

@ -520,12 +520,13 @@ abstract class Extract {
*
* @param context
* @param file
* @param IngestJobId The ingest job id.
* @return Newly created copy of the AbstractFile
* @throws IOException
*/
protected File createTemporaryFile(IngestJobContext context, AbstractFile file) throws IOException{
protected File createTemporaryFile(IngestJobContext context, AbstractFile file, long ingestJobId) throws IOException{
Path tempFilePath = Paths.get(RAImageIngestModule.getRATempPath(
getCurrentCase(), getName()), file.getName() + file.getId() + file.getNameExtension());
getCurrentCase(), getName(), ingestJobId), file.getName() + file.getId() + file.getNameExtension());
java.io.File tempFile = tempFilePath.toFile();
try {

View File

@ -64,7 +64,6 @@ import org.sleuthkit.datamodel.TskCoreException;
final class ExtractEdge extends Extract {
private static final Logger LOG = Logger.getLogger(ExtractEdge.class.getName());
private final Path moduleTempResultPath;
private Content dataSource;
private IngestJobContext context;
private HashMap<String, ArrayList<String>> containersTable;
@ -125,9 +124,8 @@ final class ExtractEdge extends Extract {
/**
* Extract the bookmarks, cookies, downloads and history from Microsoft Edge
*/
ExtractEdge() throws NoCurrentCaseException {
ExtractEdge() {
super(Bundle.ExtractEdge_Module_Name());
moduleTempResultPath = Paths.get(RAImageIngestModule.getRATempPath(Case.getCurrentCaseThrows(), EDGE), EDGE_RESULT_FOLDER_NAME);
}
@Override
@ -137,6 +135,9 @@ final class ExtractEdge extends Extract {
@Override
void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
String moduleTempDir = RAImageIngestModule.getRATempPath(getCurrentCase(), EDGE, context.getJobId());
String moduleTempResultDir = Paths.get(moduleTempDir, EDGE_RESULT_FOLDER_NAME).toString();
this.dataSource = dataSource;
this.context = context;
this.setFoundData(false);
@ -186,7 +187,7 @@ final class ExtractEdge extends Extract {
}
try {
this.processWebCacheDbFile(esedumper, webCacheFiles, progressBar);
this.processWebCacheDbFile(esedumper, webCacheFiles, progressBar, moduleTempDir, moduleTempResultDir);
} catch (IOException | TskCoreException ex) {
LOG.log(Level.SEVERE, "Error processing 'WebCacheV01.dat' files for Microsoft Edge", ex); // NON-NLS
this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_webcacheFail());
@ -194,7 +195,7 @@ final class ExtractEdge extends Extract {
progressBar.progress(Bundle.Progress_Message_Edge_Bookmarks());
try {
this.processSpartanDbFile(esedumper, spartanFiles);
this.processSpartanDbFile(esedumper, spartanFiles, moduleTempDir, moduleTempResultDir);
} catch (IOException | TskCoreException ex) {
LOG.log(Level.SEVERE, "Error processing 'spartan.edb' files for Microsoft Edge", ex); // NON-NLS
this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_spartanFail());
@ -207,10 +208,13 @@ final class ExtractEdge extends Extract {
*
* @param eseDumperPath Path to ESEDatabaseView.exe
* @param webCacheFiles List of case WebCacheV01.dat files
* @param moduleTempDir The temp directory for this module.
* @param moduleTempResultDir The temp results directory for this module.
* @throws IOException
* @throws TskCoreException
*/
void processWebCacheDbFile(String eseDumperPath, List<AbstractFile> webCacheFiles, DataSourceIngestModuleProgress progressBar) throws IOException, TskCoreException {
void processWebCacheDbFile(String eseDumperPath, List<AbstractFile> webCacheFiles, DataSourceIngestModuleProgress progressBar,
String moduleTempDir, String moduleTempResultDir) throws IOException, TskCoreException {
for (AbstractFile webCacheFile : webCacheFiles) {
@ -223,7 +227,7 @@ final class ExtractEdge extends Extract {
//Run the dumper
String tempWebCacheFileName = EDGE_WEBCACHE_PREFIX
+ Integer.toString((int) webCacheFile.getId()) + EDGE_WEBCACHE_EXT; //NON-NLS
File tempWebCacheFile = new File(RAImageIngestModule.getRATempPath(currentCase, EDGE), tempWebCacheFileName);
File tempWebCacheFile = new File(moduleTempDir, tempWebCacheFileName);
try {
ContentUtils.writeToFile(webCacheFile, tempWebCacheFile,
@ -232,7 +236,7 @@ final class ExtractEdge extends Extract {
throw new IOException("Error writingToFile: " + webCacheFile, ex); //NON-NLS
}
File resultsDir = new File(moduleTempResultPath.toAbsolutePath() + Integer.toString((int) webCacheFile.getId()));
File resultsDir = new File(moduleTempDir, Integer.toString((int) webCacheFile.getId()));
resultsDir.mkdirs();
try {
executeDumper(eseDumperPath, tempWebCacheFile.getAbsolutePath(),
@ -267,10 +271,13 @@ final class ExtractEdge extends Extract {
*
* @param eseDumperPath Path to ESEDatabaseViewer
* @param spartanFiles List of the case spartan.edb files
* @param moduleTempDir The temp directory for this module.
* @param moduleTempResultDir The temp results directory for this module.
* @throws IOException
* @throws TskCoreException
*/
void processSpartanDbFile(String eseDumperPath, List<AbstractFile> spartanFiles) throws IOException, TskCoreException {
void processSpartanDbFile(String eseDumperPath, List<AbstractFile> spartanFiles,
String moduleTempDir, String moduleTempResultDir) throws IOException, TskCoreException {
for (AbstractFile spartanFile : spartanFiles) {
@ -281,7 +288,7 @@ final class ExtractEdge extends Extract {
//Run the dumper
String tempSpartanFileName = EDGE_WEBCACHE_PREFIX
+ Integer.toString((int) spartanFile.getId()) + EDGE_WEBCACHE_EXT;
File tempSpartanFile = new File(RAImageIngestModule.getRATempPath(currentCase, EDGE), tempSpartanFileName);
File tempSpartanFile = new File(moduleTempDir, tempSpartanFileName);
try {
ContentUtils.writeToFile(spartanFile, tempSpartanFile,
@ -290,7 +297,7 @@ final class ExtractEdge extends Extract {
throw new IOException("Error writingToFile: " + spartanFile, ex); //NON-NLS
}
File resultsDir = new File(moduleTempResultPath.toAbsolutePath() + Integer.toString((int) spartanFile.getId()));
File resultsDir = new File(moduleTempResultDir, Integer.toString((int) spartanFile.getId()));
resultsDir.mkdirs();
try {
executeDumper(eseDumperPath, tempSpartanFile.getAbsolutePath(),

View File

@ -31,6 +31,7 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Paths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@ -43,7 +44,6 @@ import java.util.stream.Collectors;
import org.openide.modules.InstalledFileLocator;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.datamodel.BlackboardArtifact;
@ -67,7 +67,6 @@ import org.sleuthkit.datamodel.TskCoreException;
class ExtractIE extends Extract {
private static final Logger logger = Logger.getLogger(ExtractIE.class.getName());
private final String moduleTempResultsDir;
private String PASCO_LIB_PATH;
private final String JAVA_PATH;
private static final String RESOURCE_URL_PREFIX = "res://";
@ -84,14 +83,16 @@ class ExtractIE extends Extract {
"Progress_Message_IE_AutoFill=IE Auto Fill",
"Progress_Message_IE_Logins=IE Logins",})
ExtractIE() throws NoCurrentCaseException {
ExtractIE() {
super(NbBundle.getMessage(ExtractIE.class, "ExtractIE.moduleName.text"));
moduleTempResultsDir = RAImageIngestModule.getRATempPath(Case.getCurrentCaseThrows(), "IE") + File.separator + "results"; //NON-NLS
JAVA_PATH = PlatformUtil.getJavaPath();
}
@Override
public void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
String moduleTempDir = RAImageIngestModule.getRATempPath(getCurrentCase(), "IE", context.getJobId());
String moduleTempResultsDir = Paths.get(moduleTempDir, "results").toString();
this.dataSource = dataSource;
this.context = context;
dataFound = false;
@ -111,7 +112,7 @@ class ExtractIE extends Extract {
}
progressBar.progress(Bundle.Progress_Message_IE_History());
this.getHistory();
this.getHistory(moduleTempDir, moduleTempResultsDir);
}
/**
@ -297,8 +298,10 @@ class ExtractIE extends Extract {
/**
* Locates index.dat files, runs Pasco on them, and creates artifacts.
* @param moduleTempDir The path to the module temp directory.
* @param moduleTempResultsDir The path to the module temp results directory.
*/
private void getHistory() {
private void getHistory(String moduleTempDir, String moduleTempResultsDir) {
logger.log(Level.INFO, "Pasco results path: {0}", moduleTempResultsDir); //NON-NLS
boolean foundHistory = false;
@ -350,7 +353,7 @@ class ExtractIE extends Extract {
//BlackboardArtifact bbart = fsc.newArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY);
indexFileName = "index" + Integer.toString((int) indexFile.getId()) + ".dat"; //NON-NLS
//indexFileName = "index" + Long.toString(bbart.getArtifactID()) + ".dat";
temps = RAImageIngestModule.getRATempPath(currentCase, "IE") + File.separator + indexFileName; //NON-NLS
temps = moduleTempDir + File.separator + indexFileName; //NON-NLS
File datFile = new File(temps);
if (context.dataSourceIngestIsCancelled()) {
break;
@ -366,7 +369,7 @@ class ExtractIE extends Extract {
}
String filename = "pasco2Result." + indexFile.getId() + ".txt"; //NON-NLS
boolean bPascProcSuccess = executePasco(temps, filename);
boolean bPascProcSuccess = executePasco(temps, filename, moduleTempResultsDir);
if (context.dataSourceIngestIsCancelled()) {
return;
}
@ -375,7 +378,7 @@ class ExtractIE extends Extract {
//Now fetch the results, parse them and the delete the files.
if (bPascProcSuccess) {
// Don't add TSK_OS_ACCOUNT artifacts to the ModuleDataEvent
bbartifacts.addAll(parsePascoOutput(indexFile, filename).stream()
bbartifacts.addAll(parsePascoOutput(indexFile, filename, moduleTempResultsDir).stream()
.filter(bbart -> bbart.getArtifactTypeID() == ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID())
.collect(Collectors.toList()));
if (context.dataSourceIngestIsCancelled()) {
@ -402,6 +405,7 @@ class ExtractIE extends Extract {
*
* @param indexFilePath Path to local index.dat file to analyze
* @param outputFileName Name of file to save output to
* @param moduleTempResultsDir the path to the module temp directory.
*
* @return false on error
*/
@ -409,7 +413,7 @@ class ExtractIE extends Extract {
"# {0} - sub module name",
"ExtractIE_executePasco_errMsg_errorRunningPasco={0}: Error analyzing Internet Explorer web history",
})
private boolean executePasco(String indexFilePath, String outputFileName) {
private boolean executePasco(String indexFilePath, String outputFileName, String moduleTempResultsDir) {
boolean success = true;
try {
final String outputFileFullPath = moduleTempResultsDir + File.separator + outputFileName;
@ -451,10 +455,11 @@ class ExtractIE extends Extract {
* @param origFile Original index.dat file that was analyzed to
* get this output
* @param pascoOutputFileName name of pasco output file
* @param moduleTempResultsDir the path to the module temp directory.
*
* @return A collection of created artifacts
*/
private Collection<BlackboardArtifact> parsePascoOutput(AbstractFile origFile, String pascoOutputFileName) {
private Collection<BlackboardArtifact> parsePascoOutput(AbstractFile origFile, String pascoOutputFileName, String moduleTempResultsDir) {
Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
String fnAbs = moduleTempResultsDir + File.separator + pascoOutputFileName;

View File

@ -42,6 +42,7 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
import org.sleuthkit.autopsy.coreutils.ExecUtil;
import static org.sleuthkit.autopsy.coreutils.FileUtil.escapeFileName;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.SQLiteDBConnect;
@ -91,6 +92,7 @@ final class ExtractPrefetch extends Extract {
void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
this.context = context;
long ingestJobId = context.getJobId();
String modOutPath = Case.getCurrentCase().getModuleDirectory() + File.separator + PREFETCH_DIR_NAME;
File dir = new File(modOutPath);
@ -102,7 +104,7 @@ final class ExtractPrefetch extends Extract {
}
}
extractPrefetchFiles(dataSource);
extractPrefetchFiles(dataSource, ingestJobId);
final String prefetchDumper = getPathForPrefetchDumper();
if (prefetchDumper == null) {
@ -116,9 +118,12 @@ final class ExtractPrefetch extends Extract {
String modOutFile = modOutPath + File.separator + dataSource.getName() + "-" + PREFETCH_PARSER_DB_FILE;
try {
String tempDirPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), dataSource.getName() + "-" + PREFETCH_DIR_NAME);
String tempDirPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), dataSource.getName() + "-" + PREFETCH_DIR_NAME, ingestJobId);
parsePrefetchFiles(prefetchDumper, tempDirPath, modOutFile, modOutPath);
createAppExecArtifacts(modOutFile, dataSource);
File prefetchDatabase = new File(modOutFile);
if (prefetchDatabase.exists()) {
createAppExecArtifacts(modOutFile, dataSource);
}
} catch (IOException ex) {
logger.log(Level.SEVERE, "Error parsing prefetch files", ex); //NON-NLS
addErrorMessage(Bundle.ExtractPrefetch_errMsg_prefetchParsingFailed(Bundle.ExtractPrefetch_module_name()));
@ -131,7 +136,7 @@ final class ExtractPrefetch extends Extract {
*
* @param dataSource - datasource to search for prefetch files
*/
void extractPrefetchFiles(Content dataSource) {
void extractPrefetchFiles(Content dataSource, long ingestJobId) {
List<AbstractFile> pFiles;
FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
@ -153,8 +158,8 @@ final class ExtractPrefetch extends Extract {
String origFileName = pFile.getName();
String ext = FilenameUtils.getExtension(origFileName);
String baseName = FilenameUtils.getBaseName(origFileName);
String fileName = String.format("%s_%d.%s", baseName, pFile.getId(), ext);
String baseRaTempPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), dataSource.getName() + "-" + PREFETCH_DIR_NAME);
String fileName = escapeFileName(String.format("%s_%d.%s", baseName, pFile.getId(), ext));
String baseRaTempPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), dataSource.getName() + "-" + PREFETCH_DIR_NAME, ingestJobId);
String prefetchFile = Paths.get(baseRaTempPath, fileName).toString();
try {
ContentUtils.writeToFile(pFile, new File(prefetchFile));

View File

@ -136,7 +136,7 @@ final class ExtractRecycleBin extends Extract {
return; // No need to continue
}
String tempRARecycleBinPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), "recyclebin"); //NON-NLS
String tempRARecycleBinPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), "recyclebin", context.getJobId()); //NON-NLS
// cycle through the $I files and process each.
for (AbstractFile iFile : iFiles) {

View File

@ -294,14 +294,15 @@ class ExtractRegistry extends Extract {
/**
* Identifies registry files in the database by mtimeItem, runs regripper on
* them, and parses the output.
* @param ingestJobId The ingest job id.
*/
private void analyzeRegistryFiles() {
private void analyzeRegistryFiles(long ingestJobId) {
List<AbstractFile> allRegistryFiles = findRegistryFiles();
// open the log file
FileWriter logFile = null;
try {
logFile = new FileWriter(RAImageIngestModule.getRAOutputPath(currentCase, "reg") + File.separator + "regripper-info.txt"); //NON-NLS
logFile = new FileWriter(RAImageIngestModule.getRAOutputPath(currentCase, "reg", ingestJobId) + File.separator + "regripper-info.txt"); //NON-NLS
} catch (IOException ex) {
logger.log(Level.SEVERE, null, ex);
}
@ -313,8 +314,8 @@ class ExtractRegistry extends Extract {
String regFileName = regFile.getName();
long regFileId = regFile.getId();
String regFileNameLocal = RAImageIngestModule.getRATempPath(currentCase, "reg") + File.separator + regFileName;
String outputPathBase = RAImageIngestModule.getRAOutputPath(currentCase, "reg") + File.separator + regFileName + "-regripper-" + Long.toString(regFileId); //NON-NLS
String regFileNameLocal = RAImageIngestModule.getRATempPath(currentCase, "reg", ingestJobId) + File.separator + regFileName;
String outputPathBase = RAImageIngestModule.getRAOutputPath(currentCase, "reg", ingestJobId) + File.separator + regFileName + "-regripper-" + Long.toString(regFileId); //NON-NLS
File regFileNameLocalFile = new File(regFileNameLocal);
try {
ContentUtils.writeToFile(regFile, regFileNameLocalFile, context::dataSourceIngestIsCancelled);
@ -366,7 +367,7 @@ class ExtractRegistry extends Extract {
// create a report for the full output
if (!regOutputFiles.fullPlugins.isEmpty()) {
//parse the full regripper output from SAM hive files
if (regFileNameLocal.toLowerCase().contains("sam") && parseSamPluginOutput(regOutputFiles.fullPlugins, regFile) == false) {
if (regFileNameLocal.toLowerCase().contains("sam") && parseSamPluginOutput(regOutputFiles.fullPlugins, regFile, ingestJobId) == false) {
this.addErrorMessage(
NbBundle.getMessage(this.getClass(), "ExtractRegistry.analyzeRegFiles.failedParsingResults",
this.getName(), regFileName));
@ -806,7 +807,7 @@ class ExtractRegistry extends Extract {
try {
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, value));
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, itemMtime));
BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_INSTALLED_PROG);
BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_DELETED_PROG);
bbart.addAttributes(bbattributes);
newArtifacts.add(bbart);
@ -1049,11 +1050,12 @@ class ExtractRegistry extends Extract {
*
* @param regFilePath the path to the registry file being parsed
* @param regAbstractFile the file to associate newly created artifacts with
* @param ingestJobId The ingest job id.
*
* @return true if successful, false if parsing failed at some point
*/
private boolean parseSamPluginOutput(String regFilePath, AbstractFile regAbstractFile) {
parseSystemHostDomain();
private boolean parseSamPluginOutput(String regFilePath, AbstractFile regAbstractFile, long ingestJobId) {
parseSystemHostDomain(ingestJobId);
File regfile = new File(regFilePath);
List<BlackboardArtifact> newArtifacts = new ArrayList<>();
@ -1103,7 +1105,7 @@ class ExtractRegistry extends Extract {
//add remaining userinfos as accounts;
for (Map<String, String> userInfo : userInfoMap.values()) {
OsAccount osAccount = accountMgr.newWindowsOsAccount(userInfo.get(SID_KEY), null, domainName, host, domainName != null || !domainName.isEmpty() ? OsAccountRealm.RealmScope.DOMAIN : OsAccountRealm.RealmScope.UNKNOWN);
OsAccount osAccount = accountMgr.newWindowsOsAccount(userInfo.get(SID_KEY), null, domainName, host, domainName != null && !domainName.isEmpty() ? OsAccountRealm.RealmScope.DOMAIN : OsAccountRealm.RealmScope.UNKNOWN);
accountMgr.newOsAccountInstance(osAccount, (DataSource)dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED);
updateOsAccount(osAccount, userInfo, groupMap.get(userInfo.get(SID_KEY)), regAbstractFile);
}
@ -1139,14 +1141,15 @@ class ExtractRegistry extends Extract {
/**
* Finds the Host and Domain information from the registry.
* @param ingestJobId The ingest job id.
*/
private void parseSystemHostDomain() {
private void parseSystemHostDomain(long ingestJobId) {
List<AbstractFile> regFiles = findRegistryFiles();
for (AbstractFile systemHive: regFiles) {
if (systemHive.getName().toLowerCase().equals("system")) {
if (systemHive.getName().toLowerCase().equals("system") && systemHive.getSize() > 0) {
String systemFileNameLocal = RAImageIngestModule.getRATempPath(currentCase, "reg") + File.separator + systemHive.getName();
String systemFileNameLocal = RAImageIngestModule.getRATempPath(currentCase, "reg", ingestJobId) + File.separator + "Domain-" + systemHive.getName();
File systemFileNameLocalFile = new File(systemFileNameLocal);
if (!systemFileNameLocalFile.exists()) {
@ -1989,7 +1992,7 @@ class ExtractRegistry extends Extract {
this.context = context;
progressBar.progress(Bundle.Progress_Message_Analyze_Registry());
analyzeRegistryFiles();
analyzeRegistryFiles(context.getJobId());
}
@ -2022,7 +2025,7 @@ class ExtractRegistry extends Extract {
Optional<OsAccount> optional = accountMgr.getWindowsOsAccount(sid, null, null, host);
OsAccount osAccount;
if (!optional.isPresent()) {
osAccount = accountMgr.newWindowsOsAccount(sid, userName != null && userName.isEmpty() ? null : userName, domainName, host, domainName != null || !domainName.isEmpty()? OsAccountRealm.RealmScope.DOMAIN : OsAccountRealm.RealmScope.UNKNOWN);
osAccount = accountMgr.newWindowsOsAccount(sid, userName != null && userName.isEmpty() ? null : userName, domainName, host, domainName != null && !domainName.isEmpty()? OsAccountRealm.RealmScope.DOMAIN : OsAccountRealm.RealmScope.UNKNOWN);
accountMgr.newOsAccountInstance(osAccount, (DataSource)dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED);
} else {
osAccount = optional.get();

View File

@ -289,7 +289,7 @@ final class ExtractSafari extends Extract {
return;
}
File tempHistoryFile = createTemporaryFile(context, historyFile);
File tempHistoryFile = createTemporaryFile(context, historyFile, context.getJobId());
try {
ContentUtils.writeToFile(historyFile, tempHistoryFile, context::dataSourceIngestIsCancelled);
@ -324,7 +324,7 @@ final class ExtractSafari extends Extract {
return;
}
File tempFile = createTemporaryFile(context, file);
File tempFile = createTemporaryFile(context, file, context.getJobId());
try {
if(!context.dataSourceIngestIsCancelled()) {
@ -354,7 +354,7 @@ final class ExtractSafari extends Extract {
return;
}
File tempFile = createTemporaryFile(context, file);
File tempFile = createTemporaryFile(context, file, context.getJobId());
try {
if(!context.dataSourceIngestIsCancelled()) {
@ -385,7 +385,7 @@ final class ExtractSafari extends Extract {
File tempFile = null;
try {
tempFile = createTemporaryFile(context, file);
tempFile = createTemporaryFile(context, file, context.getJobId());
if(!context.dataSourceIngestIsCancelled()) {
postArtifacts(getCookieArtifacts(file, tempFile, context));

View File

@ -100,7 +100,7 @@ final class ExtractSru extends Extract {
dir.mkdirs();
}
String tempDirPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), "sru"); //NON-NLS
String tempDirPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), "sru", context.getJobId()); //NON-NLS
String softwareHiveFileName = getSoftwareHiveFile(dataSource, tempDirPath);
if (softwareHiveFileName == null) {

View File

@ -108,47 +108,52 @@ class Firefox extends Extract {
this.dataSource = dataSource;
this.context = context;
dataFound = false;
long ingestJobId = context.getJobId();
progressBar.progress(Bundle.Progress_Message_Firefox_History());
this.getHistory();
this.getHistory(context.getJobId());
if (context.dataSourceIngestIsCancelled()) {
return;
}
progressBar.progress(Bundle.Progress_Message_Firefox_Bookmarks());
this.getBookmark();
this.getBookmark(ingestJobId);
if (context.dataSourceIngestIsCancelled()) {
return;
}
progressBar.progress(Bundle.Progress_Message_Firefox_Downloads());
this.getDownload();
this.getDownload(ingestJobId);
if (context.dataSourceIngestIsCancelled()) {
return;
}
progressBar.progress(Bundle.Progress_Message_Firefox_Cookies());
this.getCookie();
this.getCookie(ingestJobId);
if (context.dataSourceIngestIsCancelled()) {
return;
}
progressBar.progress(Bundle.Progress_Message_Firefox_FormHistory());
this.getFormsHistory();
this.getFormsHistory(ingestJobId);
if (context.dataSourceIngestIsCancelled()) {
return;
}
progressBar.progress(Bundle.Progress_Message_Firefox_AutoFill());
this.getAutofillProfiles();
this.getAutofillProfiles(ingestJobId);
}
private void getHistory() {
/**
* Get Firefox history.
* @param ingestJobId The ingest job id.
*/
private void getHistory(long ingestJobId) {
FileManager fileManager = currentCase.getServices().getFileManager();
List<AbstractFile> historyFiles;
try {
@ -180,7 +185,7 @@ class Firefox extends Extract {
}
String fileName = historyFile.getName();
String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox", ingestJobId) + File.separator + fileName + j + ".db"; //NON-NLS
try {
ContentUtils.writeToFile(historyFile, new File(temps), context::dataSourceIngestIsCancelled);
} catch (ReadContentInputStreamException ex) {
@ -254,8 +259,9 @@ class Firefox extends Extract {
/**
* Queries for bookmark files and adds artifacts
* @param ingestJobId The ingest job id.
*/
private void getBookmark() {
private void getBookmark(long ingestJobId) {
FileManager fileManager = currentCase.getServices().getFileManager();
List<AbstractFile> bookmarkFiles;
@ -281,7 +287,7 @@ class Firefox extends Extract {
continue;
}
String fileName = bookmarkFile.getName();
String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox", ingestJobId) + File.separator + fileName + j + ".db"; //NON-NLS
try {
ContentUtils.writeToFile(bookmarkFile, new File(temps), context::dataSourceIngestIsCancelled);
} catch (ReadContentInputStreamException ex) {
@ -351,8 +357,9 @@ class Firefox extends Extract {
/**
* Queries for cookies file and adds artifacts
* @param ingestJobId The ingest job id.
*/
private void getCookie() {
private void getCookie(long ingestJobId) {
FileManager fileManager = currentCase.getServices().getFileManager();
List<AbstractFile> cookiesFiles;
try {
@ -381,7 +388,7 @@ class Firefox extends Extract {
continue;
}
String fileName = cookiesFile.getName();
String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox", ingestJobId) + File.separator + fileName + j + ".db"; //NON-NLS
try {
ContentUtils.writeToFile(cookiesFile, new File(temps), context::dataSourceIngestIsCancelled);
} catch (ReadContentInputStreamException ex) {
@ -468,18 +475,20 @@ class Firefox extends Extract {
/**
* Queries for downloads files and adds artifacts
* @param ingestJobId The ingest job id.
*/
private void getDownload() {
getDownloadPreVersion24();
getDownloadVersion24();
private void getDownload(long ingestJobId) {
getDownloadPreVersion24(ingestJobId);
getDownloadVersion24(ingestJobId);
}
/**
* Finds downloads artifacts from Firefox data from versions before 24.0.
*
* Downloads were stored in a separate downloads database.
* @param ingestJobId The ingest job id.
*/
private void getDownloadPreVersion24() {
private void getDownloadPreVersion24(long ingestJobId) {
FileManager fileManager = currentCase.getServices().getFileManager();
List<AbstractFile> downloadsFiles;
@ -505,7 +514,7 @@ class Firefox extends Extract {
continue;
}
String fileName = downloadsFile.getName();
String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox", ingestJobId) + File.separator + fileName + j + ".db"; //NON-NLS
int errors = 0;
try {
ContentUtils.writeToFile(downloadsFile, new File(temps), context::dataSourceIngestIsCancelled);
@ -611,8 +620,9 @@ class Firefox extends Extract {
* Gets download artifacts from Firefox data from version 24.
*
* Downloads are stored in the places database.
* @param ingestJobId The ingest job id.
*/
private void getDownloadVersion24() {
private void getDownloadVersion24(long ingestJobId) {
FileManager fileManager = currentCase.getServices().getFileManager();
List<AbstractFile> downloadsFiles;
try {
@ -637,7 +647,7 @@ class Firefox extends Extract {
continue;
}
String fileName = downloadsFile.getName();
String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + "-downloads" + j + ".db"; //NON-NLS
String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox", ingestJobId) + File.separator + fileName + "-downloads" + j + ".db"; //NON-NLS
int errors = 0;
try {
ContentUtils.writeToFile(downloadsFile, new File(temps), context::dataSourceIngestIsCancelled);
@ -742,8 +752,9 @@ class Firefox extends Extract {
/**
* Gets data from formshistory.sqlite database.
* Parses and creates artifacts.
* @param ingestJobId The ingest job id.
*/
private void getFormsHistory() {
private void getFormsHistory(long ingestJobId) {
FileManager fileManager = currentCase.getServices().getFileManager();
List<AbstractFile> formHistoryFiles;
@ -777,7 +788,7 @@ class Firefox extends Extract {
}
String fileName = formHistoryFile.getName();
String tempFilePath = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
String tempFilePath = RAImageIngestModule.getRATempPath(currentCase, "firefox", ingestJobId) + File.separator + fileName + j + ".db"; //NON-NLS
try {
ContentUtils.writeToFile(formHistoryFile, new File(tempFilePath), context::dataSourceIngestIsCancelled);
} catch (ReadContentInputStreamException ex) {
@ -864,9 +875,9 @@ class Firefox extends Extract {
/**
* Gets data from autofill-profiles.json file.
* Parses file and makes artifacts.
*
* @param ingestJobId The ingest job id.
*/
private void getAutofillProfiles() {
private void getAutofillProfiles(long ingestJobId) {
FileManager fileManager = currentCase.getServices().getFileManager();
List<AbstractFile> autofillProfilesFiles;
try {
@ -891,7 +902,7 @@ class Firefox extends Extract {
if (profileFile.getSize() == 0) {
continue;
}
String temps = RAImageIngestModule.getRATempPath(currentCase, "Firefox") + File.separator + profileFile.getName() + j + ".json"; //NON-NLS
String temps = RAImageIngestModule.getRATempPath(currentCase, "Firefox", ingestJobId) + File.separator + profileFile.getName() + j + ".json"; //NON-NLS
try {
ContentUtils.writeToFile(profileFile, new File(temps), context::dataSourceIngestIsCancelled);
} catch (ReadContentInputStreamException ex) {

View File

@ -27,6 +27,7 @@ import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -116,6 +117,9 @@ public class ParseRegistryHive {
}
} catch (RegistryParseException ex) {
return null;
} catch (NoSuchElementException ex) {
logger.log(Level.WARNING, String.format("Cannot find the registry key %s in the registry hive file %s", registryKey, registryHiveFile.toString()));
return null;
}
return currentKey;

View File

@ -23,15 +23,16 @@
package org.sleuthkit.autopsy.recentactivity;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.TimeStampUtils;
import org.sleuthkit.autopsy.ingest.DataSourceIngestModule;
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
import org.sleuthkit.autopsy.ingest.IngestServices;
@ -41,7 +42,6 @@ import org.sleuthkit.datamodel.Content;
import org.sleuthkit.autopsy.ingest.IngestModule.ProcessResult;
import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.OsAccount;
import org.sleuthkit.datamodel.SleuthkitCase;
/**
@ -49,6 +49,7 @@ import org.sleuthkit.datamodel.SleuthkitCase;
*/
public final class RAImageIngestModule implements DataSourceIngestModule {
private static final String RECENT_ACTIVITY_FOLDER = "RecentActivity";
private static final Logger logger = Logger.getLogger(RAImageIngestModule.class.getName());
private final List<Extract> extractors = new ArrayList<>();
private final List<Extract> browserExtractors = new ArrayList<>();
@ -64,18 +65,11 @@ public final class RAImageIngestModule implements DataSourceIngestModule {
@Override
public void startUp(IngestJobContext context) throws IngestModuleException {
this.context = context;
tskCase = Case.getCurrentCase().getSleuthkitCase();
Extract iexplore;
Extract edge;
try {
iexplore = new ExtractIE();
edge = new ExtractEdge();
} catch (NoCurrentCaseException ex) {
throw new IngestModuleException(ex.getMessage(), ex);
}
Extract iexplore = new ExtractIE();
Extract edge = new ExtractEdge();
Extract registry = new ExtractRegistry();
Extract recentDocuments = new RecentDocumentsByLnk();
Extract chrome = new Chromium();
@ -104,10 +98,10 @@ public final class RAImageIngestModule implements DataSourceIngestModule {
extractors.add(webAccountType); // this needs to run after the web browser modules
extractors.add(zoneInfo); // this needs to run after the web browser modules
extractors.add(recycleBin); // this needs to run after ExtractRegistry and ExtractOS
extractors.add(sru);
extractors.add(sru);
extractors.add(prefetch);
extractors.add(messageDomainType);
browserExtractors.add(chrome);
browserExtractors.add(firefox);
browserExtractors.add(iexplore);
@ -141,8 +135,8 @@ public final class RAImageIngestModule implements DataSourceIngestModule {
try {
extracter.process(dataSource, context, progressBar, accountCache);
if(extracter instanceof ExtractRegistry) {
accountCache.initialize(tskCase, ((DataSource)dataSource).getHost());
if (extracter instanceof ExtractRegistry) {
accountCache.initialize(tskCase, ((DataSource) dataSource).getHost());
}
} catch (Exception ex) {
logger.log(Level.SEVERE, "Exception occurred in " + extracter.getName(), ex); //NON-NLS
@ -221,23 +215,39 @@ public final class RAImageIngestModule implements DataSourceIngestModule {
return ProcessResult.OK;
}
/**
* Makes a path of the format
* [basePath]/[RECENT_ACTIVITY_FOLDER]/[module]_[ingest job id] if it does not
* already exist and returns the created folder.
*
* @param basePath The base path (a case-related folder like temp or
* output).
* @param module The module name to include in the folder name.
* @param ingestJobId The id of the ingest job.
* @return The path to the folder.
*/
private static String getAndMakeRAPath(String basePath, String module, long ingestJobId) {
String moduleFolder = String.format("%s_%d", module, ingestJobId);
Path tmpPath = Paths.get(basePath, RECENT_ACTIVITY_FOLDER, moduleFolder);
File dir = tmpPath.toFile();
if (dir.exists() == false) {
dir.mkdirs();
}
return tmpPath.toString();
}
/**
* Get the temp path for a specific sub-module in recent activity. Will
* create the dir if it doesn't exist.
*
* @param a_case Case that directory is for
* @param mod Module name that will be used for a sub folder in the temp
* folder to prevent name collisions
* @param mod Module name that will be used for a sub folder in the temp
* folder to prevent name collisions
*
* @return Path to directory
*/
static String getRATempPath(Case a_case, String mod) {
String tmpDir = a_case.getTempDirectory() + File.separator + "RecentActivity" + File.separator + mod; //NON-NLS
File dir = new File(tmpDir);
if (dir.exists() == false) {
dir.mkdirs();
}
return tmpDir;
static String getRATempPath(Case a_case, String mod, long ingestJobId) {
return getAndMakeRAPath(a_case.getTempDirectory(), mod, ingestJobId);
}
/**
@ -245,28 +255,24 @@ public final class RAImageIngestModule implements DataSourceIngestModule {
* create the dir if it doesn't exist.
*
* @param a_case Case that directory is for
* @param mod Module name that will be used for a sub folder in the temp
* folder to prevent name collisions
* @param mod Module name that will be used for a sub folder in the temp
* folder to prevent name collisions
*
* @return Path to directory
*/
static String getRAOutputPath(Case a_case, String mod) {
String tmpDir = a_case.getModuleDirectory() + File.separator + "RecentActivity" + File.separator + mod; //NON-NLS
File dir = new File(tmpDir);
if (dir.exists() == false) {
dir.mkdirs();
}
return tmpDir;
static String getRAOutputPath(Case a_case, String mod, long ingestJobId) {
return getAndMakeRAPath(a_case.getModuleDirectory(), mod, ingestJobId);
}
/**
* Get relative path for module output folder.
*
* @throws NoCurrentCaseException if there is no open case.
* @return the relative path of the module output folder
*/
static String getRelModuleOutputPath() throws NoCurrentCaseException {
return Paths.get(Case.getCurrentCaseThrows().getModuleOutputDirectoryRelativePath(),
"RecentActivity").normalize().toString() ; //NON-NLS
static String getRelModuleOutputPath(Case autCase, String mod, long ingestJobId) {
return Paths.get(getAndMakeRAPath(autCase.getModuleOutputDirectoryRelativePath(), mod, ingestJobId))
.normalize()
.toString();
}
}

View File

@ -0,0 +1 @@
This contains jars provided in Netbeans 8 RCP that provide localization bundles. They do not appear to be included in Netbeans >= 9. See Jira 7434 for more information.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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