diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java index 9197b2fb42..4ab37d01b5 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java @@ -79,7 +79,7 @@ class AddImageWizardSelectHostVisual extends javax.swing.JPanel { @Override public int hashCode() { int hash = 7; - hash = 41 * hash + Objects.hashCode(this.host == null ? 0 : this.host.getId()); + hash = 41 * hash + Objects.hashCode(this.host == null ? 0 : this.host.getHostId()); return hash; } @@ -96,8 +96,8 @@ class AddImageWizardSelectHostVisual extends javax.swing.JPanel { } final HostListItem other = (HostListItem) obj; if (!Objects.equals( - this.host == null ? 0 : this.host.getId(), - other.host == null ? 0 : other.host.getId())) { + this.host == null ? 0 : this.host.getHostId(), + other.host == null ? 0 : other.host.getHostId())) { return false; } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index e5983f24d3..c0497c083c 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -528,8 +528,8 @@ public class Case { @Subscribe public void publishOsAccountDeletedEvent(OsAccountsDeleteEvent event) { - for(OsAccount account: event.getOsAcounts()) { - eventPublisher.publish(new OsAccountRemovedEvent(account)); + for(Long accountId: event.getOsAcountObjectIds()) { + eventPublisher.publish(new OsAccountRemovedEvent(accountId)); } } @@ -1802,8 +1802,8 @@ public class Case { eventPublisher.publish(new OsAccountChangedEvent(account)); } - public void notifyOsAccountRemoved(OsAccount account) { - eventPublisher.publish(new OsAccountRemovedEvent(account)); + public void notifyOsAccountRemoved(Long osAccountObjectId) { + eventPublisher.publish(new OsAccountRemovedEvent(osAccountObjectId)); } /** diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/SolrNotConfiguredDialog.java b/Core/src/org/sleuthkit/autopsy/casemodule/SolrNotConfiguredDialog.java index 3adf647596..5fecaa9826 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/SolrNotConfiguredDialog.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/SolrNotConfiguredDialog.java @@ -37,11 +37,8 @@ class SolrNotConfiguredDialog extends javax.swing.JDialog { SolrNotConfiguredDialog() { super((JFrame) WindowManager.getDefault().getMainWindow(), true); // Center the startup window. - Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize(); - int width = getSize().width; - int height = getSize().height; - setLocation((screenDimension.width - width) / 2, (screenDimension.height - height) / 2); initComponents(); + setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); setIconImage(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/warning16.png", false)); } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/events/HostsEvent.java b/Core/src/org/sleuthkit/autopsy/casemodule/events/HostsEvent.java index 1ba225f4a2..f37a159125 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/events/HostsEvent.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/events/HostsEvent.java @@ -42,7 +42,7 @@ public class HostsEvent extends TskDataModelChangeEvent { private static List getIds(List hosts) { return getSafeList(hosts).stream() .filter(h -> h != null) - .map(h -> h.getId()).collect(Collectors.toList()); + .map(h -> h.getHostId()).collect(Collectors.toList()); } /** diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/events/OsAccountEvent.java b/Core/src/org/sleuthkit/autopsy/casemodule/events/OsAccountEvent.java index 22b0622ba8..d34da7822d 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/events/OsAccountEvent.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/events/OsAccountEvent.java @@ -56,7 +56,7 @@ class OsAccountEvent extends TskDataModelChangeEvent { @Override protected List getDataModelObjects(SleuthkitCase caseDb, List ids) throws TskCoreException { Long id = ids.get(0); - OsAccount account = caseDb.getOsAccountManager().getOsAccount(id); + OsAccount account = caseDb.getOsAccountManager().getOsAccountByObjectId(id); List accounts = new ArrayList<>(); accounts.add(account); return accounts; diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/events/OsAccountRemovedEvent.java b/Core/src/org/sleuthkit/autopsy/casemodule/events/OsAccountRemovedEvent.java index 2dfcc1db79..4bf03c90d9 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/events/OsAccountRemovedEvent.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/events/OsAccountRemovedEvent.java @@ -19,16 +19,19 @@ package org.sleuthkit.autopsy.casemodule.events; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.datamodel.OsAccount; +import org.sleuthkit.autopsy.events.AutopsyEvent; /** * Event published when an OsAccount is deleted. + * + * oldValue will contain the objectId of the account that was removed. newValue + * will be null. */ -public final class OsAccountRemovedEvent extends OsAccountEvent { +public final class OsAccountRemovedEvent extends AutopsyEvent { private static final long serialVersionUID = 1L; - public OsAccountRemovedEvent(OsAccount account) { - super(Case.Events.OS_ACCOUNT_REMOVED.toString(), account); + public OsAccountRemovedEvent(Long osAccountObjectId) { + super(Case.Events.OS_ACCOUNT_REMOVED.toString(), osAccountObjectId, null); } } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/events/PersonsEvent.java b/Core/src/org/sleuthkit/autopsy/casemodule/events/PersonsEvent.java index ef74585b7f..e3f584d58a 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/events/PersonsEvent.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/events/PersonsEvent.java @@ -42,7 +42,7 @@ public class PersonsEvent extends TskDataModelChangeEvent { private static List getIds(List persons) { return getSafeList(persons).stream() .filter(h -> h != null) - .map(h -> h.getId()).collect(Collectors.toList()); + .map(h -> h.getPersonId()).collect(Collectors.toList()); } /** diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java index a1077e3e82..79b22d81cb 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountDataPanel.java @@ -82,6 +82,24 @@ public class OsAccountDataPanel extends JPanel { * @param account OsAccount to display, if null is passed the panel will * appear blank. */ +// void setOsAccount(OsAccount account) { + void setOsAccountId(Long osAccountId) { + removeAll(); + revalidate(); + + if (osAccountId != null) { + setLayout(new BorderLayout()); + add(new JLabel("Loading OsAccount Data..."), BorderLayout.NORTH); + + if (dataFetcher != null && !dataFetcher.isDone()) { + dataFetcher.cancel(true); + } + + dataFetcher = new PanelDataFetcher(osAccountId); + dataFetcher.execute(); + } + } + void setOsAccount(OsAccount account) { removeAll(); revalidate(); @@ -319,15 +337,22 @@ public class OsAccountDataPanel extends JPanel { */ private class PanelDataFetcher extends SwingWorker { - private final OsAccount account; + private final Long accountId; + private OsAccount account; /** * Construct a new worker for the given account. * * @param account */ + PanelDataFetcher(Long accountId) { + this.accountId = accountId; + this.account = null; + } + PanelDataFetcher(OsAccount account) { this.account = account; + this.accountId = null; } @Override @@ -335,6 +360,11 @@ public class OsAccountDataPanel extends JPanel { Map> hostMap = new HashMap<>(); Map instanceMap = new HashMap<>(); OsAccountManager osAccountManager = Case.getCurrentCase().getSleuthkitCase().getOsAccountManager(); + + if(account == null) { + account = osAccountManager.getOsAccountByObjectId(accountId); + } + List hosts = osAccountManager.getHosts(account); List attributeList = account.getOsAccountAttributes(); @@ -362,7 +392,7 @@ public class OsAccountDataPanel extends JPanel { // Add attribute lists to the hostMap for (Host host : hosts) { - List atList = idMap.get(host.getId()); + List atList = idMap.get(host.getHostId()); if (atList != null) { hostMap.put(host, atList); } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountViewer.java index a56e4de8c3..dd43d1f531 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/osaccount/OsAccountViewer.java @@ -53,26 +53,29 @@ public class OsAccountViewer extends javax.swing.JPanel implements DataContentVi @Override public void setNode(Node node) { - OsAccount osAccount = null; + Long osAccountId = null; try { - osAccount = node.getLookup().lookup(OsAccount.class); - if (osAccount == null) { - Optional optional; - AbstractFile file = node.getLookup().lookup(AbstractFile.class); - if (file != null) { - optional = file.getOsAccount(); - if (optional.isPresent()) { - osAccount = optional.get(); - } + OsAccount osAccount = node.getLookup().lookup(OsAccount.class); + if (osAccount != null) { + dataPanel.setOsAccount(osAccount); + return; + } + + Optional optional; + AbstractFile file = node.getLookup().lookup(AbstractFile.class); + if (file != null) { + optional = file.getOsAccountObjectId(); + if (optional.isPresent()) { + osAccountId = optional.get(); } } - if (osAccount == null) { + if (osAccountId == null) { DataArtifact dataArtifact = node.getLookup().lookup(DataArtifact.class); if (dataArtifact != null) { - Optional optional = dataArtifact.getOsAccount(); + optional = dataArtifact.getOsAccountObjectId(); if (optional.isPresent()) { - osAccount = optional.get(); + osAccountId = optional.get(); } } @@ -81,8 +84,8 @@ public class OsAccountViewer extends javax.swing.JPanel implements DataContentVi logger.log(Level.SEVERE, String.format("Failed to get OsAccount for node %s", node.getDisplayName()), ex); } - if (osAccount != null) { - dataPanel.setOsAccount(osAccount); + if (osAccountId != null) { + dataPanel.setOsAccountId(osAccountId); } } @@ -125,8 +128,8 @@ public class OsAccountViewer extends javax.swing.JPanel implements DataContentVi try { return osAccount != null - || (file != null && file.getOsAccount().isPresent()) - || (dataArtifact != null && dataArtifact.getOsAccount().isPresent()); + || (file != null && file.getOsAccountObjectId().isPresent()) + || (dataArtifact != null && dataArtifact.getOsAccountObjectId().isPresent()); } catch (TskCoreException ex) { logger.log(Level.SEVERE, String.format("Failed to determine if node %s is Supported for OsAccountViewer", node.getDisplayName()), ex); return false; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/HostDataSources.java b/Core/src/org/sleuthkit/autopsy/datamodel/HostDataSources.java index 37dadc840e..9451e401da 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/HostDataSources.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/HostDataSources.java @@ -51,7 +51,7 @@ public class HostDataSources implements AutopsyVisitableItem, Comparable h != null && h.getId() == hostId) + .filter(h -> h != null && h.getHostId() == hostId) .findFirst() .ifPresent((newHost) -> { setName(newHost.getName()); @@ -242,7 +242,7 @@ public class HostNode extends DisplayableItemNode { super(children, host == null ? Lookups.fixed(displayName) : Lookups.fixed(host, displayName)); - hostId = host == null ? null : host.getId(); + hostId = host == null ? null : host.getHostId(); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.HOSTS_CHANGED), WeakListeners.propertyChange(hostChangePcl, this)); super.setName(displayName); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/OsAccounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/OsAccounts.java index 8465b76947..556b247164 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/OsAccounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/OsAccounts.java @@ -144,10 +144,10 @@ public final class OsAccounts implements AutopsyVisitableItem { if(skCase != null) { try { if (filteringDSObjId == 0) { - list.addAll(skCase.getOsAccountManager().getAccounts()); + list.addAll(skCase.getOsAccountManager().getOsAccounts()); } else { Host host = skCase.getHostManager().getHost(skCase.getDataSource(filteringDSObjId)); - list.addAll(skCase.getOsAccountManager().getAccounts(host)); + list.addAll(skCase.getOsAccountManager().getOsAccounts(host)); } } catch (TskCoreException | TskDataException ex) { logger.log(Level.SEVERE, "Unable to retrieve list of OsAccounts for case", ex); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/PersonGrouping.java b/Core/src/org/sleuthkit/autopsy/datamodel/PersonGrouping.java index d606d288f1..1e65a06271 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/PersonGrouping.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/PersonGrouping.java @@ -52,7 +52,7 @@ public class PersonGrouping implements AutopsyVisitableItem, Comparable p != null && p.getId() == personId) + .filter(p -> p != null && p.getPersonId() == personId) .findFirst() .ifPresent((newPerson) -> { setName(newPerson.getName()); @@ -191,7 +191,7 @@ public class PersonGroupingNode extends DisplayableItemNode { super.setDisplayName(displayName); this.setIconBaseWithExtension(ICON_PATH); this.person = person; - this.personId = person == null ? null : person.getId(); + this.personId = person == null ? null : person.getPersonId(); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.PERSONS_CHANGED), WeakListeners.propertyChange(personChangePcl, this)); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java index 6d27cd53a1..7d4d521b51 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java @@ -89,7 +89,7 @@ public class ManageHostsDialog extends javax.swing.JDialog { @Override public int hashCode() { int hash = 5; - hash = 89 * hash + Objects.hashCode(this.host == null ? 0 : this.host.getId()); + hash = 89 * hash + Objects.hashCode(this.host == null ? 0 : this.host.getHostId()); return hash; } @@ -109,7 +109,7 @@ public class ManageHostsDialog extends javax.swing.JDialog { return this.host == null && other.getHost() == null; } - return this.host.getId() == other.getHost().getId(); + return this.host.getHostId() == other.getHost().getHostId(); } } @@ -167,7 +167,7 @@ public class ManageHostsDialog extends javax.swing.JDialog { Long selectedId = null; try { Host newHost = Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().createHost(newHostName); - selectedId = newHost == null ? null : newHost.getId(); + selectedId = newHost == null ? null : newHost.getHostId(); } catch (NoCurrentCaseException | TskCoreException e) { logger.log(Level.WARNING, String.format("Unable to add new host '%s' at this time.", newHostName), e); } @@ -215,7 +215,7 @@ public class ManageHostsDialog extends javax.swing.JDialog { continue; } - if (host.getId() == selectedId) { + if (host.getHostId() == selectedId) { hostList.setSelectedIndex(i); return; } @@ -238,11 +238,11 @@ public class ManageHostsDialog extends javax.swing.JDialog { try { Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().updateHost(selectedHost); } catch (NoCurrentCaseException | TskCoreException e) { - logger.log(Level.WARNING, String.format("Unable to update host '%s' with id: %d at this time.", selectedHost.getName(), selectedHost.getId()), e); + logger.log(Level.WARNING, String.format("Unable to update host '%s' with id: %d at this time.", selectedHost.getName(), selectedHost.getHostId()), e); } HostListItem selectedItem = hostList.getSelectedValue(); - Long selectedId = selectedItem == null || selectedItem.getHost() == null ? null : selectedItem.getHost().getId(); + Long selectedId = selectedItem == null || selectedItem.getHost() == null ? null : selectedItem.getHost().getHostId(); refresh(); diff --git a/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestPipeline.java b/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestPipeline.java index 3bef43e0b2..f48fc337f0 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestPipeline.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestPipeline.java @@ -95,6 +95,7 @@ final class DataSourceIngestPipeline extends IngestTaskPipeline { + private static final int FILE_BATCH_SIZE = 500; + private static final String SAVE_RESULTS_ACTIVITY = Bundle.FileIngestPipeline_SaveResults_Activity(); + private static final Logger logger = Logger.getLogger(FileIngestPipeline.class.getName()); private static final IngestManager ingestManager = IngestManager.getInstance(); private final IngestJobPipeline ingestJobPipeline; + private final List fileBatch; /** * Constructs a pipeline of file ingest modules for performing file ingest @@ -44,6 +59,7 @@ final class FileIngestPipeline extends IngestTaskPipeline { FileIngestPipeline(IngestJobPipeline ingestJobPipeline, List moduleTemplates) { super(ingestJobPipeline, moduleTemplates); this.ingestJobPipeline = ingestJobPipeline; + fileBatch = new ArrayList<>(); } @Override @@ -61,36 +77,102 @@ final class FileIngestPipeline extends IngestTaskPipeline { } @Override - @NbBundle.Messages({ - "FileIngestPipeline_SaveResults_Activity=Saving Results" - }) void completeTask(FileIngestTask task) throws IngestTaskPipelineException { - ingestManager.setIngestTaskProgress(task, Bundle.FileIngestPipeline_SaveResults_Activity()); - AbstractFile file = null; try { - file = task.getFile(); + ingestManager.setIngestTaskProgress(task, SAVE_RESULTS_ACTIVITY); + AbstractFile file = task.getFile(); + file.close(); + cacheFileForBatchUpdate(file); } catch (TskCoreException ex) { throw new IngestTaskPipelineException(String.format("Failed to get file (file objId = %d)", task.getFileId()), ex); //NON-NLS - } - try { - if (!ingestJobPipeline.isCancelled()) { - /* - * Save any updates from the ingest modules to the case - * database. - */ - file.save(); - } - } catch (TskCoreException ex) { - throw new IngestTaskPipelineException(String.format("Failed to save updated data for file (file objId = %d)", task.getFileId()), ex); //NON-NLS } finally { - if (!ingestJobPipeline.isCancelled()) { - IngestManager.getInstance().fireFileIngestDone(file); - } - file.close(); ingestManager.setIngestTaskProgressCompleted(task); } } + @Override + List shutDown() { + List errors = new ArrayList<>(); + Date start = new Date(); + try { + updateBatchedFiles(); + } catch (IngestTaskPipelineException ex) { + errors.add(new IngestModuleError(SAVE_RESULTS_ACTIVITY, ex)); + } + Date finish = new Date(); + ingestManager.incrementModuleRunTime(SAVE_RESULTS_ACTIVITY, finish.getTime() - start.getTime()); + errors.addAll(super.shutDown()); + return errors; + } + + /** + * Adds a file to a file cache used to update the case database with new + * properties added to the files in the cache by the ingest modules that + * processed them. If adding the file to the cache fills the cache, a batch + * update is done immediately. + * + * @param file The file. + * + * @throws IngestTaskPipelineException if the case database update fails. + */ + private void cacheFileForBatchUpdate(AbstractFile file) throws IngestTaskPipelineException { + /* + * Only one file ingest thread at a time will try to access the file + * cache. The synchronization here is to ensure visibility of the files + * in all of the threads that share the cache, rather than to prevent + * simultaneous access in multiple threads. + */ + synchronized (fileBatch) { + fileBatch.add(file); + if (fileBatch.size() >= FILE_BATCH_SIZE) { + updateBatchedFiles(); + } + } + } + + /** + * Updates the case database with new properties added to the files in the + * cache by the ingest modules that processed them. + * + * @throws IngestTaskPipelineException if the case database update fails. + */ + private void updateBatchedFiles() throws IngestTaskPipelineException { + /* + * Only one file ingest thread at a time will try to access the file + * cache. The synchronization here is to ensure visibility of the files + * in all of the threads that share the cache, rather than to prevent + * simultaneous access in multiple threads. + */ + synchronized (fileBatch) { + CaseDbTransaction transaction = null; + try { + if (!ingestJobPipeline.isCancelled()) { + Case currentCase = Case.getCurrentCaseThrows(); + SleuthkitCase caseDb = currentCase.getSleuthkitCase(); + transaction = caseDb.beginTransaction(); + for (AbstractFile file : fileBatch) { + file.save(transaction); + } + transaction.commit(); + for (AbstractFile file : fileBatch) { + IngestManager.getInstance().fireFileIngestDone(file); + } + } + } catch (NoCurrentCaseException | TskCoreException ex) { + if (transaction != null) { + try { + transaction.rollback(); + } catch (TskCoreException ex1) { + logger.log(Level.SEVERE, "Error rolling back transaction after failure to save updated properties for cached files from tasks", ex1); + } + } + throw new IngestTaskPipelineException("Failed to save updated properties for cached files from tasks", ex); //NON-NLS + } finally { + fileBatch.clear(); + } + } + } + /** * A wrapper that adds ingest infrastructure operations to a file ingest * module. @@ -123,6 +205,7 @@ final class FileIngestPipeline extends IngestTaskPipeline { ingestManager.setIngestTaskProgress(task, getDisplayName()); ingestJobPipeline.setCurrentFileIngestModule(getDisplayName(), file.getName()); ProcessResult result = module.process(file); + // See JIRA-7449 // if (result == ProcessResult.ERROR) { // throw new IngestModuleException(String.format("%s experienced an error analyzing %s (file objId = %d)", getDisplayName(), file.getName(), file.getId())); //NON-NLS // } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java index f73960aeca..4b3fe4e119 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java @@ -837,7 +837,7 @@ public class IngestManager implements IngestProgressSnapshotProvider { * @param moduleDisplayName The diplay name of the ingest module. * @param duration */ - private void incrementModuleRunTime(String moduleDisplayName, Long duration) { + void incrementModuleRunTime(String moduleDisplayName, Long duration) { if (moduleDisplayName.equals("IDLE")) { //NON-NLS return; } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestTaskPipeline.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestTaskPipeline.java index f7451dd9d8..2866987f46 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestTaskPipeline.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestTaskPipeline.java @@ -36,7 +36,6 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; */ abstract class IngestTaskPipeline { - private static final IngestManager ingestManager = IngestManager.getInstance(); private final IngestJobPipeline ingestJobPipeline; private final List moduleTemplates; private final List> modules; diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties index 3ddcf3d7f3..27440f0cdf 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties @@ -1,5 +1,5 @@ OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=Recent Activity ingest module.\n\n\The module extracts useful information about the recent user activity on the disk image being ingested, such as:\n\n- Recently open documents,\n- Web activity (sites visited, stored cookies, book marked sites, search engine queries, file downloads),\n- Recently attached devices,\n- Installed programs.\n\nThe module currently supports Windows only disk images.\nThe plugin is also fully functional when deployed on Windows version of Autopsy. +OpenIDE-Module-Long-Description=Recent Activity ingest module.\n\n The module extracts useful information about the recent user activity on the disk image being ingested, such as:\n\n- Recently open documents,\n- Web activity (sites visited, stored cookies, book marked sites, search engine queries, file downloads),\n- Recently attached devices,\n- Installed programs.\n\nThe module currently supports Windows only disk images.\nThe plugin is also fully functional when deployed on Windows version of Autopsy. OpenIDE-Module-Name=RecentActivity OpenIDE-Module-Short-Description=Recent Activity finder ingest module Chrome.moduleName=Chromium diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED index 86bf343c8f..547b90ca6a 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED @@ -88,7 +88,7 @@ ExtractZone_progress_Msg=Extracting :Zone.Identifer files ExtractZone_Restricted=Restricted Sites Zone ExtractZone_Trusted=Trusted Sites Zone OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=Recent Activity ingest module.\n\n\The module extracts useful information about the recent user activity on the disk image being ingested, such as:\n\n- Recently open documents,\n- Web activity (sites visited, stored cookies, book marked sites, search engine queries, file downloads),\n- Recently attached devices,\n- Installed programs.\n\nThe module currently supports Windows only disk images.\nThe plugin is also fully functional when deployed on Windows version of Autopsy. +OpenIDE-Module-Long-Description=Recent Activity ingest module.\n\n The module extracts useful information about the recent user activity on the disk image being ingested, such as:\n\n- Recently open documents,\n- Web activity (sites visited, stored cookies, book marked sites, search engine queries, file downloads),\n- Recently attached devices,\n- Installed programs.\n\nThe module currently supports Windows only disk images.\nThe plugin is also fully functional when deployed on Windows version of Autopsy. OpenIDE-Module-Name=RecentActivity OpenIDE-Module-Short-Description=Recent Activity finder ingest module Chrome.moduleName=Chromium diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ChromeCacheExtractor.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ChromeCacheExtractor.java index 8b13eda7d1..1ddc1ed401 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ChromeCacheExtractor.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ChromeCacheExtractor.java @@ -538,8 +538,12 @@ final class ChromeCacheExtractor { webAttr.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID, moduleName, cachedItemFile.getId())); - Optional optional = cacheEntryFile.getOsAccount(); - BlackboardArtifact webCacheArtifact = cacheEntryFile.newDataArtifact(new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_WEB_CACHE), webAttr, optional.isPresent() ? optional.get() : null); + Optional optional = cacheEntryFile.getOsAccountObjectId(); + OsAccount account = null; + if(optional.isPresent()) { + account = currentCase.getSleuthkitCase().getOsAccountManager().getOsAccountByObjectId(optional.get()); + } + BlackboardArtifact webCacheArtifact = cacheEntryFile.newDataArtifact(new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_WEB_CACHE), webAttr, account); artifactsAdded.add(webCacheArtifact); // Create a TSK_ASSOCIATED_OBJECT on the f_XXX or derived file file back to the CACHE entry diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Extract.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Extract.java index 97c17b58dc..e152a146fa 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Extract.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Extract.java @@ -533,7 +533,11 @@ abstract class Extract { Optional getOsAccount(Content content) throws TskCoreException { if(content instanceof AbstractFile) { if(osAccountCache == null) { - return ((AbstractFile)content).getOsAccount(); + Optional accountId = ((AbstractFile)content).getOsAccountObjectId(); + if(accountId.isPresent()) { + return Optional.ofNullable(tskCase.getOsAccountManager().getOsAccountByObjectId(accountId.get())); + } + return Optional.empty(); } return osAccountCache.getOsAccount(((AbstractFile)content)); diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRecycleBin.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRecycleBin.java index 9c0f777407..8e6ad2df8e 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRecycleBin.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRecycleBin.java @@ -35,6 +35,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.logging.Level; import org.joda.time.Instant; import org.openide.util.NbBundle.Messages; @@ -54,7 +55,9 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PAT import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_ID; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME; import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.FsContent; +import org.sleuthkit.datamodel.OsAccount; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; @@ -336,21 +339,11 @@ final class ExtractRecycleBin extends Extract { */ private Map makeUserNameMap(Content dataSource) throws TskCoreException { Map userNameMap = new HashMap<>(); - - List accounts = blackboard.getArtifacts(TSK_OS_ACCOUNT.getTypeID(), dataSource.getId()); - - for (BlackboardArtifact account : accounts) { - BlackboardAttribute nameAttribute = getAttributeForArtifact(account, TSK_USER_NAME); - BlackboardAttribute idAttribute = getAttributeForArtifact(account, TSK_USER_ID); - - String userName = nameAttribute != null ? nameAttribute.getDisplayString() : ""; - String userID = idAttribute != null ? idAttribute.getDisplayString() : ""; - - if (!userID.isEmpty()) { - userNameMap.put(userID, userName); - } + + for(OsAccount account: tskCase.getOsAccountManager().getOsAccounts(((DataSource)dataSource).getHost())) { + Optional userName = account.getLoginName(); + userNameMap.put(account.getName(), userName.isPresent() ? userName.get() : ""); } - return userNameMap; } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index 1c0db38074..1699042b52 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -70,8 +70,6 @@ import java.util.Optional; import static java.util.TimeZone.getTimeZone; import java.util.stream.Collectors; import org.openide.util.Lookup; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress; import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException; import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService; @@ -80,7 +78,6 @@ import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.Blackboard.BlackboardException; import org.sleuthkit.datamodel.BlackboardArtifact; -import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_ACCOUNT; import org.sleuthkit.datamodel.BlackboardAttribute; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME; @@ -90,8 +87,6 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DAT import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_ID; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HOME_DIR; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.DataSource; @@ -101,6 +96,7 @@ import org.sleuthkit.datamodel.OsAccount; import org.sleuthkit.datamodel.OsAccountAttribute; import org.sleuthkit.datamodel.OsAccountInstance; import org.sleuthkit.datamodel.OsAccountManager; +import org.sleuthkit.datamodel.OsAccountManager.NotUserSIDException; import org.sleuthkit.datamodel.OsAccountRealm; import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException; import org.sleuthkit.datamodel.Report; @@ -184,9 +180,9 @@ class ExtractRegistry extends Extract { private static final SimpleDateFormat REG_RIPPER_TIME_FORMAT = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy 'Z'", US); - BlackboardArtifact.Type shellBagArtifactType = null; - BlackboardAttribute.Type shellBagKeyAttributeType = null; - BlackboardAttribute.Type shellBagLastWriteAttributeType = null; + private BlackboardArtifact.Type shellBagArtifactType = null; + private BlackboardAttribute.Type shellBagKeyAttributeType = null; + private BlackboardAttribute.Type shellBagLastWriteAttributeType = null; static { REG_RIPPER_TIME_FORMAT.setTimeZone(getTimeZone("GMT")); @@ -850,68 +846,14 @@ class ExtractRegistry extends Extract { break; case "ProfileList": //NON-NLS - try { - String homeDir = value; - String sid = artnode.getAttribute("sid"); //NON-NLS - String username = artnode.getAttribute("username"); //NON-NLS - - // For now both an OsAccount and the - // TSK_OS_ACCOUNT artifact will be created. - try{ - createOrUpdateOsAccount(regFile, sid, username, homeDir); - - } catch (OsAccountManager.NotUserSIDException ex) { - logger.log(Level.WARNING, String.format("Cannot create OsAccount for file: %s, sid: %s is not a user SID.", regFile.getId(), sid)); - } - catch(TskCoreException | TskDataException ex ) { - logger.log(Level.SEVERE, String.format("Failed to create OsAccount for file: %s, sid: %s", regFile.getId(), sid)); - } - - BlackboardArtifact bbart = null; - try { - //check if any of the existing artifacts match this username - ArrayList existingArtifacts = currentCase.getSleuthkitCase().getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_ACCOUNT); - for (BlackboardArtifact artifact : existingArtifacts) { - if (artifact.getDataSource().getId() == regFile.getDataSourceObjectId()) { - BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_ID)); - if (attribute != null && attribute.getValueString().equals(sid)) { - bbart = artifact; - break; - } - } - } - } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Error getting existing os account artifact", ex); - } - if (bbart == null) { - //create new artifact - bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME, - parentModuleName, username)); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_ID, - parentModuleName, sid)); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH, - parentModuleName, homeDir)); + String homeDir = value; + String sid = artnode.getAttribute("sid"); //NON-NLS + String username = artnode.getAttribute("username"); //NON-NLS - newArtifacts.add(bbart); - } else { - //add attributes to existing artifact - BlackboardAttribute bbattr = bbart.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_NAME)); - - if (bbattr == null) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME, - parentModuleName, username)); - } - bbattr = bbart.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PATH)); - if (bbattr == null) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH, - parentModuleName, homeDir)); - } - } - bbart.addAttributes(bbattributes); - - } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Error adding account artifact to blackboard.", ex); //NON-NLS + try{ + createOrUpdateOsAccount(regFile, sid, username, homeDir); + } catch(TskCoreException | TskDataException | NotUserSIDException ex) { + logger.log(Level.SEVERE, String.format("Failed to create OsAccount for file: %s, sid: %s", regFile.getId(), sid), ex); } break; @@ -1139,9 +1081,9 @@ class ExtractRegistry extends Extract { HostManager hostMrg = tskCase.getHostManager(); Host host = hostMrg.getHost((DataSource)dataSource); - List existingAccounts = accountMgr.getAccounts(host); + List existingAccounts = accountMgr.getOsAccounts(host); for(OsAccount osAccount: existingAccounts) { - Optional optional = osAccount.getUniqueIdWithinRealm(); + Optional optional = osAccount.getAddr(); if(!optional.isPresent()) { continue; } @@ -1155,37 +1097,11 @@ 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); + OsAccount osAccount = accountMgr.createWindowsOsAccount(userInfo.get(SID_KEY), null, null, host, OsAccountRealm.RealmScope.UNKNOWN); accountMgr.createOsAccountInstance(osAccount, (DataSource)dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED); updateOsAccount(osAccount, userInfo, groupMap.get(userInfo.get(SID_KEY)), regAbstractFile); } - // Existing TSK_OS_ACCOUNT code. - - //get all existing OS account artifacts - List existingOsAccounts = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_ACCOUNT); - for (BlackboardArtifact osAccount : existingOsAccounts) { - //if the OS Account artifact was from the same data source check the user id - if (osAccount.getDataSource().getId() == regAbstractFile.getDataSourceObjectId()) { - BlackboardAttribute existingUserId = osAccount.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_ID)); - if (existingUserId != null) { - String userID = existingUserId.getValueString().trim(); - Map userInfo = userInfoMap.remove(userID); - //if the existing user id matches a user id which we parsed information for check if that information exists and if it doesn't add it - if (userInfo != null) { - osAccount.addAttributes(getAttributesForAccount(userInfo, groupMap.get(userID), true, regAbstractFile)); - } - } - } - } - - //add remaining userinfos as accounts; - for (Map userInfo : userInfoMap.values()) { - BlackboardArtifact bbart = regAbstractFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT); - bbart.addAttributes(getAttributesForAccount(userInfo, groupMap.get(userInfo.get(SID_KEY)), false, regAbstractFile)); - // index the artifact for keyword search - newArtifacts.add(bbart); - } // 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 { @@ -1201,8 +1117,6 @@ class ExtractRegistry extends Extract { logger.log(Level.WARNING, "Error finding the registry file.", ex); //NON-NLS } catch (IOException ex) { logger.log(Level.WARNING, "Error building the document parser: {0}", ex); //NON-NLS - } catch (ParseException ex) { - logger.log(Level.WARNING, "Error parsing the the date from the registry file", ex); //NON-NLS } catch (TskDataException | TskCoreException ex) { logger.log(Level.WARNING, "Error updating TSK_OS_ACCOUNT artifacts to include newly parsed data.", ex); //NON-NLS } catch (OsAccountManager.NotUserSIDException ex) { @@ -1215,163 +1129,6 @@ class ExtractRegistry extends Extract { } return false; } - - /** - * Creates the attribute list for the given user information and group list. - * - * @param userInfo Map of key\value pairs of user information - * @param groupList List of the groups that user belongs - * @param existingUser - * - * @return List - * - * @throws ParseException - */ - Collection getAttributesForAccount(Map userInfo, List groupList, boolean existingUser, AbstractFile regAbstractFile) throws ParseException { - Collection bbattributes = new ArrayList<>(); - - SimpleDateFormat regRipperTimeFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy 'Z'", US); - regRipperTimeFormat.setTimeZone(getTimeZone("GMT")); - - if (!existingUser) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_ID, - getRAModuleName(), userInfo.get(SID_KEY))); - - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME, - getRAModuleName(), userInfo.get(USERNAME_KEY))); - } - - String value = userInfo.get(ACCOUNT_CREATED_KEY); - if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED, - getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC)); - } - - value = userInfo.get(LAST_LOGIN_KEY); - if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, - getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC)); - } - - value = userInfo.get(LOGIN_COUNT_KEY); - if (value != null && !value.isEmpty()) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT, - getRAModuleName(), Integer.parseInt(value))); - } - - value = userInfo.get(ACCOUNT_TYPE_KEY); - if (value != null && !value.isEmpty()) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE, - getRAModuleName(), value)); - } - - value = userInfo.get(USER_COMMENT_KEY); - if (value != null && !value.isEmpty()) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DESCRIPTION, - getRAModuleName(), value)); - } - - value = userInfo.get(NAME_KEY); - if (value != null && !value.isEmpty()) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, - getRAModuleName(), value)); - } - - value = userInfo.get(INTERNET_NAME_KEY); - if (value != null && !value.isEmpty()) { - try { - // Create an account for this email, if it doesn't already exist. - Case.getCurrentCaseThrows() - .getSleuthkitCase() - .getCommunicationsManager() - .createAccountFileInstance(Account.Type.EMAIL, - value, getRAModuleName(), regAbstractFile); - } catch (NoCurrentCaseException | TskCoreException ex) { - logger.log(Level.SEVERE, - String.format("Error adding email account with value " - + "%s, to the case database for file %s [objId=%d]", - value, regAbstractFile.getName(), regAbstractFile.getId()), ex); - } - - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL, - getRAModuleName(), value)); - } - - value = userInfo.get(FULL_NAME_KEY); - if (value != null && !value.isEmpty()) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DISPLAY_NAME, - getRAModuleName(), value)); - } - - value = userInfo.get(PWD_RESET_KEY); - if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_PASSWORD_RESET, - getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC)); - } - - value = userInfo.get(PASSWORD_HINT); - if (value != null && !value.isEmpty()) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PASSWORD_HINT, - getRAModuleName(), value)); - } - - value = userInfo.get(PWD_FAILE_KEY); - if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_PASSWORD_FAIL, - getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC)); - } - - String settingString = ""; - for (String setting : PASSWORD_SETTINGS_FLAGS) { - if (userInfo.containsKey(setting)) { - settingString += setting + ", "; - } - } - - if (!settingString.isEmpty()) { - settingString = settingString.substring(0, settingString.length() - 2); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PASSWORD_SETTINGS, - getRAModuleName(), settingString)); - } - - settingString = ""; - for (String setting : ACCOUNT_SETTINGS_FLAGS) { - if (userInfo.containsKey(setting)) { - settingString += setting + ", "; - } - } - - if (!settingString.isEmpty()) { - settingString = settingString.substring(0, settingString.length() - 2); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_SETTINGS, - getRAModuleName(), settingString)); - } - - settingString = ""; - for (String setting : ACCOUNT_TYPE_FLAGS) { - if (userInfo.containsKey(setting)) { - settingString += setting + ", "; - } - } - - if (!settingString.isEmpty()) { - settingString = settingString.substring(0, settingString.length() - 2); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_FLAG, - getRAModuleName(), settingString)); - } - - if (groupList != null && groupList.isEmpty()) { - String groups = ""; - for (String group : groupList) { - groups += group + ", "; - } - - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_GROUPS, - getRAModuleName(), groups.substring(0, groups.length() - 2))); - } - - return bbattributes; - } /** * Read the User Information section of the SAM regripper plugin's output @@ -1957,23 +1714,14 @@ class ExtractRegistry extends Extract { * @throws TskCoreException */ private Map makeUserNameMap(Content dataSource) throws TskCoreException { - Map userNameMap = new HashMap<>(); + Map map = new HashMap<>(); - List accounts = blackboard.getArtifacts(TSK_OS_ACCOUNT.getTypeID(), dataSource.getId()); - - for (BlackboardArtifact account : accounts) { - BlackboardAttribute nameAttribute = getAttributeForArtifact(account, TSK_USER_NAME); - BlackboardAttribute idAttribute = getAttributeForArtifact(account, TSK_USER_ID); - - String userName = nameAttribute != null ? nameAttribute.getDisplayString() : ""; - String userID = idAttribute != null ? idAttribute.getDisplayString() : ""; - - if (!userID.isEmpty()) { - userNameMap.put(userID, userName); - } + for(OsAccount account: tskCase.getOsAccountManager().getOsAccounts(((DataSource)dataSource).getHost())) { + Optional userName = account.getLoginName(); + map.put(account.getName(), userName.isPresent() ? userName.get() : ""); } - return userNameMap; + return map; } /** @@ -2216,15 +1964,15 @@ class ExtractRegistry extends Extract { * @throws TskDataException * @throws OsAccountManager.NotUserSIDException */ - private void createOrUpdateOsAccount(AbstractFile file, String sid, String userName, String homeDir) throws TskCoreException, TskDataException, OsAccountManager.NotUserSIDException { + private void createOrUpdateOsAccount(AbstractFile file, String sid, String userName, String homeDir) throws TskCoreException, TskDataException, NotUserSIDException { OsAccountManager accountMgr = tskCase.getOsAccountManager(); HostManager hostMrg = tskCase.getHostManager(); Host host = hostMrg.getHost((DataSource)dataSource); - Optional optional = accountMgr.getWindowsAccount(sid, null, null, host); + Optional optional = accountMgr.getWindowsOsAccount(sid, null, null, host); OsAccount osAccount; if (!optional.isPresent()) { - osAccount = accountMgr.createWindowsAccount(sid, userName != null && userName.isEmpty() ? null : userName, null, host, OsAccountRealm.RealmScope.UNKNOWN); + osAccount = accountMgr.createWindowsOsAccount(sid, userName != null && userName.isEmpty() ? null : userName, null, host, OsAccountRealm.RealmScope.UNKNOWN); accountMgr.createOsAccountInstance(osAccount, (DataSource)dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED); } else { osAccount = optional.get(); @@ -2241,7 +1989,7 @@ class ExtractRegistry extends Extract { osAccount.addAttributes(attributes); } - accountMgr.updateAccount(osAccount); + accountMgr.updateOsAccount(osAccount); } /** @@ -2317,6 +2065,11 @@ class ExtractRegistry extends Extract { osAccount, host, regFile)); } } + + value = userInfo.get(USERNAME_KEY); + if (value != null && !value.isEmpty()) { + osAccount.setLoginName(value); + } value = userInfo.get(LOGIN_COUNT_KEY); if (value != null && !value.isEmpty()) { @@ -2411,7 +2164,7 @@ class ExtractRegistry extends Extract { } osAccount.addAttributes(attributes); - tskCase.getOsAccountManager().updateAccount(osAccount); + tskCase.getOsAccountManager().updateOsAccount(osAccount); } /** diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAOsAccountCache.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAOsAccountCache.java index f5208807af..788f219371 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAOsAccountCache.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAOsAccountCache.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.Host; @@ -71,18 +72,18 @@ final class RAOsAccountCache { * @throws TskCoreException */ Optional getOsAccount(AbstractFile file) throws TskCoreException { - Optional optional = file.getOsAccount(); + Optional optional = file.getOsAccountObjectId(); if (!optional.isPresent()) { return getAccountForPath(file.getParentPath()); } - OsAccount osAccount = optional.get(); + OsAccount osAccount = Case.getCurrentCase().getSleuthkitCase().getOsAccountManager().getOsAccountByObjectId(optional.get()); if (osAccount.getName().equals("S-1-5-32-544")) { return getAccountForPath(file.getParentPath()); } - return optional; + return Optional.ofNullable(osAccount); } /** @@ -113,14 +114,14 @@ final class RAOsAccountCache { */ private void buildAccountMap(SleuthkitCase tskCase, Host host) throws TskCoreException { BlackboardAttribute.Type homeDir = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HOME_DIR); - List accounts = tskCase.getOsAccountManager().getAccounts(host); + List accounts = tskCase.getOsAccountManager().getOsAccounts(host); for (OsAccount account : accounts) { List attributeList = account.getOsAccountAttributes(); for (OsAccountAttribute attribute : attributeList) { if (attribute.getHostId().isPresent() - && attribute.getHostId().get().equals(host.getId()) + && attribute.getHostId().get().equals(host.getHostId()) && attribute.getAttributeType().equals(homeDir)) { accountCache.put(attribute.getValueString(), account); }