From 0dac3815b522dd5df50c27298afa7caf37a7ebc9 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Wed, 5 May 2021 13:39:28 -0400 Subject: [PATCH 1/6] modified updateguiforcaseopened to get db calls off of edt --- .../sleuthkit/autopsy/casemodule/Case.java | 71 ++++++++++++------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index ddf8cc22b9..2a255a13c9 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -29,6 +29,7 @@ import java.awt.event.ActionListener; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.io.File; +import java.lang.reflect.InvocationTargetException; import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; @@ -63,6 +64,7 @@ import javax.annotation.concurrent.ThreadSafe; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import org.apache.commons.lang3.StringUtils; +import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; @@ -1032,10 +1034,6 @@ public class Case { } newCurrentCase.doOpenCaseAction(progressIndicatorTitle, openCaseAction, CaseLockType.SHARED, true, null); currentCase = newCurrentCase; - logger.log(Level.INFO, "Opened {0} ({1}) in {2} as the current case", new Object[]{newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory()}); //NON-NLS - if (RuntimeProperties.runningWithGUI()) { - updateGUIForCaseOpened(newCurrentCase); - } eventPublisher.publishLocally(new AutopsyEvent(Events.CURRENT_CASE.toString(), null, currentCase)); } catch (CaseActionCancelledException ex) { logger.log(Level.INFO, String.format("Cancelled opening %s (%s) in %s as the current case", newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory())); //NON-NLS @@ -1213,9 +1211,7 @@ public class Case { /** * Update the GUI to to reflect the current case. */ - private static void updateGUIForCaseOpened(Case newCurrentCase) { - if (RuntimeProperties.runningWithGUI()) { - SwingUtilities.invokeLater(() -> { + private static void updateGUIForCaseOpened(Case newCurrentCase) { /* * If the case database was upgraded for a new schema and a * backup database was created, notify the user. @@ -1241,17 +1237,31 @@ public class Case { String path = entry.getValue(); boolean fileExists = (new File(path).isFile() || DriveUtils.driveExists(path)); if (!fileExists) { - int response = JOptionPane.showConfirmDialog( - mainFrame, - NbBundle.getMessage(Case.class, "Case.checkImgExist.confDlg.doesntExist.msg", path), - NbBundle.getMessage(Case.class, "Case.checkImgExist.confDlg.doesntExist.title"), - JOptionPane.YES_NO_OPTION); - if (response == JOptionPane.YES_OPTION) { - MissingImageDialog.makeDialog(obj_id, caseDb); - } else { - logger.log(Level.SEVERE, "User proceeding with missing image files"); //NON-NLS + try { + // Using invokeAndWait means that the dialog will + // open on the EDT but this thread will wait for an + // answer. Using invokeLater would cause this loop to + // end before all of the dialogs appeared. + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + int response = JOptionPane.showConfirmDialog( + mainFrame, + NbBundle.getMessage(Case.class, "Case.checkImgExist.confDlg.doesntExist.msg", path), + NbBundle.getMessage(Case.class, "Case.checkImgExist.confDlg.doesntExist.title"), + JOptionPane.YES_NO_OPTION); + if (response == JOptionPane.YES_OPTION) { + MissingImageDialog.makeDialog(obj_id, caseDb); + } else { + logger.log(Level.SEVERE, "User proceeding with missing image files"); //NON-NLS - } + } + } + + }); + } catch (InterruptedException | InvocationTargetException ex) { + logger.log(Level.SEVERE, "Failed to show missing image confirmation dialog", ex); //NON-NLS + } } } @@ -1269,14 +1279,16 @@ public class Case { CallableSystemAction.get(CommonAttributeSearchAction.class).setEnabled(true); CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false); CallableSystemAction.get(OpenDiscoveryAction.class).setEnabled(true); - - /* - * Add the case to the recent cases tracker that supplies a list - * of recent cases to the recent cases menu item and the - * open/create case dialog. - */ - RecentCases.getInstance().addRecentCase(newCurrentCase.getDisplayName(), newCurrentCase.getMetadata().getFilePath().toString()); - + + /* + * Add the case to the recent cases tracker that supplies a list + * of recent cases to the recent cases menu item and the + * open/create case dialog. + */ + RecentCases.getInstance().addRecentCase(newCurrentCase.getDisplayName(), newCurrentCase.getMetadata().getFilePath().toString()); + final boolean hasData = newCurrentCase.hasData(); + + SwingUtilities.invokeLater(() -> { /* * Open the top components (windows within the main application * window). @@ -1285,7 +1297,7 @@ public class Case { * opened via the DirectoryTreeTopComponent 'propertyChange()' * method on a DATA_SOURCE_ADDED event. */ - if (newCurrentCase.hasData()) { + if (hasData) { CoreComponentControl.openCoreWindows(); } @@ -1296,7 +1308,6 @@ public class Case { */ mainFrame.setTitle(newCurrentCase.getDisplayName() + " - " + getNameForTitle()); }); - } } /* @@ -2133,6 +2144,12 @@ public class Case { throw ex; } } + + logger.log(Level.INFO, "Opened {0} ({1}) in {2} as the current case", new Object[]{this.getDisplayName(), this.getName(), this.getCaseDirectory()}); //NON-NLS + if (RuntimeProperties.runningWithGUI()) { + updateGUIForCaseOpened(this); + } + return null; }); if (null != cancelButtonListener) { From 071c4bcff94ef67d92a4b84e8a84a30932233ad5 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Wed, 5 May 2021 13:50:10 -0400 Subject: [PATCH 2/6] Put call to updateGUIForCaseOpen back to its original location --- Core/src/org/sleuthkit/autopsy/casemodule/Case.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index 2a255a13c9..4ad8d9f8da 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -1034,6 +1034,10 @@ public class Case { } newCurrentCase.doOpenCaseAction(progressIndicatorTitle, openCaseAction, CaseLockType.SHARED, true, null); currentCase = newCurrentCase; + logger.log(Level.INFO, "Opened {0} ({1}) in {2} as the current case", new Object[]{newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory()}); //NON-NLS + if (RuntimeProperties.runningWithGUI()) { + updateGUIForCaseOpened(newCurrentCase); + } eventPublisher.publishLocally(new AutopsyEvent(Events.CURRENT_CASE.toString(), null, currentCase)); } catch (CaseActionCancelledException ex) { logger.log(Level.INFO, String.format("Cancelled opening %s (%s) in %s as the current case", newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory())); //NON-NLS @@ -2144,12 +2148,6 @@ public class Case { throw ex; } } - - logger.log(Level.INFO, "Opened {0} ({1}) in {2} as the current case", new Object[]{this.getDisplayName(), this.getName(), this.getCaseDirectory()}); //NON-NLS - if (RuntimeProperties.runningWithGUI()) { - updateGUIForCaseOpened(this); - } - return null; }); if (null != cancelButtonListener) { From a46bbb81a3c20358212870aad3be8f150ec3274c Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 6 May 2021 14:19:26 -0400 Subject: [PATCH 3/6] Fixed RA NPE --- .../recentactivity/ExtractRegistry.java | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index 5951ac504c..80e784aaa7 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -742,7 +742,7 @@ class ExtractRegistry extends Extract { } else { results.get(0).addAttributes(bbattributes); } - for (Map.Entry userMap : userNameMap.entrySet()) { + for (Map.Entry userMap : getUserNameMap().entrySet()) { String sid = ""; try{ sid = (String)userMap.getKey(); @@ -1116,17 +1116,6 @@ class ExtractRegistry extends Extract { accountMgr.newOsAccountInstance(osAccount, (DataSource)dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED); updateOsAccount(osAccount, userInfo, groupMap.get(userInfo.get(SID_KEY)), regAbstractFile); } - - // Get a mapping of user sids to user names and save globally so it can be used for other areas - // of the registry, ie: BAM key - try { - userNameMap = makeUserNameMap(dataSource); - } catch (TskCoreException ex) { - logger.log(Level.WARNING, "Unable to create OS Account user name map", ex); - // This is not the end of the world we will just continue without - // user names - userNameMap = new HashMap<>(); - } return true; } catch (FileNotFoundException ex) { logger.log(Level.WARNING, "Error finding the registry file.", ex); //NON-NLS @@ -1261,7 +1250,7 @@ class ExtractRegistry extends Extract { // We can add the S- back to the string that we split on since S- is a valid beginning of a User SID String fileNameSid[] = tokens[4].split("\\s+\\(S-"); String userSid = "S-" + fileNameSid[1].substring(0, fileNameSid[1].length() - 1); - String userName = userNameMap.get(userSid); + String userName = getUserNameMap().get(userSid); if (userName == null) { userName = userSid; } @@ -1738,6 +1727,23 @@ class ExtractRegistry extends Extract { return map; } + + private Map getUserNameMap() { + if(userNameMap == null) { + // Get a mapping of user sids to user names and save globally so it can be used for other areas + // of the registry, ie: BAM key + try { + userNameMap = makeUserNameMap(dataSource); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Unable to create OS Account user name map", ex); + // This is not the end of the world we will just continue without + // user names + userNameMap = new HashMap<>(); + } + } + + return userNameMap; + } /** * Gets the attribute for the given type from the given artifact. From 6b39909199f55cf77935bc6d80811e181a216e28 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 6 May 2021 14:22:13 -0400 Subject: [PATCH 4/6] Added method header --- .../sleuthkit/autopsy/recentactivity/ExtractRegistry.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index 80e784aaa7..b0d7fe08c3 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -1728,6 +1728,11 @@ class ExtractRegistry extends Extract { return map; } + /** + * Returns a mapping of user sids to user names. + * + * @return username man or empty list if none where found. + */ private Map getUserNameMap() { if(userNameMap == null) { // Get a mapping of user sids to user names and save globally so it can be used for other areas From 4b1527bf20c41695a58a43126b4d107db8af6e4b Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Mon, 10 May 2021 12:48:24 -0400 Subject: [PATCH 5/6] Add Registry Key Modification Time To Registry Content Viewer Added registry key modification time to registry content viewer for a registry key when it is selected. Date/time is in GMT + 0 (UTC) --- .../autopsy/rejview/Bundle.properties-MERGED | 1 + .../autopsy/rejview/RejTreeKeyView.java | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/rejview/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/rejview/Bundle.properties-MERGED index c633b9838e..84a54f1640 100644 --- a/Core/src/org/sleuthkit/autopsy/rejview/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/rejview/Bundle.properties-MERGED @@ -15,6 +15,7 @@ RejTreeKeyView.columns.type=Type RejTreeKeyView.columns.value=Value RejTreeKeyView.failedToParse.keyName=FAILED TO PARSE KEY NAME RejTreeKeyView.metadataBorder.title=Metadata +RejTreeKeyView.template.dateTime=Modification Time: RejTreeKeyView.template.name=Name: RejTreeKeyView.template.numberOfSubkeys=Number of subkeys: RejTreeKeyView.template.numberOfValues=Number of values: diff --git a/Core/src/org/sleuthkit/autopsy/rejview/RejTreeKeyView.java b/Core/src/org/sleuthkit/autopsy/rejview/RejTreeKeyView.java index a74d4d26b4..6d2d55ba1a 100644 --- a/Core/src/org/sleuthkit/autopsy/rejview/RejTreeKeyView.java +++ b/Core/src/org/sleuthkit/autopsy/rejview/RejTreeKeyView.java @@ -28,6 +28,8 @@ import java.awt.Dimension; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import java.io.UnsupportedEncodingException; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.Iterator; import java.util.logging.Level; import javax.swing.BorderFactory; @@ -54,7 +56,8 @@ public final class RejTreeKeyView extends RejTreeNodeView { "RejTreeKeyView.valuesBorder.title=Values", "RejTreeKeyView.template.name=Name:", "RejTreeKeyView.template.numberOfSubkeys=Number of subkeys:", - "RejTreeKeyView.template.numberOfValues=Number of values:"}) + "RejTreeKeyView.template.numberOfValues=Number of values:", + "RejTreeKeyView.template.dateTime=Modification Time:"}) public RejTreeKeyView(RejTreeKeyNode node) { super(new BorderLayout()); @@ -62,6 +65,7 @@ public final class RejTreeKeyView extends RejTreeNodeView { * param 1 Name * param 2 Number of subkeys * param 3 Number of values + * param 4 Date/time */ String metadataTemplate = "" + Bundle.RejTreeKeyView_template_name() @@ -69,10 +73,13 @@ public final class RejTreeKeyView extends RejTreeNodeView { + Bundle.RejTreeKeyView_template_numberOfSubkeys() + " %2$d
" + Bundle.RejTreeKeyView_template_numberOfValues() - + " %3$d
"; + + " %3$d
" + + Bundle.RejTreeKeyView_template_dateTime() + + " %4$s
"; String keyName; int numSubkeys; int numValues; + String dateTime; try { keyName = node.getKey().getName(); @@ -95,7 +102,12 @@ public final class RejTreeKeyView extends RejTreeNodeView { numValues = -1; } - JLabel metadataLabel = new JLabel(String.format(metadataTemplate, keyName, numSubkeys, numValues), JLabel.LEFT); + Date date = new java.util.Date(node.getKey().getTimestamp().getTimeInMillis()); + SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); + sdf.setTimeZone(java.util.TimeZone.getTimeZone("GMT+0")); + dateTime = sdf.format(date); + + JLabel metadataLabel = new JLabel(String.format(metadataTemplate, keyName, numSubkeys, numValues, dateTime), JLabel.LEFT); metadataLabel.setBorder(BorderFactory.createTitledBorder(Bundle.RejTreeKeyView_metadataBorder_title())); metadataLabel.setVerticalAlignment(SwingConstants.TOP); From 60fe3d15c26f82abbf34fe24387c12802534ae8f Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Tue, 11 May 2021 15:41:43 -0400 Subject: [PATCH 6/6] Removed unused import --- Core/src/org/sleuthkit/autopsy/casemodule/Case.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index 4ad8d9f8da..36c8c230db 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -64,7 +64,6 @@ import javax.annotation.concurrent.ThreadSafe; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import org.apache.commons.lang3.StringUtils; -import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages;