19package org.sleuthkit.autopsy.datamodel;
21import java.beans.PropertyChangeEvent;
22import java.beans.PropertyChangeListener;
23import java.lang.ref.WeakReference;
24import java.util.ArrayList;
25import java.util.Arrays;
26import java.util.Collections;
27import java.util.EnumSet;
29import java.util.Optional;
30import java.util.logging.Level;
31import java.util.stream.Collectors;
32import javax.swing.Action;
33import org.apache.commons.lang3.tuple.Pair;
34import javax.swing.SwingUtilities;
35import org.apache.commons.lang3.StringUtils;
36import org.openide.nodes.ChildFactory;
37import org.openide.nodes.Children;
38import org.openide.nodes.Node;
39import org.openide.nodes.Sheet;
40import org.openide.util.NbBundle;
41import org.openide.util.NbBundle.Messages;
42import org.openide.util.WeakListeners;
43import org.sleuthkit.autopsy.casemodule.Case;
44import org.sleuthkit.autopsy.casemodule.events.OsAccountsUpdatedEvent;
45import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil;
46import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
47import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
48import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
49import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
50import org.sleuthkit.autopsy.core.UserPreferences;
51import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
52import org.sleuthkit.autopsy.coreutils.Logger;
53import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
54import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.NO_DESCR;
55import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.VALUE_LOADING;
56import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.backgroundTasksPool;
57import org.sleuthkit.autopsy.events.AutopsyEvent;
58import org.sleuthkit.datamodel.Host;
59import org.sleuthkit.datamodel.OsAccount;
60import org.sleuthkit.datamodel.OsAccountRealm;
61import org.sleuthkit.datamodel.SleuthkitCase;
62import org.sleuthkit.datamodel.Tag;
63import org.sleuthkit.datamodel.TskCoreException;
71 private static final String
ICON_PATH =
"org/sleuthkit/autopsy/images/os-account.png";
74 private static final String
LIST_NAME = Bundle.OsAccount_listNode_name();
94 this.filteringDSObjId = objId;
99 return visitor.
visit(
this);
103 "OsAccount_listNode_name=OS Accounts"
117 setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/os-account.png");
122 return visitor.
visit(
this);
132 return getClass().getName();
142 private final PropertyChangeListener
listener =
new PropertyChangeListener() {
144 public void propertyChange(PropertyChangeEvent evt) {
145 String eventType = evt.getPropertyName();
151 if (evt.getNewValue() ==
null) {
159 private final PropertyChangeListener
weakPcl = WeakListeners.propertyChange(
listener,
null);
179 list.addAll(
skCase.getOsAccountManager().getOsAccounts());
183 }
catch (TskCoreException ex) {
184 logger.log(Level.SEVERE,
"Unable to retrieve list of OsAccounts for case", ex);
200 public static final class OsAccountNode
extends AbstractContentNode<OsAccount> {
205 "OsAccounts_accountNameProperty_name=Name",
206 "OsAccounts_accountNameProperty_displayName=Name",
207 "OsAccounts_accountNameProperty_desc=Os Account name",
208 "OsAccounts_accountRealmNameProperty_name=RealmName",
209 "OsAccounts_accountRealmNameProperty_displayName=Realm Name",
210 "OsAccounts_accountRealmNameProperty_desc=OS Account Realm Name",
211 "OsAccounts_accountHostNameProperty_name=HostName",
212 "OsAccounts_accountHostNameProperty_displayName=Host",
213 "OsAccounts_accountHostNameProperty_desc=OS Account Host Name",
214 "OsAccounts_accountScopeNameProperty_name=ScopeName",
215 "OsAccounts_accountScopeNameProperty_displayName=Scope",
216 "OsAccounts_accountScopeNameProperty_desc=OS Account Scope Name",
217 "OsAccounts_createdTimeProperty_name=creationTime",
218 "OsAccounts_createdTimeProperty_displayName=Creation Time",
219 "OsAccounts_createdTimeProperty_desc=OS Account Creation Time",
220 "OsAccounts_loginNameProperty_name=loginName",
221 "OsAccounts_loginNameProperty_displayName=Login Name",
222 "OsAccounts_loginNameProperty_desc=OS Account login name",
223 "OsAccounts.createSheet.score.name=S",
224 "OsAccounts.createSheet.score.displayName=S",
225 "OsAccounts.createSheet.count.name=O",
226 "OsAccounts.createSheet.count.displayName=O",
227 "OsAccounts.createSheet.comment.name=C",
228 "OsAccounts.createSheet.comment.displayName=C"
230 private final PropertyChangeListener
listener =
new PropertyChangeListener() {
232 public void propertyChange(PropertyChangeEvent evt) {
235 for (OsAccount acct : updateEvent.getOsAccounts()) {
236 if (acct.getId() ==
account.getId()) {
246 List<NodeProperty<?>> propertiesToUpdate =
new ArrayList<>();
250 List<String> realmNames = osAcctData.getOsAcctRealm().getRealmNames();
251 if (!realmNames.isEmpty()) {
252 String realmNamesStr = realmNames.stream()
255 .sorted((a, b) -> a.compareToIgnoreCase(b))
256 .collect(Collectors.joining(
", "));
259 Bundle.OsAccounts_accountRealmNameProperty_name(),
260 Bundle.OsAccounts_accountRealmNameProperty_displayName(),
261 Bundle.OsAccounts_accountRealmNameProperty_desc(),
265 String scopeName = osAcctData.getOsAcctRealm().getScope().getName();
266 if (StringUtils.isNotBlank(scopeName)) {
268 Bundle.OsAccounts_accountScopeNameProperty_name(),
269 Bundle.OsAccounts_accountScopeNameProperty_displayName(),
270 Bundle.OsAccounts_accountScopeNameProperty_desc(),
274 List<Host>
hosts = osAcctData.getHosts();
275 if (!
hosts.isEmpty()) {
276 String hostsString =
hosts.stream()
277 .map(h -> h.getName().trim())
279 .sorted((a, b) -> a.compareToIgnoreCase(b))
280 .collect(Collectors.joining(
", "));
283 Bundle.OsAccounts_accountHostNameProperty_name(),
284 Bundle.OsAccounts_accountHostNameProperty_displayName(),
285 Bundle.OsAccounts_accountHostNameProperty_desc(),
288 updateSheet(propertiesToUpdate.toArray(
new NodeProperty<?>[propertiesToUpdate.size()]));
290 SCOData scoData = (SCOData) evt.getNewValue();
291 if (scoData.getScoreAndDescription() !=
null) {
293 Bundle.OsAccounts_createSheet_score_name(),
294 Bundle.OsAccounts_createSheet_score_displayName(),
295 scoData.getScoreAndDescription().getRight(),
296 scoData.getScoreAndDescription().getLeft()));
298 if (scoData.getComment() !=
null) {
300 Bundle.OsAccounts_createSheet_comment_name(),
301 Bundle.OsAccounts_createSheet_comment_displayName(),
304 if (scoData.getCountAndDescription() !=
null) {
306 Bundle.OsAccounts_createSheet_count_name(),
307 Bundle.OsAccounts_createSheet_count_displayName(),
308 scoData.getCountAndDescription().getRight(),
309 scoData.getCountAndDescription().getLeft()));
322 OsAccountNode(OsAccount
account) {
327 setDisplayName(
account.getName());
335 return visitor.
visit(
this);
345 return getClass().getName();
353 OsAccount getOsAccount() {
361 SwingUtilities.invokeLater(() -> {
368 Sheet sheet = super.createSheet();
369 Sheet.Set propertiesSet = sheet.get(Sheet.PROPERTIES);
370 if (propertiesSet ==
null) {
371 propertiesSet = Sheet.createPropertiesSet();
372 sheet.put(propertiesSet);
375 Bundle.OsAccounts_accountNameProperty_name(),
376 Bundle.OsAccounts_accountNameProperty_displayName(),
377 Bundle.OsAccounts_accountNameProperty_desc(),
380 Optional<String> optional =
account.getLoginName();
382 Bundle.OsAccounts_loginNameProperty_name(),
383 Bundle.OsAccounts_loginNameProperty_displayName(),
384 Bundle.OsAccounts_loginNameProperty_desc(),
385 optional.isPresent() ? optional.get() :
""));
389 Bundle.OsAccounts_accountHostNameProperty_name(),
390 Bundle.OsAccounts_accountHostNameProperty_displayName(),
391 Bundle.OsAccounts_accountHostNameProperty_desc(),
395 Bundle.OsAccounts_accountScopeNameProperty_name(),
396 Bundle.OsAccounts_accountScopeNameProperty_displayName(),
397 Bundle.OsAccounts_accountScopeNameProperty_desc(),
401 Bundle.OsAccounts_accountRealmNameProperty_name(),
402 Bundle.OsAccounts_accountRealmNameProperty_displayName(),
403 Bundle.OsAccounts_accountRealmNameProperty_desc(),
406 Optional<Long> creationTimeValue =
account.getCreationTime();
407 String timeDisplayStr
411 Bundle.OsAccounts_createdTimeProperty_name(),
412 Bundle.OsAccounts_createdTimeProperty_displayName(),
413 Bundle.OsAccounts_createdTimeProperty_desc(),
416 backgroundTasksPool.submit(
new GetOsAccountRealmTask(
new WeakReference<>(
this),
weakListener));
431 Bundle.OsAccounts_createSheet_score_name(),
432 Bundle.OsAccounts_createSheet_score_displayName(),
436 Bundle.OsAccounts_createSheet_comment_name(),
437 Bundle.OsAccounts_createSheet_comment_displayName(),
442 Bundle.OsAccounts_createSheet_count_name(),
443 Bundle.OsAccounts_createSheet_count_displayName(),
447 backgroundTasksPool.submit(
new GetSCOTask(
new WeakReference<>(
this),
weakListener));
453 List<Action> actionsList =
new ArrayList<>();
455 actionsList.add(
null);
456 actionsList.addAll(Arrays.asList(super.getActions(popup)));
457 return actionsList.toArray(
new Action[actionsList.size()]);
462 return new ArrayList<>();
467 return visitor.
visit(
this);
473 static class GetOsAccountRealmTask
implements Runnable {
475 private final WeakReference<OsAccountNode> weakNodeRef;
476 private final PropertyChangeListener
listener;
484 GetOsAccountRealmTask(WeakReference<OsAccountNode> weakContentRef, PropertyChangeListener
listener) {
485 this.weakNodeRef = weakContentRef;
491 OsAccountNode node = weakNodeRef.get();
497 SleuthkitCase
skCase = Case.getCurrentCase().getSleuthkitCase();
498 OsAccount osAcct = node.getOsAccount();
499 long realmId = osAcct.getRealmId();
500 OsAccountRealm realm =
skCase.getOsAccountRealmManager().getRealmByRealmId(realmId);
502 List<Host> hosts =
skCase.getOsAccountManager().getHosts(osAcct);
504 AsynchOsAcctData evtData =
new AsynchOsAcctData(osAcct.getId(), realm, hosts);
506 if (
listener !=
null && realm !=
null) {
507 listener.propertyChange(
new PropertyChangeEvent(
508 AutopsyEvent.SourceType.LOCAL.toString(),
512 }
catch (TskCoreException ex) {
513 logger.log(Level.WARNING,
"Error occurred getting realm information for Os Account Node from case db, for account: " + node.getOsAccount().getName(), ex);
519 "OsAccounts.createSheet.count.hashLookupNotRun.description=Hash lookup had not been run on this file when the column was populated",
520 "# {0} - occurrenceCount",
521 "OsAccounts.createSheet.count.description=There were {0} datasource(s) found with occurrences of the OS Account correlation value"})
526 String description = defaultDescription;
529 if (attributeInstance !=
null && StringUtils.isNotBlank(attributeInstance.
getCorrelationValue())) {
531 description = Bundle.OsAccounts_createSheet_count_description(count);
532 }
else if (attributeInstance !=
null) {
533 description = Bundle.OsAccounts_createSheet_count_hashLookupNotRun_description();
540 return Pair.of(count, description);
558 for (Tag tag :
tags) {
559 if (!StringUtils.isBlank(tag.getComment())) {
577 logger.log(Level.SEVERE,
"Attempted to Query CR for presence of comments in an OS Account node and was unable to perform query, comment column will only reflect caseDB", ex);
586 private static class AsynchOsAcctData {
608 long getOsAccountId() {
615 OsAccountRealm getOsAcctRealm() {
622 List<Host> getHosts() {
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
static boolean commentExistsOnAttributes(List< CorrelationAttributeInstance > attributes)
String getCorrelationValue()
Type getCorrelationType()
static boolean getHideSCOColumns()
synchronized static Logger getLogger(String name)
static String getFormattedTime(long epochTime)
static final String NO_DESCR
static final Logger logger
static final String VALUE_LOADING
void setName(String name)
static List< Action > getActions(File file, boolean isArtifactSource)
DisplayableItemNode(Children children)
final OsAccountRealm osAcctRealm
Node createNodeForKey(OsAccount key)
boolean createKeys(List< OsAccount > list)
final PropertyChangeListener weakPcl
final PropertyChangeListener listener
Action[] getActions(boolean popup)
final PropertyChangeListener weakListener
DataResultViewerTable.HasCommentStatus getCommentProperty(List< Tag > tags, List< CorrelationAttributeInstance > attributes)
void addSCOColumns(Sheet.Set sheetSet)
List< Tag > getAllTagsFromDatabase()
Pair< Long, String > getCountPropertyAndDescription(CorrelationAttributeInstance attributeInstance, String defaultDescription)
final PropertyChangeListener listener
static String getListName()
final long filteringDSObjId
static final String OS_ACCOUNT_DATA_AVAILABLE_EVENT
static final String ICON_PATH
static final String LIST_NAME
static final Logger logger
OsAccounts(SleuthkitCase skCase, long objId)
OsAccounts(SleuthkitCase skCase)
Long getCountCasesWithOtherInstances(CorrelationAttributeInstance instance)
static CentralRepository getInstance()
static boolean isEnabled()
T visit(DataSourceFilesNode in)