From 386e9e8cef77c1d86b19ab2fb3820f9c76371774 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Wed, 3 Mar 2021 10:53:50 -0500 Subject: [PATCH 1/4] Inital commit of changes --- .../osaccount/Bundle.properties-MERGED | 1 + .../osaccount/OsAccountDataPanel.java | 127 ++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/Bundle.properties-MERGED index c313958fd5..b3b1f7816a 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/Bundle.properties-MERGED @@ -11,6 +11,7 @@ OsAccountDataPanel_basic_yes=Yes OsAccountDataPanel_realm_address=Address OsAccountDataPanel_realm_confidence=Confidence OsAccountDataPanel_realm_name=Name +OsAccountDataPanel_realm_scope=Scope OsAccountDataPanel_realm_title=Realm Properties OsAccountDataPanel_realm_unknown=Unknown OsAccountViewer_title=Os Account diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java index a0e2ee7edf..0f564ea896 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java @@ -25,15 +25,26 @@ import java.awt.Insets; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; import static java.util.Locale.US; +import java.util.Map; import java.util.Optional; +import java.util.concurrent.ExecutionException; import javax.swing.Box; import javax.swing.JLabel; import javax.swing.JPanel; +import javax.swing.SwingWorker; +import org.openide.util.Exceptions; import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.contentviewers.osaccount.SectionData.RowData; +import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.Host; +import org.sleuthkit.datamodel.HostManager; import org.sleuthkit.datamodel.OsAccount; +import org.sleuthkit.datamodel.OsAccountAttribute; +import org.sleuthkit.datamodel.OsAccountManager; import org.sleuthkit.datamodel.OsAccountRealm; /** @@ -195,6 +206,15 @@ public class OsAccountDataPanel extends JPanel { return data; } + + private SectionData buildHostData(Host host, List attributeList) { + SectionData data = new SectionData(host.getName()); + for(OsAccountAttribute attribute: attributeList) { + data.addData(attribute.getAttributeType().getDisplayName(), attribute.getDisplayString()); + } + + return data; + } /** * Add a section title to the panel with the given title and location. @@ -316,5 +336,112 @@ public class OsAccountDataPanel extends JPanel { } } } + + private class HostFetcher extends SwingWorker { + + private final OsAccount account; + + HostFetcher(OsAccount account) { + this.account = account; + } + + @Override + protected WorkerResults doInBackground() throws Exception { + Map> hostMap = new HashMap<>(); + Map instanceMap = new HashMap<>(); + OsAccountManager osAccountManager = Case.getCurrentCase().getSleuthkitCase().getOsAccountManager(); + List hosts = osAccountManager.getHosts(account); + List attributeList = account.getOsAccountAttributes(); + + if(attributeList != null) { + if(hosts != null) { + // Organize the attributes by hostId + Map> idMap = new HashMap<>(); + for(OsAccountAttribute attribute: attributeList) { + List atList = null; + Optional optionalId = attribute.getHostId(); + Long key = null; + if(optionalId.isPresent()) { + key = optionalId.get(); + } + + atList = idMap.get(key); + + if(atList == null) { + atList = new ArrayList<>(); + idMap.put(key, atList); + } + + atList.add(attribute); + } + + HostManager hostManager = Case.getCurrentCase().getSleuthkitCase().getHostManager(); + // Add attribute lists to the hostMap + for(Host host: hosts) { + List atList = idMap.get(host.getId()); + if(atList != null) { + hostMap.put(host, atList); + } + + } + List atList = idMap.get(null); + if(atList != null) { + hostMap.put(null, atList); + } + } else { + hostMap.put(null, attributeList); + } + } + + return new WorkerResults(hostMap, instanceMap); + } + + @Override + protected void done() { + WorkerResults results = null; + + try { + results = get(); + } catch (InterruptedException ex) { + Exceptions.printStackTrace(ex); + } catch (ExecutionException ex) { + Exceptions.printStackTrace(ex); + } + + if(results != null) { + List data = new ArrayList<>(); + data.add(buildBasicProperties(account)); + Map> hostDataMap = results.getAttributeMap(); + if(hostDataMap != null && !hostDataMap.isEmpty()) { + hostDataMap.forEach((K,V)-> data.add(buildHostData(K,V))); + } + + OsAccountRealm realm = account.getRealm(); + if (realm != null) { + data.add(buildRealmProperties(realm)); + } + + addDataComponents(data); + } + } + } + + private final class WorkerResults { + private final Map> attributeMap; + private final Map instanceMap; + + WorkerResults(Map> attributeMap, Map instanceMap) { + this.attributeMap = attributeMap; + this.instanceMap = instanceMap; + } + + Map> getAttributeMap() { + return attributeMap; + } + + Map getDataSourceMap() { + return instanceMap; + } + } } From c0b9d5f49cc3a6fb68a52dcabb3fc9a65bba824e Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Fri, 5 Mar 2021 15:18:26 -0500 Subject: [PATCH 2/4] Finished OsAccountContentViewer changes --- .../osaccount/OsAccountDataPanel.java | 172 ++++++++++++------ .../recentactivity/ExtractRegistry.java | 3 + 2 files changed, 118 insertions(+), 57 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java index 0f564ea896..2ea3989b44 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.contentviewers.osaccount; +import java.awt.BorderLayout; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; @@ -31,19 +32,20 @@ import static java.util.Locale.US; import java.util.Map; import java.util.Optional; import java.util.concurrent.ExecutionException; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.Box; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SwingWorker; -import org.openide.util.Exceptions; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.contentviewers.osaccount.SectionData.RowData; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.Host; -import org.sleuthkit.datamodel.HostManager; import org.sleuthkit.datamodel.OsAccount; import org.sleuthkit.datamodel.OsAccountAttribute; +import org.sleuthkit.datamodel.OsAccountInstance; import org.sleuthkit.datamodel.OsAccountManager; import org.sleuthkit.datamodel.OsAccountRealm; @@ -53,12 +55,15 @@ import org.sleuthkit.datamodel.OsAccountRealm; public class OsAccountDataPanel extends JPanel { private static final long serialVersionUID = 1L; + final private static Logger logger = Logger.getLogger(OsAccountDataPanel.class.getName()); private static final int KEY_COLUMN = 0; private static final int VALUE_COLUMN = 1; - + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MMM dd yyyy", US); + private PanelDataFetcher dataFetcher = null; + // Panel constructor. OsAccountDataPanel() { initialize(); @@ -79,19 +84,19 @@ public class OsAccountDataPanel extends JPanel { */ void setOsAccount(OsAccount account) { removeAll(); + revalidate(); if (account != null) { - List data = new ArrayList<>(); - data.add(buildBasicProperties(account)); + setLayout(new BorderLayout()); + add(new JLabel("Loading OsAccount Data..."), BorderLayout.NORTH); - OsAccountRealm realm = account.getRealm(); - if (realm != null) { - data.add(buildRealmProperties(realm)); + if (dataFetcher != null && !dataFetcher.isDone()) { + dataFetcher.cancel(true); } - addDataComponents(data); + dataFetcher = new PanelDataFetcher(account); + dataFetcher.execute(); } - revalidate(); } /** @@ -133,8 +138,7 @@ public class OsAccountDataPanel extends JPanel { "OsAccountDataPanel_basic_address=Address", "OsAccountDataPanel_basic_admin=Administrator", "OsAccountDataPanel_basic_type=Type", - "OsAccountDataPanel_basic_creationDate=Creation Date", - }) + "OsAccountDataPanel_basic_creationDate=Creation Date",}) /** * Returns the data for the Basic Properties section of the panel. @@ -160,12 +164,11 @@ public class OsAccountDataPanel extends JPanel { data.addData(Bundle.OsAccountDataPanel_basic_admin(), getIsAdminValue(account.isAdmin())); data.addData(Bundle.OsAccountDataPanel_basic_type(), account.getOsAccountType().getName()); - + Optional crTime = account.getCreationTime(); - if(crTime.isPresent()) { + if (crTime.isPresent()) { data.addData(Bundle.OsAccountDataPanel_basic_creationDate(), DATE_FORMAT.format(new Date(crTime.get() * 1000))); - } - else { + } else { data.addData(Bundle.OsAccountDataPanel_basic_creationDate(), ""); } @@ -197,22 +200,22 @@ public class OsAccountDataPanel extends JPanel { optional = realm.getRealmAddr(); data.addData(Bundle.OsAccountDataPanel_realm_address(), optional.isPresent() ? optional.get() : ""); - + data.addData(Bundle.OsAccountDataPanel_realm_scope(), - realm.getScope().getName()); - + realm.getScope().getName()); + data.addData(Bundle.OsAccountDataPanel_realm_confidence(), realm.getScopeConfidence().getName()); return data; } - + private SectionData buildHostData(Host host, List attributeList) { SectionData data = new SectionData(host.getName()); - for(OsAccountAttribute attribute: attributeList) { + for (OsAccountAttribute attribute : attributeList) { data.addData(attribute.getAttributeType().getDisplayName(), attribute.getDisplayString()); } - + return data; } @@ -336,15 +339,23 @@ public class OsAccountDataPanel extends JPanel { } } } - - private class HostFetcher extends SwingWorker { + + /** + * A SwingWorker to gather the data for the content panel. + */ + private class PanelDataFetcher extends SwingWorker { private final OsAccount account; - - HostFetcher(OsAccount account) { + + /** + * Construct a new worker for the given account. + * + * @param account + */ + PanelDataFetcher(OsAccount account) { this.account = account; } - + @Override protected WorkerResults doInBackground() throws Exception { Map> hostMap = new HashMap<>(); @@ -352,68 +363,79 @@ public class OsAccountDataPanel extends JPanel { OsAccountManager osAccountManager = Case.getCurrentCase().getSleuthkitCase().getOsAccountManager(); List hosts = osAccountManager.getHosts(account); List attributeList = account.getOsAccountAttributes(); - - if(attributeList != null) { - if(hosts != null) { + + if (attributeList != null) { + if (hosts != null) { // Organize the attributes by hostId Map> idMap = new HashMap<>(); - for(OsAccountAttribute attribute: attributeList) { + for (OsAccountAttribute attribute : attributeList) { List atList = null; Optional optionalId = attribute.getHostId(); Long key = null; - if(optionalId.isPresent()) { - key = optionalId.get(); + if (optionalId.isPresent()) { + key = optionalId.get(); } atList = idMap.get(key); - if(atList == null) { + if (atList == null) { atList = new ArrayList<>(); idMap.put(key, atList); } atList.add(attribute); } - - HostManager hostManager = Case.getCurrentCase().getSleuthkitCase().getHostManager(); + // Add attribute lists to the hostMap - for(Host host: hosts) { + for (Host host : hosts) { List atList = idMap.get(host.getId()); - if(atList != null) { + if (atList != null) { hostMap.put(host, atList); } - + } List atList = idMap.get(null); - if(atList != null) { + if (atList != null) { hostMap.put(null, atList); } + + // Store both the host and the dataSource so that we get + // all of the calls to the db done in the thread. + for (OsAccountInstance instance : account.getOsAccountInstances()) { + instanceMap.put(instance.getDataSource().getHost(), instance.getDataSource()); + } + } else { hostMap.put(null, attributeList); } } - + return new WorkerResults(hostMap, instanceMap); } - + @Override protected void done() { WorkerResults results = null; - + try { - results = get(); - } catch (InterruptedException ex) { - Exceptions.printStackTrace(ex); - } catch (ExecutionException ex) { - Exceptions.printStackTrace(ex); + if (this.isCancelled()) { + return; + } else { + results = get(); + } + } catch (ExecutionException | InterruptedException ex) { + logger.log(Level.SEVERE, String.format("Failed to retrieve data for OsAccount (%d)", account.getId()), ex); } - - if(results != null) { + + if (results != null) { + removeAll(); + setLayout(new GridBagLayout()); + List data = new ArrayList<>(); data.add(buildBasicProperties(account)); Map> hostDataMap = results.getAttributeMap(); - if(hostDataMap != null && !hostDataMap.isEmpty()) { - hostDataMap.forEach((K,V)-> data.add(buildHostData(K,V))); + if (hostDataMap != null && !hostDataMap.isEmpty()) { + hostDataMap.forEach((K, V) -> data.add(buildHostData(K, V))); } OsAccountRealm realm = account.getRealm(); @@ -421,24 +443,60 @@ public class OsAccountDataPanel extends JPanel { data.add(buildRealmProperties(realm)); } + Map instanceMap = results.getDataSourceMap(); + if (!instanceMap.isEmpty()) { + SectionData instanceSection = new SectionData("Instances"); + instanceMap.forEach((K, V) -> instanceSection.addData(K.getName(), V.getName())); + + data.add(instanceSection); + } + addDataComponents(data); + + revalidate(); + repaint(); } - } + } } - + + /** + * Helper class for PanelDataFetcher that wraps the returned data needed for + * the panel. + */ private final class WorkerResults { + private final Map> attributeMap; private final Map instanceMap; - + + /** + * Construct a new WorkerResult object. + * + * @param attributeMap Maps the OsAccountAttributes to the host they + * belong with. + * @param instanceMap A map of data to display OsAccount instance + * information. + */ WorkerResults(Map> attributeMap, Map instanceMap) { this.attributeMap = attributeMap; this.instanceMap = instanceMap; } - + + /** + * Returns a map of OsAccountAttributes that belong to a specific Host. + * There maybe a null key in the map which represents properties that + * are not host specific. + * + * @return OsAccountAttribute map. + */ Map> getAttributeMap() { return attributeMap; } - + + /** + * A map of the instance data for the OsAccount. + * + * @return + */ Map getDataSourceMap() { return instanceMap; } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index 1b1661c82e..f464ed0b63 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -102,6 +102,7 @@ import org.sleuthkit.datamodel.Host; import org.sleuthkit.datamodel.HostManager; import org.sleuthkit.datamodel.OsAccount; import org.sleuthkit.datamodel.OsAccountAttribute; +import org.sleuthkit.datamodel.OsAccountInstance; import org.sleuthkit.datamodel.OsAccountManager; import org.sleuthkit.datamodel.OsAccountRealm; import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException; @@ -1166,6 +1167,7 @@ class ExtractRegistry extends Extract { //add remaining userinfos as accounts; for (Map userInfo : userInfoMap.values()) { OsAccount osAccount = accountMgr.createWindowsAccount(userInfo.get(SID_KEY), null, null, host, OsAccountRealm.RealmScope.UNKNOWN); + accountMgr.createOsAccountInstance(osAccount, (DataSource)dataSource, OsAccountInstance.OsAccountInstanceType.PERFORMED_ACTION_ON); updateOsAccount(osAccount, userInfo, groupMap.get(userInfo.get(SID_KEY)), regAbstractFile); } @@ -2214,6 +2216,7 @@ class ExtractRegistry extends Extract { OsAccount osAccount; if (!optional.isPresent()) { osAccount = accountMgr.createWindowsAccount(sid, userName != null && userName.isEmpty() ? null : userName, null, host, OsAccountRealm.RealmScope.UNKNOWN); + accountMgr.createOsAccountInstance(osAccount, (DataSource)dataSource, OsAccountInstance.OsAccountInstanceType.PERFORMED_ACTION_ON); } else { osAccount = optional.get(); if (userName != null && !userName.isEmpty()) { From 5e47760892ab1307ce5f9df6740d9cc2f25d4e06 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Tue, 9 Mar 2021 15:35:47 -0500 Subject: [PATCH 3/4] Merged change from sleuthkit in --- .../org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index 4a735e890d..13025e3e56 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -1167,7 +1167,7 @@ class ExtractRegistry extends Extract { //add remaining userinfos as accounts; for (Map userInfo : userInfoMap.values()) { OsAccount osAccount = accountMgr.createWindowsAccount(userInfo.get(SID_KEY), null, null, host, OsAccountRealm.RealmScope.UNKNOWN); - accountMgr.createOsAccountInstance(osAccount, (DataSource)dataSource, OsAccountInstance.OsAccountInstanceType.PERFORMED_ACTION_ON); + accountMgr.createOsAccountInstance(osAccount, (DataSource)dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED); updateOsAccount(osAccount, userInfo, groupMap.get(userInfo.get(SID_KEY)), regAbstractFile); } @@ -2216,7 +2216,7 @@ class ExtractRegistry extends Extract { OsAccount osAccount; if (!optional.isPresent()) { osAccount = accountMgr.createWindowsAccount(sid, userName != null && userName.isEmpty() ? null : userName, null, host, OsAccountRealm.RealmScope.UNKNOWN); - accountMgr.createOsAccountInstance(osAccount, (DataSource)dataSource, OsAccountInstance.OsAccountInstanceType.PERFORMED_ACTION_ON); + accountMgr.createOsAccountInstance(osAccount, (DataSource)dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED); } else { osAccount = optional.get(); if (userName != null && !userName.isEmpty()) { From 4dfffc96ceb57356e40652bb26663cf9104ad3f1 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Wed, 10 Mar 2021 10:39:46 -0500 Subject: [PATCH 4/4] Updated with review changes --- .../org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index 13025e3e56..8d215ccf6e 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -2372,16 +2372,14 @@ class ExtractRegistry extends Extract { } } - String settingString = getSettingsFromMap(ACCOUNT_SETTINGS_FLAGS, userInfo); + String settingString = getSettingsFromMap(PASSWORD_SETTINGS_FLAGS, userInfo); if (!settingString.isEmpty()) { - settingString = settingString.substring(0, settingString.length() - 2); attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_PASSWORD_SETTINGS, settingString, osAccount, host, regFile)); } settingString = getSettingsFromMap(ACCOUNT_SETTINGS_FLAGS, userInfo); if (!settingString.isEmpty()) { - settingString = settingString.substring(0, settingString.length() - 2); attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_SETTINGS, settingString, osAccount, host, regFile)); }