mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 02:07:42 +00:00
Merge branch 'develop' of https://github.com/sleuthkit/autopsy into 2882-AllowResetWhileCaseOpen
This commit is contained in:
commit
c2a338768d
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ public class HostsEvent extends TskDataModelChangeEvent<Host> {
|
||||
private static List<Long> getIds(List<Host> hosts) {
|
||||
return getSafeList(hosts).stream()
|
||||
.filter(h -> h != null)
|
||||
.map(h -> h.getId()).collect(Collectors.toList());
|
||||
.map(h -> h.getHostId()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,7 +56,7 @@ class OsAccountEvent extends TskDataModelChangeEvent<OsAccount> {
|
||||
@Override
|
||||
protected List<OsAccount> getDataModelObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
|
||||
Long id = ids.get(0);
|
||||
OsAccount account = caseDb.getOsAccountManager().getOsAccount(id);
|
||||
OsAccount account = caseDb.getOsAccountManager().getOsAccountByObjectId(id);
|
||||
List<OsAccount> accounts = new ArrayList<>();
|
||||
accounts.add(account);
|
||||
return accounts;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public class PersonsEvent extends TskDataModelChangeEvent<Person> {
|
||||
private static List<Long> getIds(List<Person> persons) {
|
||||
return getSafeList(persons).stream()
|
||||
.filter(h -> h != null)
|
||||
.map(h -> h.getId()).collect(Collectors.toList());
|
||||
.map(h -> h.getPersonId()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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<WorkerResults, Void> {
|
||||
|
||||
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<Host, List<OsAccountAttribute>> hostMap = new HashMap<>();
|
||||
Map<Host, DataSource> instanceMap = new HashMap<>();
|
||||
OsAccountManager osAccountManager = Case.getCurrentCase().getSleuthkitCase().getOsAccountManager();
|
||||
|
||||
if(account == null) {
|
||||
account = osAccountManager.getOsAccountByObjectId(accountId);
|
||||
}
|
||||
|
||||
List<Host> hosts = osAccountManager.getHosts(account);
|
||||
List<OsAccountAttribute> attributeList = account.getOsAccountAttributes();
|
||||
|
||||
@ -362,7 +392,7 @@ public class OsAccountDataPanel extends JPanel {
|
||||
|
||||
// Add attribute lists to the hostMap
|
||||
for (Host host : hosts) {
|
||||
List<OsAccountAttribute> atList = idMap.get(host.getId());
|
||||
List<OsAccountAttribute> atList = idMap.get(host.getHostId());
|
||||
if (atList != null) {
|
||||
hostMap.put(host, atList);
|
||||
}
|
||||
|
@ -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<OsAccount> 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<Long> 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<OsAccount> 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;
|
||||
|
@ -51,7 +51,7 @@ public class HostDataSources implements AutopsyVisitableItem, Comparable<HostDat
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.host == null ? 0 : this.host.getId());
|
||||
return Objects.hashCode(this.host == null ? 0 : this.host.getHostId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -66,8 +66,8 @@ public class HostDataSources implements AutopsyVisitableItem, Comparable<HostDat
|
||||
return false;
|
||||
}
|
||||
final HostDataSources other = (HostDataSources) obj;
|
||||
long thisId = (this.getHost() == null) ? 0 : this.getHost().getId();
|
||||
long otherId = (other.getHost() == null) ? 0 : other.getHost().getId();
|
||||
long thisId = (this.getHost() == null) ? 0 : this.getHost().getHostId();
|
||||
long otherId = (other.getHost() == null) ? 0 : other.getHost().getHostId();
|
||||
return thisId == otherId;
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ public class HostGrouping implements AutopsyVisitableItem, Comparable<HostGroupi
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.host == null ? 0 : this.host.getId());
|
||||
return Objects.hashCode(this.host == null ? 0 : this.host.getHostId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -66,8 +66,8 @@ public class HostGrouping implements AutopsyVisitableItem, Comparable<HostGroupi
|
||||
return false;
|
||||
}
|
||||
final HostGrouping other = (HostGrouping) obj;
|
||||
long thisId = (this.getHost() == null) ? 0 : this.getHost().getId();
|
||||
long otherId = (other.getHost() == null) ? 0 : other.getHost().getId();
|
||||
long thisId = (this.getHost() == null) ? 0 : this.getHost().getHostId();
|
||||
long otherId = (other.getHost() == null) ? 0 : other.getHost().getHostId();
|
||||
return thisId == otherId;
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,7 @@ public class HostNode extends DisplayableItemNode {
|
||||
String eventType = evt.getPropertyName();
|
||||
if (hostId != null && eventType.equals(Case.Events.HOSTS_CHANGED.toString()) && evt instanceof HostsChangedEvent) {
|
||||
((HostsChangedEvent) evt).getNewValue().stream()
|
||||
.filter(h -> 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);
|
||||
|
@ -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);
|
||||
|
@ -52,7 +52,7 @@ public class PersonGrouping implements AutopsyVisitableItem, Comparable<PersonGr
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.person == null ? 0 : this.person.getId());
|
||||
return Objects.hashCode(this.person == null ? 0 : this.person.getPersonId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -67,8 +67,8 @@ public class PersonGrouping implements AutopsyVisitableItem, Comparable<PersonGr
|
||||
return false;
|
||||
}
|
||||
final PersonGrouping other = (PersonGrouping) obj;
|
||||
long thisId = (this.getPerson() == null) ? 0 : this.getPerson().getId();
|
||||
long otherId = (other.getPerson() == null) ? 0 : other.getPerson().getId();
|
||||
long thisId = (this.getPerson() == null) ? 0 : this.getPerson().getPersonId();
|
||||
long otherId = (other.getPerson() == null) ? 0 : other.getPerson().getPersonId();
|
||||
return thisId == otherId;
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ public class PersonGroupingNode extends DisplayableItemNode {
|
||||
String eventType = evt.getPropertyName();
|
||||
if (personId != null && eventType.equals(Case.Events.PERSONS_CHANGED.toString()) && evt instanceof PersonsChangedEvent) {
|
||||
((PersonsChangedEvent) evt).getNewValue().stream()
|
||||
.filter(p -> 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));
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -95,6 +95,7 @@ final class DataSourceIngestPipeline extends IngestTaskPipeline<DataSourceIngest
|
||||
if (!ingestJobPipeline.isCancelled() && ingestJobPipeline.currentDataSourceIngestModuleIsCancelled()) {
|
||||
ingestJobPipeline.currentDataSourceIngestModuleCancellationCompleted(getDisplayName());
|
||||
}
|
||||
// See JIRA-7449
|
||||
// if (result == ProcessResult.ERROR) {
|
||||
// throw new IngestModuleException(String.format("%s experienced an error analyzing %s (data source objId = %d)", getDisplayName(), dataSource.getName(), dataSource.getId())); //NON-NLS
|
||||
// }
|
||||
|
@ -18,20 +18,35 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.ingest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
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.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* A pipeline of file ingest modules for performing file ingest tasks for an
|
||||
* ingest job.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"FileIngestPipeline_SaveResults_Activity=Saving Results"
|
||||
})
|
||||
final class FileIngestPipeline extends IngestTaskPipeline<FileIngestTask> {
|
||||
|
||||
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<AbstractFile> fileBatch;
|
||||
|
||||
/**
|
||||
* Constructs a pipeline of file ingest modules for performing file ingest
|
||||
@ -44,6 +59,7 @@ final class FileIngestPipeline extends IngestTaskPipeline<FileIngestTask> {
|
||||
FileIngestPipeline(IngestJobPipeline ingestJobPipeline, List<IngestModuleTemplate> moduleTemplates) {
|
||||
super(ingestJobPipeline, moduleTemplates);
|
||||
this.ingestJobPipeline = ingestJobPipeline;
|
||||
fileBatch = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -61,36 +77,102 @@ final class FileIngestPipeline extends IngestTaskPipeline<FileIngestTask> {
|
||||
}
|
||||
|
||||
@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<IngestModuleError> shutDown() {
|
||||
List<IngestModuleError> 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<FileIngestTask> {
|
||||
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
|
||||
// }
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -36,7 +36,6 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
*/
|
||||
abstract class IngestTaskPipeline<T extends IngestTask> {
|
||||
|
||||
private static final IngestManager ingestManager = IngestManager.getInstance();
|
||||
private final IngestJobPipeline ingestJobPipeline;
|
||||
private final List<IngestModuleTemplate> moduleTemplates;
|
||||
private final List<PipelineModule<T>> modules;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -538,8 +538,12 @@ final class ChromeCacheExtractor {
|
||||
webAttr.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID,
|
||||
moduleName, cachedItemFile.getId()));
|
||||
|
||||
Optional<OsAccount> optional = cacheEntryFile.getOsAccount();
|
||||
BlackboardArtifact webCacheArtifact = cacheEntryFile.newDataArtifact(new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_WEB_CACHE), webAttr, optional.isPresent() ? optional.get() : null);
|
||||
Optional<Long> 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
|
||||
|
@ -533,7 +533,11 @@ abstract class Extract {
|
||||
Optional<OsAccount> getOsAccount(Content content) throws TskCoreException {
|
||||
if(content instanceof AbstractFile) {
|
||||
if(osAccountCache == null) {
|
||||
return ((AbstractFile)content).getOsAccount();
|
||||
Optional<Long> accountId = ((AbstractFile)content).getOsAccountObjectId();
|
||||
if(accountId.isPresent()) {
|
||||
return Optional.ofNullable(tskCase.getOsAccountManager().getOsAccountByObjectId(accountId.get()));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return osAccountCache.getOsAccount(((AbstractFile)content));
|
||||
|
@ -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<String, String> makeUserNameMap(Content dataSource) throws TskCoreException {
|
||||
Map<String, String> userNameMap = new HashMap<>();
|
||||
|
||||
List<BlackboardArtifact> 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<String> userName = account.getLoginName();
|
||||
userNameMap.put(account.getName(), userName.isPresent() ? userName.get() : "");
|
||||
}
|
||||
|
||||
return userNameMap;
|
||||
}
|
||||
|
||||
|
@ -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<BlackboardArtifact> 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<OsAccount> existingAccounts = accountMgr.getAccounts(host);
|
||||
List<OsAccount> existingAccounts = accountMgr.getOsAccounts(host);
|
||||
for(OsAccount osAccount: existingAccounts) {
|
||||
Optional<String> optional = osAccount.getUniqueIdWithinRealm();
|
||||
Optional<String> optional = osAccount.getAddr();
|
||||
if(!optional.isPresent()) {
|
||||
continue;
|
||||
}
|
||||
@ -1155,37 +1097,11 @@ class ExtractRegistry extends Extract {
|
||||
|
||||
//add remaining userinfos as accounts;
|
||||
for (Map<String, String> 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<BlackboardArtifact> 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<String, String> 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<String, String> 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<BlackboardAttribute> getAttributesForAccount(Map<String, String> userInfo, List<String> groupList, boolean existingUser, AbstractFile regAbstractFile) throws ParseException {
|
||||
Collection<BlackboardAttribute> 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<String, String> makeUserNameMap(Content dataSource) throws TskCoreException {
|
||||
Map<String, String> userNameMap = new HashMap<>();
|
||||
Map<String, String> map = new HashMap<>();
|
||||
|
||||
List<BlackboardArtifact> 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<String> 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<OsAccount> optional = accountMgr.getWindowsAccount(sid, null, null, host);
|
||||
Optional<OsAccount> 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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<OsAccount> getOsAccount(AbstractFile file) throws TskCoreException {
|
||||
Optional<OsAccount> optional = file.getOsAccount();
|
||||
Optional<Long> 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<OsAccount> accounts = tskCase.getOsAccountManager().getAccounts(host);
|
||||
List<OsAccount> accounts = tskCase.getOsAccountManager().getOsAccounts(host);
|
||||
|
||||
for (OsAccount account : accounts) {
|
||||
List<OsAccountAttribute> 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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user