Autopsy  4.19.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
OsAccounts.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2021 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.datamodel;
20 
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.lang.ref.WeakReference;
24 import java.text.SimpleDateFormat;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.EnumSet;
29 import java.util.List;
30 import java.util.Optional;
31 import java.util.logging.Level;
32 import javax.swing.Action;
33 import org.apache.commons.lang3.tuple.Pair;
34 import org.openide.nodes.ChildFactory;
35 import org.openide.nodes.Children;
36 import org.openide.nodes.Node;
37 import org.openide.nodes.Sheet;
38 import org.openide.util.Exceptions;
39 import org.openide.util.NbBundle.Messages;
40 import org.openide.util.WeakListeners;
47 import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.backgroundTasksPool;
49 import org.sleuthkit.datamodel.Host;
50 import org.sleuthkit.datamodel.OsAccount;
51 import org.sleuthkit.datamodel.OsAccountRealm;
52 import org.sleuthkit.datamodel.SleuthkitCase;
53 import org.sleuthkit.datamodel.Tag;
54 import org.sleuthkit.datamodel.TskCoreException;
55 import org.sleuthkit.datamodel.TskDataException;
56 
60 public final class OsAccounts implements AutopsyVisitableItem {
61 
62  private static final Logger logger = Logger.getLogger(OsAccounts.class.getName());
63  private static final String ICON_PATH = "org/sleuthkit/autopsy/images/os-account.png";
64  private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
65  private static final String REALM_DATA_AVAILABLE_EVENT = "REALM_DATA_AVAILABLE_EVENT";
66 
67  private SleuthkitCase skCase;
68  private final long filteringDSObjId;
69 
70  public OsAccounts(SleuthkitCase skCase) {
71  this(skCase, 0);
72  }
73 
74  public OsAccounts(SleuthkitCase skCase, long objId) {
75  this.skCase = skCase;
76  this.filteringDSObjId = objId;
77  }
78 
79  @Override
80  public <T> T accept(AutopsyItemVisitor<T> visitor) {
81  return visitor.visit(this);
82  }
83 
84  @Messages({
85  "OsAccount_listNode_name=OS Accounts"
86  })
90  public final class OsAccountListNode extends DisplayableItemNode {
91 
95  public OsAccountListNode() {
96  super(Children.create(new OsAccountNodeFactory(), true));
97  setName(Bundle.OsAccount_listNode_name());
98  setDisplayName(Bundle.OsAccount_listNode_name());
99  setIconBaseWithExtension("org/sleuthkit/autopsy/images/os-account.png");
100  }
101 
102  @Override
103  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
104  return visitor.visit(this);
105  }
106 
107  @Override
108  public boolean isLeafTypeNode() {
109  return true;
110  }
111 
112  @Override
113  public String getItemType() {
114  return getClass().getName();
115  }
116  }
117 
122  private final class OsAccountNodeFactory extends ChildFactory.Detachable<OsAccount> {
123 
124  private final PropertyChangeListener listener = new PropertyChangeListener() {
125  @Override
126  public void propertyChange(PropertyChangeEvent evt) {
127  String eventType = evt.getPropertyName();
128  if (eventType.equals(Case.Events.OS_ACCOUNTS_ADDED.toString())
129  || eventType.equals(Case.Events.OS_ACCOUNTS_DELETED.toString())) {
130  refresh(true);
131  } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
132  // case was closed. Remove listeners so that we don't get called with a stale case handle
133  if (evt.getNewValue() == null) {
134  removeNotify();
135  skCase = null;
136  }
137  }
138  }
139  };
140 
141  private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(listener, null);
142 
143  @Override
144  protected void finalize() throws Throwable {
145  super.finalize();
148  }
149 
150  @Override
151  protected void addNotify() {
154  }
155 
156  @Override
157  protected boolean createKeys(List<OsAccount> list) {
158  if (skCase != null) {
159  try {
160  if (filteringDSObjId == 0) {
161  list.addAll(skCase.getOsAccountManager().getOsAccounts());
162  } else {
163  Host host = skCase.getHostManager().getHostByDataSource(skCase.getDataSource(filteringDSObjId));
164  list.addAll(skCase.getOsAccountManager().getOsAccounts(host));
165  }
166  } catch (TskCoreException | TskDataException ex) {
167  logger.log(Level.SEVERE, "Unable to retrieve list of OsAccounts for case", ex);
168  return false;
169  }
170  }
171  return true;
172  }
173 
174  @Override
175  protected Node createNodeForKey(OsAccount key) {
176  return new OsAccountNode(key);
177  }
178  }
179 
183  public static final class OsAccountNode extends AbstractContentNode<OsAccount> {
184 
185  private OsAccount account;
186 
187  private final PropertyChangeListener listener = new PropertyChangeListener() {
188  @Override
189  public void propertyChange(PropertyChangeEvent evt) {
190  if (evt.getPropertyName().equals(Case.Events.OS_ACCOUNTS_UPDATED.name())) {
192  for (OsAccount acct : updateEvent.getOsAccounts()) {
193  if (acct.getId() == account.getId()) {
194  account = acct;
195  updateSheet();
196  break;
197  }
198  }
199  } else if (evt.getPropertyName().equals(REALM_DATA_AVAILABLE_EVENT)) {
200  OsAccountRealm realm = (OsAccountRealm) evt.getNewValue();
201 
202  // Currently only 0 or 1 names are supported, this will need
203  // to be modified if that changes.
204  List<String> realmNames = realm.getRealmNames();
205  if (!realmNames.isEmpty()) {
206  updateSheet(new NodeProperty<>(
207  Bundle.OsAccounts_accountRealmNameProperty_name(),
208  Bundle.OsAccounts_accountRealmNameProperty_displayName(),
209  Bundle.OsAccounts_accountRealmNameProperty_desc(),
210  realmNames.get(0)));
211  }
212  }
213  }
214  };
215 
216  private final PropertyChangeListener weakListener = WeakListeners.propertyChange(listener, null);
217 
223  OsAccountNode(OsAccount account) {
224  super(account);
225  this.account = account;
226 
227  setName(account.getName());
228  setDisplayName(account.getName());
229  setIconBaseWithExtension(ICON_PATH);
230 
232  }
233 
234  @Override
235  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
236  return visitor.visit(this);
237  }
238 
239  @Override
240  public boolean isLeafTypeNode() {
241  return true;
242  }
243 
244  @Override
245  public String getItemType() {
246  return getClass().getName();
247  }
248 
254  OsAccount getOsAccount() {
255  return account;
256  }
257 
258  @Messages({
259  "OsAccounts_accountNameProperty_name=Name",
260  "OsAccounts_accountNameProperty_displayName=Name",
261  "OsAccounts_accountNameProperty_desc=Os Account name",
262  "OsAccounts_accountRealmNameProperty_name=RealmName",
263  "OsAccounts_accountRealmNameProperty_displayName=Realm Name",
264  "OsAccounts_accountRealmNameProperty_desc=OS Account Realm Name",
265  "OsAccounts_createdTimeProperty_name=creationTime",
266  "OsAccounts_createdTimeProperty_displayName=Creation Time",
267  "OsAccounts_createdTimeProperty_desc=OS Account Creation Time",
268  "OsAccounts_loginNameProperty_name=loginName",
269  "OsAccounts_loginNameProperty_displayName=Login Name",
270  "OsAccounts_loginNameProperty_desc=Os Account login name"
271  })
272 
276  void updateSheet() {
277  this.setSheet(createSheet());
278  }
279 
280  @Override
281  protected Sheet createSheet() {
282  Sheet sheet = super.createSheet();
283  Sheet.Set propertiesSet = sheet.get(Sheet.PROPERTIES);
284  if (propertiesSet == null) {
285  propertiesSet = Sheet.createPropertiesSet();
286  sheet.put(propertiesSet);
287  }
288 
289  propertiesSet.put(new NodeProperty<>(
290  Bundle.OsAccounts_accountNameProperty_name(),
291  Bundle.OsAccounts_accountNameProperty_displayName(),
292  Bundle.OsAccounts_accountNameProperty_desc(),
293  account.getName() != null ? account.getName() : ""));
294 
295  Optional<String> optional = account.getLoginName();
296  propertiesSet.put(new NodeProperty<>(
297  Bundle.OsAccounts_loginNameProperty_name(),
298  Bundle.OsAccounts_loginNameProperty_displayName(),
299  Bundle.OsAccounts_loginNameProperty_desc(),
300  optional.isPresent() ? optional.get() : ""));
301  // Fill with empty string, fetch on background task.
302  String realmName = "";
303  propertiesSet.put(new NodeProperty<>(
304  Bundle.OsAccounts_accountRealmNameProperty_name(),
305  Bundle.OsAccounts_accountRealmNameProperty_displayName(),
306  Bundle.OsAccounts_accountRealmNameProperty_desc(),
307  realmName));
308 
309  Optional<Long> creationTimeValue = account.getCreationTime();
310  String timeDisplayStr
311  = creationTimeValue.isPresent() ? TimeZoneUtils.getFormattedTime(creationTimeValue.get()) : "";
312 
313  propertiesSet.put(new NodeProperty<>(
314  Bundle.OsAccounts_createdTimeProperty_name(),
315  Bundle.OsAccounts_createdTimeProperty_displayName(),
316  Bundle.OsAccounts_createdTimeProperty_desc(),
317  timeDisplayStr));
318 
319  backgroundTasksPool.submit(new GetOsAccountRealmTask(new WeakReference<>(this), weakListener));
320 
321  return sheet;
322  }
323 
324  @Override
325  public Action[] getActions(boolean popup) {
326  List<Action> actionsList = new ArrayList<>();
327  actionsList.addAll(Arrays.asList(super.getActions(popup)));
328  actionsList.addAll(DataModelActionsFactory.getActions(account));
329 
330  return actionsList.toArray(new Action[actionsList.size()]);
331  }
332 
333  @Override
334  protected List<Tag> getAllTagsFromDatabase() {
335  throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
336  }
337 
338  @Override
340  return null;
341  }
342 
343  @Override
346  }
347 
348  @Override
349  protected Pair<Long, String> getCountPropertyAndDescription(CorrelationAttributeInstance.Type attributeType, String attributeValue, String defaultDescription) {
350  return null;
351  }
352 
353  @Override
354  public <T> T accept(ContentNodeVisitor<T> visitor) {
355  return visitor.visit(this);
356  }
357 
361  static class GetOsAccountRealmTask implements Runnable {
362 
363  private final WeakReference<OsAccountNode> weakNodeRef;
364  private final PropertyChangeListener listener;
365 
372  GetOsAccountRealmTask(WeakReference<OsAccountNode> weakContentRef, PropertyChangeListener listener) {
373  this.weakNodeRef = weakContentRef;
374  this.listener = listener;
375  }
376 
377  @Override
378  public void run() {
379  OsAccountNode node = weakNodeRef.get();
380  if (node == null) {
381  return;
382  }
383 
384  try {
385  long realmId = node.getOsAccount().getRealmId();
386  OsAccountRealm realm = Case.getCurrentCase().getSleuthkitCase().getOsAccountRealmManager().getRealmByRealmId(realmId);
387 
388  if (listener != null && realm != null) {
389  listener.propertyChange(new PropertyChangeEvent(
390  AutopsyEvent.SourceType.LOCAL.toString(),
392  null, realm));
393  }
394 
395  } catch (TskCoreException ex) {
396  Exceptions.printStackTrace(ex);
397  }
398  }
399  }
400  }
401 }
Pair< Long, String > getCountPropertyAndDescription(CorrelationAttributeInstance.Type attributeType, String attributeValue, String defaultDescription)
static List< Action > getActions(File file, boolean isArtifactSource)
OsAccounts(SleuthkitCase skCase, long objId)
Definition: OsAccounts.java:74
static String getFormattedTime(long epochTime)
static final SimpleDateFormat DATE_FORMATTER
Definition: OsAccounts.java:64
DataResultViewerTable.HasCommentStatus getCommentProperty(List< Tag > tags, CorrelationAttributeInstance attribute)
CorrelationAttributeInstance getCorrelationAttributeInstance()
static final String REALM_DATA_AVAILABLE_EVENT
Definition: OsAccounts.java:65
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:711
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:756

Copyright © 2012-2021 Basis Technology. Generated on: Fri Aug 6 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.