From d4d1c7236b2736e3a4efef5a1956603188c3efc4 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Fri, 30 Nov 2018 10:53:36 +0100 Subject: [PATCH 1/8] modify UI to compile with TimelineEvents that have multiple types --- .../timeline/ShowInTimelineDialog.java | 2 +- .../timeline/explorernodes/EventNode.java | 25 +- .../timeline/ui/detailview/EventNodeBase.java | 2 +- .../detailview/datamodel/DetailViewEvent.java | 3 +- .../datamodel/DetailsViewModel.java | 8 +- .../ui/detailview/datamodel/EventCluster.java | 365 +++++++++--------- .../ui/detailview/datamodel/EventStripe.java | 351 ++++++++--------- .../datamodel/SingleDetailsViewEvent.java | 21 +- .../ui/detailview/tree/BaseTypeTreeItem.java | 21 +- .../detailview/tree/DescriptionTreeItem.java | 4 +- .../timeline/ui/detailview/tree/RootItem.java | 6 +- .../ui/detailview/tree/SubTypeTreeItem.java | 3 +- .../ui/detailview/tree/TreeComparator.java | 3 +- 13 files changed, 420 insertions(+), 394 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ShowInTimelineDialog.java b/Core/src/org/sleuthkit/autopsy/timeline/ShowInTimelineDialog.java index d27bc706c2..4c4417dfe8 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ShowInTimelineDialog.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ShowInTimelineDialog.java @@ -189,7 +189,7 @@ final class ShowInTimelineDialog extends Dialog { unitComboBox.getItems().setAll(SCROLL_BY_UNITS); unitComboBox.getSelectionModel().select(ChronoField.MINUTE_OF_HOUR); - typeColumn.setCellValueFactory(param -> new SimpleObjectProperty<>(param.getValue().getEventType())); + typeColumn.setCellValueFactory(param -> new SimpleObjectProperty<>(EventType.getCommonSuperType(param.getValue().getEventTypes()))); typeColumn.setCellFactory(param -> new TypeTableCell<>()); dateTimeColumn.setCellValueFactory(param -> new SimpleObjectProperty<>(param.getValue().getStartMillis())); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java b/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java index 8b8e6511cb..6e223eaca3 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java @@ -18,12 +18,15 @@ */ package org.sleuthkit.autopsy.timeline.explorernodes; +import com.google.common.collect.Iterables; import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.NoSuchElementException; import java.util.logging.Level; +import static java.util.stream.Collectors.joining; import javax.swing.Action; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; @@ -50,6 +53,7 @@ import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; +import org.sleuthkit.datamodel.timeline.EventType; import org.sleuthkit.datamodel.timeline.TimelineEvent; /** @@ -57,8 +61,6 @@ import org.sleuthkit.datamodel.timeline.TimelineEvent; */ public class EventNode extends DisplayableItemNode { - private static final long serialVersionUID = 1L; - private static final Logger LOGGER = Logger.getLogger(EventNode.class.getName()); private final TimelineEvent event; @@ -66,13 +68,18 @@ public class EventNode extends DisplayableItemNode { EventNode(TimelineEvent event, Content file, BlackboardArtifact artifact) { super(Children.LEAF, Lookups.fixed(event, file, artifact)); this.event = event; - this.setIconBaseWithExtension(EventTypeUtils.getImagePath(event.getEventType())); // NON-NLS + //TODO: filesystem events get the icon of the first type encountered... + EventType evenType = event.getEventTypes().stream().findFirst().orElseThrow(() + -> new NoSuchElementException("Event has no type. " + event.getEventID() + ": " + event.getFullDescription())); + this.setIconBaseWithExtension(EventTypeUtils.getImagePath(evenType)); } EventNode(TimelineEvent event, Content file) { super(Children.LEAF, Lookups.fixed(event, file)); this.event = event; - this.setIconBaseWithExtension(EventTypeUtils.getImagePath(event.getEventType())); // NON-NLS + EventType evenType = event.getEventTypes().stream().findFirst().orElseThrow(() + -> new NoSuchElementException("Event has no type. " + event.getEventID() + ": " + event.getFullDescription())); + this.setIconBaseWithExtension(EventTypeUtils.getImagePath(evenType)); } @Override @@ -94,9 +101,11 @@ public class EventNode extends DisplayableItemNode { properties.put(new NodeProperty<>("icon", Bundle.NodeProperty_displayName_icon(), "icon", true)); // NON-NLS //gets overridden with icon properties.put(new TimeProperty("time", Bundle.NodeProperty_displayName_dateTime(), "time ", getDateTimeString()));// NON-NLS properties.put(new NodeProperty<>("description", Bundle.NodeProperty_displayName_description(), "description", event.getFullDescription())); // NON-NLS - properties.put(new NodeProperty<>("eventBaseType", Bundle.NodeProperty_displayName_baseType(), "base type", event.getEventType().getSuperType().getDisplayName())); // NON-NLS - properties.put(new NodeProperty<>("eventSubType", Bundle.NodeProperty_displayName_subType(), "sub type", event.getEventType().getDisplayName())); // NON-NLS - + // properties.put(new NodeProperty<>("eventBaseType", Bundle.NodeProperty_displayName_baseType(), "base type", event.getEventType().getSuperType().getDisplayName())); // NON-NLS + // todo: change filesystem events to use MACB notation. + properties.put(new NodeProperty<>("eventSubType", Bundle.NodeProperty_displayName_subType(), "sub type", + event.getEventTypes().stream().map(EventType::getDisplayName).collect(joining(", ")))); // NON-NLS + return sheet; } @@ -225,7 +234,7 @@ public class EventNode extends DisplayableItemNode { * Look up the event by id and creata an EventNode with the * appropriate data in the lookup. */ - final TimelineEvent eventById = eventsModel.getEventById(eventID); + final TimelineEvent eventById = eventsModel.getEventById(eventID); Content file = sleuthkitCase.getContentById(eventById.getFileObjID()); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventNodeBase.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventNodeBase.java index b8b17e8089..603b5106f4 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventNodeBase.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventNodeBase.java @@ -351,7 +351,7 @@ public abstract class EventNodeBase extends StackP } final EventType getEventType() { - return tlEvent.getEventType(); + return EventType.getCommonSuperType(tlEvent.getEventTypes()); } long getStartMillis() { diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/DetailViewEvent.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/DetailViewEvent.java index 455260a619..b47f30163e 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/DetailViewEvent.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/DetailViewEvent.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.timeline.ui.detailview.datamodel; +import com.google.common.collect.ImmutableCollection; import java.util.Optional; import java.util.Set; import java.util.SortedSet; @@ -86,7 +87,7 @@ public interface DetailViewEvent { * * @return the EventType of this event. */ - EventType getEventType(); + ImmutableCollection getEventTypes(); /** * Get the start time of this event as milliseconds from the Unix Epoch. diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/DetailsViewModel.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/DetailsViewModel.java index 99e2c8282e..ca5d55093c 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/DetailsViewModel.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/DetailsViewModel.java @@ -27,6 +27,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.time.temporal.ChronoUnit; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; @@ -211,7 +212,8 @@ final public class DetailsViewModel { List hashHits = unGroupConcat(resultSet.getString("hash_hits"), Long::valueOf); //NON-NLS List tagged = unGroupConcat(resultSet.getString("taggeds"), Long::valueOf); //NON-NLS - return new EventCluster(interval, eventType, eventIDs, hashHits, tagged, description, descriptionLOD); + //TODO: address singleton type, instead of potential multiple types + return new EventCluster(interval, Collections.singleton(eventType), eventIDs, hashHits, tagged, description, descriptionLOD); } /** @@ -233,7 +235,7 @@ final public class DetailsViewModel { Map> typeMap = new HashMap<>(); for (EventCluster aggregateEvent : preMergedEvents) { - typeMap.computeIfAbsent(aggregateEvent.getEventType(), eventType -> HashMultimap.create()) + typeMap.computeIfAbsent(EventType.getCommonSuperType(aggregateEvent.getEventTypes()), eventType -> HashMultimap.create()) .put(aggregateEvent.getDescription(), aggregateEvent); } //result list to return @@ -271,7 +273,7 @@ final public class DetailsViewModel { Map, EventStripe> stripeDescMap = new HashMap<>(); for (EventCluster eventCluster : aggEvents) { - stripeDescMap.merge(ImmutablePair.of(eventCluster.getEventType(), eventCluster.getDescription()), + stripeDescMap.merge(ImmutablePair.of(EventType.getCommonSuperType(eventCluster.getEventTypes()), eventCluster.getDescription()), new EventStripe(eventCluster), EventStripe::merge); } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventCluster.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventCluster.java index 7cc4c172bd..7f9c378d7a 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventCluster.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventCluster.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.timeline.ui.detailview.datamodel; +import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Sets; @@ -25,6 +26,7 @@ import java.util.Collection; import java.util.Comparator; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.SortedSet; import org.joda.time.Interval; import org.sleuthkit.autopsy.timeline.utils.IntervalUtils; @@ -38,214 +40,215 @@ import org.sleuthkit.datamodel.timeline.EventType; */ public class EventCluster implements MultiEvent { - final private EventStripe parent; + final private EventStripe parent; - /** - * the smallest time interval containing all the clustered events - */ - final private Interval span; + /** + * the smallest time interval containing all the clustered events + */ + final private Interval span; - /** - * the type of all the clustered events - */ - final private EventType type; + /** + * the type of all the clustered events + */ + final private ImmutableCollection types; - /** - * the common description of all the clustered events - */ - final private String description; + /** + * the common description of all the clustered events + */ + final private String description; - /** - * the description level of detail that the events were clustered at. - */ - private final DescriptionLoD lod; + /** + * the description level of detail that the events were clustered at. + */ + private final DescriptionLoD lod; - /** - * the set of ids of the clustered events - */ - final private ImmutableSet eventIDs; + /** + * the set of ids of the clustered events + */ + final private ImmutableSet eventIDs; - /** - * the ids of the subset of clustered events that have at least one tag - * applied to them - */ - private final ImmutableSet tagged; + /** + * the ids of the subset of clustered events that have at least one tag + * applied to them + */ + private final ImmutableSet tagged; - /** - * the ids of the subset of clustered events that have at least one hash set - * hit - */ - private final ImmutableSet hashHits; + /** + * the ids of the subset of clustered events that have at least one hash set + * hit + */ + private final ImmutableSet hashHits; - /** - * merge two event clusters into one new event cluster. - * - * @param cluster1 - * @param cluster2 - * - * @return a new event cluster that is the result of merging the given - * events clusters - */ - public static EventCluster merge(EventCluster cluster1, EventCluster cluster2) { - if (cluster1.getEventType() != cluster2.getEventType()) { - throw new IllegalArgumentException("event clusters are not compatible: they have different types"); - } + /** + * merge two event clusters into one new event cluster. + * + * @param cluster1 + * @param cluster2 + * + * @return a new event cluster that is the result of merging the given + * events clusters + */ + public static EventCluster merge(EventCluster cluster1, EventCluster cluster2) { +// if (cluster1.getEventType() != cluster2.getEventType()) { +// throw new IllegalArgumentException("event clusters are not compatible: they have different types"); +// } - if (!cluster1.getDescription().equals(cluster2.getDescription())) { - throw new IllegalArgumentException("event clusters are not compatible: they have different descriptions"); - } - Sets.SetView idsUnion - = Sets.union(cluster1.getEventIDs(), cluster2.getEventIDs()); - Sets.SetView hashHitsUnion - = Sets.union(cluster1.getEventIDsWithHashHits(), cluster2.getEventIDsWithHashHits()); - Sets.SetView taggedUnion - = Sets.union(cluster1.getEventIDsWithTags(), cluster2.getEventIDsWithTags()); + if (!cluster1.getDescription().equals(cluster2.getDescription())) { + throw new IllegalArgumentException("event clusters are not compatible: they have different descriptions"); + } + Sets.SetView idsUnion + = Sets.union(cluster1.getEventIDs(), cluster2.getEventIDs()); + Sets.SetView hashHitsUnion + = Sets.union(cluster1.getEventIDsWithHashHits(), cluster2.getEventIDsWithHashHits()); + Sets.SetView taggedUnion + = Sets.union(cluster1.getEventIDsWithTags(), cluster2.getEventIDsWithTags()); - return new EventCluster(IntervalUtils.span(cluster1.span, cluster2.span), - cluster1.getEventType(), idsUnion, hashHitsUnion, taggedUnion, - cluster1.getDescription(), cluster1.lod); - } + Set typesUnion = ImmutableSet.builder().addAll(cluster1.getEventTypes()).addAll(cluster2.getEventTypes()).build(); + return new EventCluster(IntervalUtils.span(cluster1.span, cluster2.span), + typesUnion, idsUnion, hashHitsUnion, taggedUnion, + cluster1.getDescription(), cluster1.lod); + } - private EventCluster(Interval spanningInterval, EventType type, Collection eventIDs, - Collection hashHits, Collection tagged, String description, DescriptionLoD lod, - EventStripe parent) { + private EventCluster(Interval spanningInterval, Collection types, Collection eventIDs, + Collection hashHits, Collection tagged, String description, DescriptionLoD lod, + EventStripe parent) { - this.span = spanningInterval; - this.type = type; - this.hashHits = ImmutableSet.copyOf(hashHits); - this.tagged = ImmutableSet.copyOf(tagged); - this.description = description; - this.eventIDs = ImmutableSet.copyOf(eventIDs); - this.lod = lod; - this.parent = parent; - } + this.span = spanningInterval; + this.types = ImmutableSet.copyOf( types); + this.hashHits = ImmutableSet.copyOf(hashHits); + this.tagged = ImmutableSet.copyOf(tagged); + this.description = description; + this.eventIDs = ImmutableSet.copyOf(eventIDs); + this.lod = lod; + this.parent = parent; + } - public EventCluster(Interval spanningInterval, EventType type, Collection eventIDs, - Collection hashHits, Collection tagged, String description, DescriptionLoD lod) { - this(spanningInterval, type, eventIDs, hashHits, tagged, description, lod, null); - } + public EventCluster(Interval spanningInterval, Collection types, Collection eventIDs, + Collection hashHits, Collection tagged, String description, DescriptionLoD lod) { + this(spanningInterval, types, eventIDs, hashHits, tagged, description, lod, null); + } - /** - * get the EventStripe (if any) that contains this cluster - * - * @return an Optional containg the parent stripe of this cluster, or is - * empty if the cluster has no parent set. - */ - @Override - public Optional getParent() { - return Optional.ofNullable(parent); - } + /** + * get the EventStripe (if any) that contains this cluster + * + * @return an Optional containg the parent stripe of this cluster, or is + * empty if the cluster has no parent set. + */ + @Override + public Optional getParent() { + return Optional.ofNullable(parent); + } - /** - * get the EventStripe (if any) that contains this cluster - * - * @return an Optional containg the parent stripe of this cluster, or is - * empty if the cluster has no parent set. - */ - @Override - public Optional getParentStripe() { - //since this clusters parent must be an event stripe just delegate to getParent(); - return getParent(); - } + /** + * get the EventStripe (if any) that contains this cluster + * + * @return an Optional containg the parent stripe of this cluster, or is + * empty if the cluster has no parent set. + */ + @Override + public Optional getParentStripe() { + //since this clusters parent must be an event stripe just delegate to getParent(); + return getParent(); + } - public Interval getSpan() { - return span; - } + public Interval getSpan() { + return span; + } - @Override - public long getStartMillis() { - return span.getStartMillis(); - } + @Override + public long getStartMillis() { + return span.getStartMillis(); + } - @Override - public long getEndMillis() { - return span.getEndMillis(); - } + @Override + public long getEndMillis() { + return span.getEndMillis(); + } - @Override - public ImmutableSet getEventIDs() { - return eventIDs; - } + @Override + public ImmutableSet getEventIDs() { + return eventIDs; + } - @Override - public ImmutableSet getEventIDsWithHashHits() { - return hashHits; - } + @Override + public ImmutableSet getEventIDsWithHashHits() { + return hashHits; + } - @Override - public ImmutableSet getEventIDsWithTags() { - return tagged; - } + @Override + public ImmutableSet getEventIDsWithTags() { + return tagged; + } - @Override - public String getDescription() { - return description; - } + @Override + public String getDescription() { + return description; + } - @Override - public EventType getEventType() { - return type; - } + @Override + public ImmutableCollection getEventTypes() { + return types; + } - @Override - public DescriptionLoD getDescriptionLoD() { - return lod; - } + @Override + public DescriptionLoD getDescriptionLoD() { + return lod; + } - /** - * return a new EventCluster identical to this one, except with the given - * EventBundle as the parent. - * - * @param parent - * - * @return a new EventCluster identical to this one, except with the given - * EventBundle as the parent. - */ - public EventCluster withParent(EventStripe parent) { - return new EventCluster(span, type, eventIDs, hashHits, tagged, description, lod, parent); - } + /** + * return a new EventCluster identical to this one, except with the given + * EventBundle as the parent. + * + * @param parent + * + * @return a new EventCluster identical to this one, except with the given + * EventBundle as the parent. + */ + public EventCluster withParent(EventStripe parent) { + return new EventCluster(span, types, eventIDs, hashHits, tagged, description, lod, parent); + } - @Override - public SortedSet getClusters() { - return ImmutableSortedSet.orderedBy(Comparator.comparing(EventCluster::getStartMillis)).add(this).build(); - } + @Override + public SortedSet getClusters() { + return ImmutableSortedSet.orderedBy(Comparator.comparing(EventCluster::getStartMillis)).add(this).build(); + } - @Override - public String toString() { - return "EventCluster{" + "description=" + description + ", eventIDs=" + eventIDs.size() + '}'; - } + @Override + public String toString() { + return "EventCluster{" + "description=" + description + ", eventIDs=" + eventIDs.size() + '}'; + } - @Override - public int hashCode() { - int hash = 7; - hash = 23 * hash + Objects.hashCode(this.type); - hash = 23 * hash + Objects.hashCode(this.description); - hash = 23 * hash + Objects.hashCode(this.lod); - hash = 23 * hash + Objects.hashCode(this.eventIDs); - return hash; - } + @Override + public int hashCode() { + int hash = 7; + hash = 23 * hash + Objects.hashCode(this.types); + hash = 23 * hash + Objects.hashCode(this.description); + hash = 23 * hash + Objects.hashCode(this.lod); + hash = 23 * hash + Objects.hashCode(this.eventIDs); + return hash; + } - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final EventCluster other = (EventCluster) obj; - if (!Objects.equals(this.description, other.description)) { - return false; - } - if (!Objects.equals(this.type, other.type)) { - return false; - } - if (this.lod != other.lod) { - return false; - } - return Objects.equals(this.eventIDs, other.eventIDs); - } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final EventCluster other = (EventCluster) obj; + if (!Objects.equals(this.description, other.description)) { + return false; + } + if (!Objects.equals(this.types, other.types)) { + return false; + } + if (this.lod != other.lod) { + return false; + } + return Objects.equals(this.eventIDs, other.eventIDs); + } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventStripe.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventStripe.java index 8d113c73bf..c96bfcff82 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventStripe.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventStripe.java @@ -19,8 +19,10 @@ package org.sleuthkit.autopsy.timeline.ui.detailview.datamodel; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; +import java.util.Collection; import java.util.Comparator; import java.util.Objects; import java.util.Optional; @@ -34,206 +36,209 @@ import org.sleuthkit.datamodel.timeline.EventType; */ public final class EventStripe implements MultiEvent { - private final EventCluster parent; + private final EventCluster parent; - private final ImmutableSortedSet clusters; + private final ImmutableSortedSet clusters; - /** - * the type of all the events - */ - private final EventType type; + /** + * the type of all the events + */ + private final ImmutableCollection types; - /** - * the common description of all the events - */ - private final String description; + /** + * the common description of all the events + */ + private final String description; - /** - * the description level of detail that the events were clustered at. - */ - private final DescriptionLoD lod; + /** + * the description level of detail that the events were clustered at. + */ + private final DescriptionLoD lod; - /** - * the set of ids of the events - */ - private final ImmutableSet eventIDs; + /** + * the set of ids of the events + */ + private final ImmutableSet eventIDs; - /** - * the ids of the subset of events that have at least one tag applied to - * them - */ - private final ImmutableSet tagged; + /** + * the ids of the subset of events that have at least one tag applied to + * them + */ + private final ImmutableSet tagged; - /** - * the ids of the subset of events that have at least one hash set hit - */ - private final ImmutableSet hashHits; + /** + * the ids of the subset of events that have at least one hash set hit + */ + private final ImmutableSet hashHits; - public static EventStripe merge(EventStripe u, EventStripe v) { //NOPMD - Preconditions.checkNotNull(u); - Preconditions.checkNotNull(v); - Preconditions.checkArgument(Objects.equals(u.description, v.description)); - Preconditions.checkArgument(Objects.equals(u.lod, v.lod)); - Preconditions.checkArgument(Objects.equals(u.type, v.type)); - Preconditions.checkArgument(Objects.equals(u.parent, v.parent)); - return new EventStripe(u, v); - } + public static EventStripe merge(EventStripe u, EventStripe v) { //NOPMD + Preconditions.checkNotNull(u); + Preconditions.checkNotNull(v); + Preconditions.checkArgument(Objects.equals(u.description, v.description)); + Preconditions.checkArgument(Objects.equals(u.lod, v.lod)); + Preconditions.checkArgument(Objects.equals(u.types, v.types)); + Preconditions.checkArgument(Objects.equals(u.parent, v.parent)); + return new EventStripe(u, v); + } - public EventStripe withParent(EventCluster parent) { - if (Objects.nonNull(this.parent)) { - throw new IllegalStateException("Event Stripe already has a parent!"); - } - return new EventStripe(parent, this.type, this.description, this.lod, clusters, eventIDs, tagged, hashHits); - } + public EventStripe withParent(EventCluster parent) { + if (Objects.nonNull(this.parent)) { + throw new IllegalStateException("Event Stripe already has a parent!"); + } + return new EventStripe(parent, this.types, this.description, this.lod, clusters, eventIDs, tagged, hashHits); + } - private EventStripe(EventCluster parent, EventType type, String description, DescriptionLoD lod, SortedSet clusters, ImmutableSet eventIDs, ImmutableSet tagged, ImmutableSet hashHits) { - this.parent = parent; - this.type = type; - this.description = description; - this.lod = lod; - this.clusters = ImmutableSortedSet.copyOf(Comparator.comparing(EventCluster::getStartMillis), clusters); + private EventStripe(EventCluster parent, Collection types, String description, DescriptionLoD lod, SortedSet clusters, ImmutableSet eventIDs, ImmutableSet tagged, ImmutableSet hashHits) { + this.parent = parent; + this.types = ImmutableSet.copyOf(types); + this.description = description; + this.lod = lod; + this.clusters = ImmutableSortedSet.copyOf(Comparator.comparing(EventCluster::getStartMillis), clusters); - this.eventIDs = eventIDs; - this.tagged = tagged; - this.hashHits = hashHits; - } + this.eventIDs = eventIDs; + this.tagged = tagged; + this.hashHits = hashHits; + } - public EventStripe(EventCluster cluster) { - this.clusters = ImmutableSortedSet.orderedBy(Comparator.comparing(EventCluster::getStartMillis)) - .add(cluster.withParent(this)).build(); + public EventStripe(EventCluster cluster) { + this.clusters = ImmutableSortedSet.orderedBy(Comparator.comparing(EventCluster::getStartMillis)) + .add(cluster.withParent(this)).build(); - type = cluster.getEventType(); - description = cluster.getDescription(); - lod = cluster.getDescriptionLoD(); - eventIDs = cluster.getEventIDs(); - tagged = cluster.getEventIDsWithTags(); - hashHits = cluster.getEventIDsWithHashHits(); - this.parent = null; - } + types = ImmutableSet.copyOf(cluster.getEventTypes()); + description = cluster.getDescription(); + lod = cluster.getDescriptionLoD(); + eventIDs = cluster.getEventIDs(); + tagged = cluster.getEventIDsWithTags(); + hashHits = cluster.getEventIDsWithHashHits(); + this.parent = null; + } - private EventStripe(EventStripe u, EventStripe v) { //NOPMD - clusters = ImmutableSortedSet.orderedBy(Comparator.comparing(EventCluster::getStartMillis)) - .addAll(u.getClusters()) - .addAll(v.getClusters()) - .build(); + private EventStripe(EventStripe u, EventStripe v) { //NOPMD + clusters = ImmutableSortedSet.orderedBy(Comparator.comparing(EventCluster::getStartMillis)) + .addAll(u.getClusters()) + .addAll(v.getClusters()) + .build(); - type = u.getEventType(); - description = u.getDescription(); - lod = u.getDescriptionLoD(); - eventIDs = ImmutableSet.builder() - .addAll(u.getEventIDs()) - .addAll(v.getEventIDs()) - .build(); - tagged = ImmutableSet.builder() - .addAll(u.getEventIDsWithTags()) - .addAll(v.getEventIDsWithTags()) - .build(); - hashHits = ImmutableSet.builder() - .addAll(u.getEventIDsWithHashHits()) - .addAll(v.getEventIDsWithHashHits()) - .build(); - parent = u.getParent().orElse(v.getParent().orElse(null)); - } + types = ImmutableSet.builder() + .addAll(u.getEventTypes()) + .addAll(v.getEventTypes()) + .build(); + description = u.getDescription(); + lod = u.getDescriptionLoD(); + eventIDs = ImmutableSet.builder() + .addAll(u.getEventIDs()) + .addAll(v.getEventIDs()) + .build(); + tagged = ImmutableSet.builder() + .addAll(u.getEventIDsWithTags()) + .addAll(v.getEventIDsWithTags()) + .build(); + hashHits = ImmutableSet.builder() + .addAll(u.getEventIDsWithHashHits()) + .addAll(v.getEventIDsWithHashHits()) + .build(); + parent = u.getParent().orElse(v.getParent().orElse(null)); + } - @Override - public Optional getParent() { - return Optional.ofNullable(parent); - } + @Override + public Optional getParent() { + return Optional.ofNullable(parent); + } - @Override - public Optional getParentStripe() { - if (getParent().isPresent()) { - return getParent().get().getParent(); - } else { - return Optional.empty(); - } - } + @Override + public Optional getParentStripe() { + if (getParent().isPresent()) { + return getParent().get().getParent(); + } else { + return Optional.empty(); + } + } - @Override - public String getDescription() { - return description; - } + @Override + public String getDescription() { + return description; + } - @Override - public EventType getEventType() { - return type; - } + @Override + public ImmutableCollection getEventTypes() { + return types; + } - @Override - public DescriptionLoD getDescriptionLoD() { - return lod; - } + @Override + public DescriptionLoD getDescriptionLoD() { + return lod; + } - @Override - public ImmutableSet getEventIDs() { - return eventIDs; - } + @Override + public ImmutableSet getEventIDs() { + return eventIDs; + } - @Override - public ImmutableSet getEventIDsWithHashHits() { - return hashHits; - } + @Override + public ImmutableSet getEventIDsWithHashHits() { + return hashHits; + } - @Override - public ImmutableSet getEventIDsWithTags() { - return tagged; - } + @Override + public ImmutableSet getEventIDsWithTags() { + return tagged; + } - @Override - public long getStartMillis() { - return clusters.first().getStartMillis(); - } + @Override + public long getStartMillis() { + return clusters.first().getStartMillis(); + } - @Override - public long getEndMillis() { - return clusters.last().getEndMillis(); - } + @Override + public long getEndMillis() { + return clusters.last().getEndMillis(); + } - @Override - public ImmutableSortedSet< EventCluster> getClusters() { - return clusters; - } + @Override + public ImmutableSortedSet< EventCluster> getClusters() { + return clusters; + } - @Override - public String toString() { - return "EventStripe{" + "description=" + description + ", eventIDs=" + (Objects.isNull(eventIDs) ? 0 : eventIDs.size()) + '}'; //NON-NLS - } + @Override + public String toString() { + return "EventStripe{" + "description=" + description + ", eventIDs=" + (Objects.isNull(eventIDs) ? 0 : eventIDs.size()) + '}'; //NON-NLS + } - @Override - public int hashCode() { - int hash = 3; - hash = 79 * hash + Objects.hashCode(this.clusters); - hash = 79 * hash + Objects.hashCode(this.type); - hash = 79 * hash + Objects.hashCode(this.description); - hash = 79 * hash + Objects.hashCode(this.lod); - hash = 79 * hash + Objects.hashCode(this.eventIDs); - return hash; - } + @Override + public int hashCode() { + int hash = 3; + hash = 79 * hash + Objects.hashCode(this.clusters); + hash = 79 * hash + Objects.hashCode(this.types); + hash = 79 * hash + Objects.hashCode(this.description); + hash = 79 * hash + Objects.hashCode(this.lod); + hash = 79 * hash + Objects.hashCode(this.eventIDs); + return hash; + } - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final EventStripe other = (EventStripe) obj; - if (!Objects.equals(this.description, other.description)) { - return false; - } - if (!Objects.equals(this.clusters, other.clusters)) { - return false; - } - if (!Objects.equals(this.type, other.type)) { - return false; - } - if (this.lod != other.lod) { - return false; - } - return Objects.equals(this.eventIDs, other.eventIDs); - } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final EventStripe other = (EventStripe) obj; + if (!Objects.equals(this.description, other.description)) { + return false; + } + if (!Objects.equals(this.clusters, other.clusters)) { + return false; + } + if (!Objects.equals(this.types, other.types)) { + return false; + } + if (this.lod != other.lod) { + return false; + } + return Objects.equals(this.eventIDs, other.eventIDs); + } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/SingleDetailsViewEvent.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/SingleDetailsViewEvent.java index ec962dedbb..ab2aef8d24 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/SingleDetailsViewEvent.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/SingleDetailsViewEvent.java @@ -18,8 +18,11 @@ */ package org.sleuthkit.autopsy.timeline.ui.detailview.datamodel; +import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Optional; @@ -59,7 +62,7 @@ public class SingleDetailsViewEvent implements DetailViewEvent { /** * The type of this event. */ - private final EventType type; + private final ImmutableCollection types; /** * The three descriptions (full, med, short) stored in a map, keyed by @@ -91,20 +94,20 @@ public class SingleDetailsViewEvent implements DetailViewEvent { * @param fileObjId Object Id of file (could be a data source) that event is associated with * @param artifactID * @param time - * @param type + * @param types * @param fullDescription * @param medDescription * @param shortDescription * @param hashHit * @param tagged */ - public SingleDetailsViewEvent(long eventID, long dataSourceObjId, long fileObjId, Long artifactID, long time, EventType type, String fullDescription, String medDescription, String shortDescription, boolean hashHit, boolean tagged) { + public SingleDetailsViewEvent(long eventID, long dataSourceObjId, long fileObjId, Long artifactID, long time, Collection types, String fullDescription, String medDescription, String shortDescription, boolean hashHit, boolean tagged) { this.eventID = eventID; this.dataSourceObjId = dataSourceObjId; this.fileObjId = fileObjId; this.artifactID = Long.valueOf(0).equals(artifactID) ? null : artifactID; this.time = time; - this.type = type; + this.types = ImmutableSet.copyOf( types); descriptions = ImmutableMap.of(DescriptionLoD.FULL, fullDescription, DescriptionLoD.MEDIUM, medDescription, DescriptionLoD.SHORT, shortDescription); @@ -118,7 +121,7 @@ public class SingleDetailsViewEvent implements DetailViewEvent { singleEvent.getFileObjID(), singleEvent.getArtifactID().orElse(null), singleEvent.getTime(), - singleEvent.getEventType(), + singleEvent.getEventTypes(), singleEvent.getFullDescription(), singleEvent.getMedDescription(), singleEvent.getShortDescription(), @@ -136,7 +139,7 @@ public class SingleDetailsViewEvent implements DetailViewEvent { * with the given parent. */ public SingleDetailsViewEvent withParent(MultiEvent newParent) { - SingleDetailsViewEvent singleEvent = new SingleDetailsViewEvent(eventID, dataSourceObjId, fileObjId, artifactID, time, type, descriptions.get(DescriptionLoD.FULL), descriptions.get(DescriptionLoD.MEDIUM), descriptions.get(DescriptionLoD.SHORT), hashHit, tagged); + SingleDetailsViewEvent singleEvent = new SingleDetailsViewEvent(eventID, dataSourceObjId, fileObjId, artifactID, time, types, descriptions.get(DescriptionLoD.FULL), descriptions.get(DescriptionLoD.MEDIUM), descriptions.get(DescriptionLoD.SHORT), hashHit, tagged); singleEvent.parent = newParent; return singleEvent; } @@ -200,8 +203,8 @@ public class SingleDetailsViewEvent implements DetailViewEvent { } @Override - public EventType getEventType() { - return type; + public ImmutableCollection getEventTypes() { + return types; } /** @@ -299,7 +302,7 @@ public class SingleDetailsViewEvent implements DetailViewEvent { @Override public SortedSet getClusters() { - EventCluster eventCluster = new EventCluster(new Interval(time * 1000, time * 1000), type, getEventIDs(), getEventIDsWithHashHits(), getEventIDsWithTags(), getFullDescription(), DescriptionLoD.FULL); + EventCluster eventCluster = new EventCluster(new Interval(time * 1000, time * 1000), types, getEventIDs(), getEventIDsWithHashHits(), getEventIDsWithTags(), getFullDescription(), DescriptionLoD.FULL); return ImmutableSortedSet.orderedBy(Comparator.comparing(EventCluster::getStartMillis)).add(eventCluster).build(); } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/BaseTypeTreeItem.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/BaseTypeTreeItem.java index 9e364afd35..64092a0913 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/BaseTypeTreeItem.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/BaseTypeTreeItem.java @@ -26,6 +26,7 @@ import java.util.function.Supplier; import javafx.scene.control.TreeItem; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.timeline.ui.detailview.datamodel.DetailViewEvent; +import org.sleuthkit.datamodel.timeline.EventType; import org.sleuthkit.datamodel.timeline.EventTypeZoomLevel; /** @@ -47,29 +48,29 @@ class BaseTypeTreeItem extends EventTypeTreeItem { * this tree item */ BaseTypeTreeItem(DetailViewEvent event, Comparator> comparator) { - super(event.getEventType().getBaseType(), comparator); + super(EventType.getCommonSuperType(event.getEventTypes()).getBaseType(), comparator); } - + @ThreadConfined(type = ThreadConfined.ThreadType.JFX) @Override public void insert(List path) { DetailViewEvent head = path.get(0); - + Supplier< EventsTreeItem> treeItemConstructor; String descriptionKey; /* * if the stripe and this tree item have the same type, create a * description tree item, else create a sub-type tree item */ - if (head.getEventType().getZoomLevel() == EventTypeZoomLevel.SUB_TYPE) { - descriptionKey = head.getEventType().getDisplayName(); + if (EventType.getCommonSuperType(head.getEventTypes()).getZoomLevel() == EventTypeZoomLevel.SUB_TYPE) { + descriptionKey = EventType.getCommonSuperType(head.getEventTypes()).getDisplayName(); treeItemConstructor = () -> configureNewTreeItem(new SubTypeTreeItem(head, getComparator())); } else { descriptionKey = head.getDescription(); DetailViewEvent stripe = path.remove(0); //remove head of list if we are going straight to description treeItemConstructor = () -> configureNewTreeItem(new DescriptionTreeItem(stripe, getComparator())); } - + EventsTreeItem treeItem = childMap.computeIfAbsent(descriptionKey, key -> treeItemConstructor.get()); //insert (rest of) path in to new treeItem @@ -77,18 +78,18 @@ class BaseTypeTreeItem extends EventTypeTreeItem { treeItem.insert(path); } } - + @Override void remove(List path) { DetailViewEvent head = path.get(0); - + EventsTreeItem descTreeItem; /* * if the stripe and this tree item have the same type, get the child * item keyed on event type, else keyed on description. */ - if (head.getEventType().getZoomLevel() == EventTypeZoomLevel.SUB_TYPE) { - descTreeItem = childMap.get(head.getEventType().getDisplayName()); + if (EventType.getCommonSuperType(head.getEventTypes()).getZoomLevel() == EventTypeZoomLevel.SUB_TYPE) { + descTreeItem = childMap.get(EventType.getCommonSuperType(head.getEventTypes()).getDisplayName()); } else { path.remove(0); //remove head of list if we are going straight to description descTreeItem = childMap.get(head.getDescription()); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/DescriptionTreeItem.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/DescriptionTreeItem.java index 0540b8d2be..40024ff967 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/DescriptionTreeItem.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/DescriptionTreeItem.java @@ -102,7 +102,7 @@ class DescriptionTreeItem extends EventsTreeItem { @Override public EventsTreeItem findTreeItemForEvent(DetailViewEvent event) { - if (getValue().getEventType() == event.getEventType() + if (EventType.getCommonSuperType(getValue().getEventTypes()) == EventType.getCommonSuperType(event.getEventTypes()) && getValue().getDescription().equals(event.getDescription())) { //if this tree item match the given event, return this. return this; @@ -127,6 +127,6 @@ class DescriptionTreeItem extends EventsTreeItem { @Override EventType getEventType() { - return getValue().getEventType(); + return EventType.getCommonSuperType(getValue().getEventTypes()); } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/RootItem.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/RootItem.java index b9ebfd5a8f..58e460a54f 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/RootItem.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/RootItem.java @@ -85,7 +85,7 @@ class RootItem extends EventsTreeItem { @Override void remove(List path) { DetailViewEvent event = path.get(0); - BaseTypeTreeItem typeTreeItem = childMap.get(event.getEventType().getBaseType()); + BaseTypeTreeItem typeTreeItem = childMap.get(EventType.getCommonSuperType(event.getEventTypes()).getBaseType()); //remove the path from the child if (typeTreeItem != null) { @@ -93,7 +93,7 @@ class RootItem extends EventsTreeItem { //if the child has no children remove it also if (typeTreeItem.getChildren().isEmpty()) { - childMap.remove(event.getEventType().getBaseType()); + childMap.remove(EventType.getCommonSuperType(event.getEventTypes()).getBaseType()); getChildren().remove(typeTreeItem); } } @@ -102,7 +102,7 @@ class RootItem extends EventsTreeItem { @Override void insert(List path) { DetailViewEvent event = path.get(0); - BaseTypeTreeItem treeItem = childMap.computeIfAbsent(event.getEventType().getBaseType(), + BaseTypeTreeItem treeItem = childMap.computeIfAbsent(EventType.getCommonSuperType(event.getEventTypes()).getBaseType(), baseType -> configureNewTreeItem(new BaseTypeTreeItem(event, getComparator())) ); treeItem.insert(path); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/SubTypeTreeItem.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/SubTypeTreeItem.java index 6d9afbc2f8..20e8cf4ccb 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/SubTypeTreeItem.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/SubTypeTreeItem.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; import javafx.scene.control.TreeItem; import org.sleuthkit.autopsy.timeline.ui.detailview.datamodel.DetailViewEvent; +import org.sleuthkit.datamodel.timeline.EventType; /** * EventTreeItem for sub event types @@ -43,7 +44,7 @@ public class SubTypeTreeItem extends EventTypeTreeItem { * this tree item */ SubTypeTreeItem(DetailViewEvent event, Comparator> comparator) { - super(event.getEventType(), comparator); + super(EventType.getCommonSuperType(event.getEventTypes()), comparator); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/TreeComparator.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/TreeComparator.java index 8ec04e40d5..d35eb6863c 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/TreeComparator.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/TreeComparator.java @@ -22,6 +22,7 @@ import java.util.Comparator; import javafx.scene.control.TreeItem; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.timeline.ui.detailview.datamodel.DetailViewEvent; +import org.sleuthkit.datamodel.timeline.EventType; /** * Comparators of TreeItems: these are the ways the EventsTree can be sorted. @@ -46,7 +47,7 @@ enum TreeComparator implements Comparator> { Type(Bundle.TreeComparator_Type_displayName()) { @Override public int compare(TreeItem item1, TreeItem item2) { - return item1.getValue().getEventType().compareTo(item2.getValue().getEventType()); + return EventType.getCommonSuperType(item1.getValue().getEventTypes()).compareTo(EventType.getCommonSuperType(item2.getValue().getEventTypes())); } }; From 4aba0391d682658b6b5644bc441b0af619dcd751 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 3 Jan 2019 17:59:57 +0100 Subject: [PATCH 2/8] fix bugs --- .../autopsy/timeline/ShowInTimelineDialog.java | 1 - .../autopsy/timeline/explorernodes/EventNode.java | 7 +++---- .../ui/detailview/datamodel/DetailsViewModel.java | 4 ++-- .../timeline/ui/detailview/tree/BaseTypeTreeItem.java | 10 +++++----- .../timeline/ui/listvew/datamodel/ListViewModel.java | 2 +- 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ShowInTimelineDialog.java b/Core/src/org/sleuthkit/autopsy/timeline/ShowInTimelineDialog.java index fa1d6e04c0..fb4828e0b8 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ShowInTimelineDialog.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ShowInTimelineDialog.java @@ -126,7 +126,6 @@ final class ShowInTimelineDialog extends Dialog { @NbBundle.Messages({ "ShowInTimelineDialog.amountValidator.message=The entered amount must only contain digits."}) private ShowInTimelineDialog(TimeLineController controller, List eventIDS) throws TskCoreException { - this.controller = controller; //load dialog content fxml final String name = "nbres:/" + StringUtils.replace(ShowInTimelineDialog.class.getPackage().getName(), ".", "/") + "/ShowInTimelineDialog.fxml"; // NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java b/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java index 08abf34ed0..522be16ab6 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java @@ -83,8 +83,7 @@ public class EventNode extends DisplayableItemNode { @NbBundle.Messages({ "NodeProperty.displayName.icon=Icon", "NodeProperty.displayName.description=Description", - "NodeProperty.displayName.baseType=Base Type", - "NodeProperty.displayName.subType=Sub Type", + "NodeProperty.displayName.eventType=Event Type", "NodeProperty.displayName.known=Known", "NodeProperty.displayName.dateTime=Date/Time"}) protected Sheet createSheet() { @@ -99,8 +98,8 @@ public class EventNode extends DisplayableItemNode { properties.put(new TimeProperty("time", Bundle.NodeProperty_displayName_dateTime(), "time ", getDateTimeString()));// NON-NLS properties.put(new NodeProperty<>("description", Bundle.NodeProperty_displayName_description(), "description", event.getFullDescription())); // NON-NLS // todo: change filesystem events to use MACB notation. - properties.put(new NodeProperty<>("eventSubType", Bundle.NodeProperty_displayName_subType(), "sub type", - event.getEventType())); // NON-NLS + properties.put(new NodeProperty<>("eventType", Bundle.NodeProperty_displayName_eventType(), "event type", + event.getEventType().getDisplayName())); // NON-NLS return sheet; } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/DetailsViewModel.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/DetailsViewModel.java index 8a3ff33835..eb810cde72 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/DetailsViewModel.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/DetailsViewModel.java @@ -165,7 +165,7 @@ final public class DetailsViewModel { + " event_id, " //NON-NLS + " hash_hit, " //NON-NLS + " tagged, " //NON-NLS - + " sub_type, base_type, " + + " event_type_id, super_type_id, " + " full_description, med_description, short_description " // NON-NLS + " FROM " + TimelineManager.getAugmentedEventsTablesSQL(activeFilter) // NON-NLS + " WHERE time >= " + start + " AND time < " + end + " AND " + eventManager.getSQLWhere(activeFilter) // NON-NLS @@ -205,7 +205,7 @@ final public class DetailsViewModel { private TimelineEvent eventHelper(ResultSet resultSet) throws SQLException, TskCoreException { //the event tyepe to use to get the description. - int eventTypeID = resultSet.getInt("sub_type"); + int eventTypeID = resultSet.getInt("event_type_id"); EventType eventType = eventManager.getEventType(eventTypeID).orElseThrow(() -> new TskCoreException("Error mapping event type id " + eventTypeID + "to EventType."));//NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/BaseTypeTreeItem.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/BaseTypeTreeItem.java index 64092a0913..f593d55f19 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/BaseTypeTreeItem.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/BaseTypeTreeItem.java @@ -48,7 +48,7 @@ class BaseTypeTreeItem extends EventTypeTreeItem { * this tree item */ BaseTypeTreeItem(DetailViewEvent event, Comparator> comparator) { - super(EventType.getCommonSuperType(event.getEventTypes()).getBaseType(), comparator); + super (event.getEventType().getBaseType(), comparator); } @ThreadConfined(type = ThreadConfined.ThreadType.JFX) @@ -62,8 +62,8 @@ class BaseTypeTreeItem extends EventTypeTreeItem { * if the stripe and this tree item have the same type, create a * description tree item, else create a sub-type tree item */ - if (EventType.getCommonSuperType(head.getEventTypes()).getZoomLevel() == EventTypeZoomLevel.SUB_TYPE) { - descriptionKey = EventType.getCommonSuperType(head.getEventTypes()).getDisplayName(); + if (head.getEventType().getZoomLevel() == EventTypeZoomLevel.SUB_TYPE) { + descriptionKey = head.getEventType().getDisplayName(); treeItemConstructor = () -> configureNewTreeItem(new SubTypeTreeItem(head, getComparator())); } else { descriptionKey = head.getDescription(); @@ -88,8 +88,8 @@ class BaseTypeTreeItem extends EventTypeTreeItem { * if the stripe and this tree item have the same type, get the child * item keyed on event type, else keyed on description. */ - if (EventType.getCommonSuperType(head.getEventTypes()).getZoomLevel() == EventTypeZoomLevel.SUB_TYPE) { - descTreeItem = childMap.get(EventType.getCommonSuperType(head.getEventTypes()).getDisplayName()); + if (head.getEventType().getZoomLevel() == EventTypeZoomLevel.SUB_TYPE) { + descTreeItem = childMap.get(head.getEventType().getDisplayName()); } else { path.remove(0); //remove head of list if we are going straight to description descTreeItem = childMap.get(head.getDescription()); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/listvew/datamodel/ListViewModel.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/listvew/datamodel/ListViewModel.java index 0ae3958ded..df60c303f3 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/listvew/datamodel/ListViewModel.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/listvew/datamodel/ListViewModel.java @@ -92,7 +92,7 @@ public class ListViewModel { TimelineDBUtils dbUtils = new TimelineDBUtils(sleuthkitCase); final String querySql = "SELECT full_description, time, file_obj_id, " + dbUtils.csvAggFunction("CAST(tsk_events.event_id AS VARCHAR)") + " AS eventIDs, " - + dbUtils.csvAggFunction("CAST(sub_type AS VARCHAR)") + " AS eventTypes" + + dbUtils.csvAggFunction("CAST(event_type_id AS VARCHAR)") + " AS eventTypes" + " FROM " + TimelineManager.getAugmentedEventsTablesSQL(filterState.getActiveFilter()) + " WHERE time >= " + startTime + " AND time <" + endTime + " AND " + eventManager.getSQLWhere(filterState.getActiveFilter()) + " GROUP BY time, full_description, file_obj_id ORDER BY time ASC, full_description"; From d70aee1778dd08999a4d31b96ada69eb26d92fdb Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 7 Jan 2019 13:45:42 +0100 Subject: [PATCH 3/8] remove usage of ImmutableSet. Copying them was consuming a significant percentage of CPU. --- .../autopsy/timeline/FilteredEventsModel.java | 6 +++--- .../timeline/ShowInTimelineDialog.java | 3 ++- .../ui/detailview/EventClusterNode.java | 4 ++-- .../ui/detailview/EventStripeNode.java | 3 ++- .../ui/detailview/datamodel/EventCluster.java | 19 ++++++++++--------- .../ui/detailview/datamodel/EventStripe.java | 15 ++++++++------- 6 files changed, 27 insertions(+), 23 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/FilteredEventsModel.java b/Core/src/org/sleuthkit/autopsy/timeline/FilteredEventsModel.java index da9e56c648..04fd33965d 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/FilteredEventsModel.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/FilteredEventsModel.java @@ -526,7 +526,7 @@ public final class FilteredEventsModel { } /** - * Get a List of event IDs for the events that are derived from the given + * Get a Set of event IDs for the events that are derived from the given * file. * * @param file The AbstractFile to get derived event IDs @@ -537,12 +537,12 @@ public final class FilteredEventsModel { * directly from this file (file system * timestamps). * - * @return A List of event IDs for the events that are derived from the + * @return A Set of event IDs for the events that are derived from the * given file. * * @throws org.sleuthkit.datamodel.TskCoreException */ - public List getEventIDsForFile(AbstractFile file, boolean includeDerivedArtifacts) throws TskCoreException { + public Set getEventIDsForFile(AbstractFile file, boolean includeDerivedArtifacts) throws TskCoreException { return eventManager.getEventIDsForFile(file, includeDerivedArtifacts); } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ShowInTimelineDialog.java b/Core/src/org/sleuthkit/autopsy/timeline/ShowInTimelineDialog.java index fb4828e0b8..5111122ea9 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ShowInTimelineDialog.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ShowInTimelineDialog.java @@ -25,6 +25,7 @@ import java.time.Instant; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -125,7 +126,7 @@ final class ShowInTimelineDialog extends Dialog { */ @NbBundle.Messages({ "ShowInTimelineDialog.amountValidator.message=The entered amount must only contain digits."}) - private ShowInTimelineDialog(TimeLineController controller, List eventIDS) throws TskCoreException { + private ShowInTimelineDialog(TimeLineController controller, Collection eventIDS) throws TskCoreException { //load dialog content fxml final String name = "nbres:/" + StringUtils.replace(ShowInTimelineDialog.class.getPackage().getName(), ".", "/") + "/ShowInTimelineDialog.fxml"; // NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventClusterNode.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventClusterNode.java index a73de49fb0..a3fa974564 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventClusterNode.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventClusterNode.java @@ -18,13 +18,13 @@ */ package org.sleuthkit.autopsy.timeline.ui.detailview; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import static java.util.Objects.nonNull; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.stream.Collectors; @@ -259,7 +259,7 @@ final class EventClusterNode extends MultiEventNodeBase createChildNode(EventStripe stripe) throws TskCoreException { - ImmutableSet eventIDs = stripe.getEventIDs(); + Set eventIDs = stripe.getEventIDs(); if (eventIDs.size() == 1) { //If the stripe is a single event, make a single event node rather than a stripe node. TimelineEvent singleEvent = getController().getEventsModel().getEventById(Iterables.getOnlyElement(eventIDs)); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventStripeNode.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventStripeNode.java index 4ab889a523..5cd28571f3 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventStripeNode.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventStripeNode.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.timeline.ui.detailview; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import java.util.Arrays; +import java.util.Set; import javafx.event.EventHandler; import javafx.geometry.Pos; import javafx.scene.control.Button; @@ -117,7 +118,7 @@ final public class EventStripeNode extends MultiEventNodeBase createChildNode(EventCluster cluster) throws TskCoreException { - ImmutableSet eventIDs = cluster.getEventIDs(); + Set eventIDs = cluster.getEventIDs(); if (eventIDs.size() == 1) { TimelineEvent singleEvent = getController().getEventsModel().getEventById(Iterables.getOnlyElement(eventIDs)); SingleDetailsViewEvent singleDetailEvent = new SingleDetailsViewEvent(singleEvent).withParent(cluster); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventCluster.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventCluster.java index 3f530f68fb..e84274afc2 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventCluster.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventCluster.java @@ -25,6 +25,7 @@ import java.util.Collection; import static java.util.Collections.emptySet; import static java.util.Collections.singleton; import java.util.Comparator; +import java.util.HashSet; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -67,19 +68,19 @@ public class EventCluster implements MultiEvent { /** * the set of ids of the clustered events */ - final private ImmutableSet eventIDs; + final private Set eventIDs; /** * the ids of the subset of clustered events that have at least one tag * applied to them */ - private final ImmutableSet tagged; + private final Set tagged; /** * the ids of the subset of clustered events that have at least one hash set * hit */ - private final ImmutableSet hashHits; + private final Set hashHits; /** * merge two event clusters into one new event cluster. @@ -119,10 +120,10 @@ public class EventCluster implements MultiEvent { this.type = type; - this.hashHits = ImmutableSet.copyOf(hashHits); - this.tagged = ImmutableSet.copyOf(tagged); + this.hashHits = new HashSet<>(hashHits); + this.tagged = new HashSet<>(tagged); this.description = description; - this.eventIDs = ImmutableSet.copyOf(eventIDs); + this.eventIDs = new HashSet<>(eventIDs); this.lod = lod; this.parent = parent; } @@ -181,17 +182,17 @@ public class EventCluster implements MultiEvent { } @Override - public ImmutableSet getEventIDs() { + public Set getEventIDs() { return eventIDs; } @Override - public ImmutableSet getEventIDsWithHashHits() { + public Set getEventIDsWithHashHits() { return hashHits; } @Override - public ImmutableSet getEventIDsWithTags() { + public Set getEventIDsWithTags() { return tagged; } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventStripe.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventStripe.java index 1cac55272b..9b09bf4178 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventStripe.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventStripe.java @@ -24,6 +24,7 @@ import com.google.common.collect.ImmutableSortedSet; import java.util.Comparator; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.SortedSet; import org.sleuthkit.datamodel.DescriptionLoD; import org.sleuthkit.datamodel.timeline.EventType; @@ -56,18 +57,18 @@ public final class EventStripe implements MultiEvent { /** * the set of ids of the events */ - private final ImmutableSet eventIDs; + private final Set eventIDs; /** * the ids of the subset of events that have at least one tag applied to * them */ - private final ImmutableSet tagged; + private final Set tagged; /** * the ids of the subset of events that have at least one hash set hit */ - private final ImmutableSet hashHits; + private final Set hashHits; public static EventStripe merge(EventStripe u, EventStripe v) { //NOPMD Preconditions.checkNotNull(u); @@ -86,7 +87,7 @@ public final class EventStripe implements MultiEvent { return new EventStripe(parent, this.type, this.description, this.lod, clusters, eventIDs, tagged, hashHits); } - private EventStripe(EventCluster parent, EventType type, String description, DescriptionLoD lod, SortedSet clusters, ImmutableSet eventIDs, ImmutableSet tagged, ImmutableSet hashHits) { + private EventStripe(EventCluster parent, EventType type, String description, DescriptionLoD lod, SortedSet clusters, Set eventIDs, Set tagged, Set hashHits) { this.parent = parent; this.type = type; this.description = description; @@ -165,17 +166,17 @@ public final class EventStripe implements MultiEvent { } @Override - public ImmutableSet getEventIDs() { + public Set getEventIDs() { return eventIDs; } @Override - public ImmutableSet getEventIDsWithHashHits() { + public Set getEventIDsWithHashHits() { return hashHits; } @Override - public ImmutableSet getEventIDsWithTags() { + public Set getEventIDsWithTags() { return tagged; } From 851becfe5a1a3206d7944342a55e340d4ca4a1b1 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sat, 19 Jan 2019 12:59:17 +0100 Subject: [PATCH 4/8] cleanup --- .../sleuthkit/autopsy/timeline/FilteredEventsModel.java | 8 +++++--- .../sleuthkit/autopsy/timeline/TimeLineController.java | 3 ++- .../autopsy/timeline/ui/listvew/ListTimeline.java | 2 +- .../timeline/ui/listvew/datamodel/CombinedEvent.java | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/FilteredEventsModel.java b/Core/src/org/sleuthkit/autopsy/timeline/FilteredEventsModel.java index 04fd33965d..e1019c4164 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/FilteredEventsModel.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/FilteredEventsModel.java @@ -38,7 +38,9 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.collections.ObservableMap; import javafx.collections.ObservableSet; +import org.apache.commons.collections4.CollectionUtils; import static org.apache.commons.collections4.CollectionUtils.emptyIfNull; +import static org.apache.commons.collections4.CollectionUtils.isNotEmpty; import org.joda.time.DateTimeZone; import org.joda.time.Interval; import org.openide.util.NbBundle; @@ -637,7 +639,7 @@ public final class FilteredEventsModel { synchronized public Set addTag(long objID, Long artifactID, Tag tag) throws TskCoreException { Set updatedEventIDs = eventManager.setEventsTagged(objID, artifactID, true); - if (!updatedEventIDs.isEmpty()) { + if (isNotEmpty(updatedEventIDs)) { invalidateCaches(updatedEventIDs); } return updatedEventIDs; @@ -645,7 +647,7 @@ public final class FilteredEventsModel { synchronized public Set deleteTag(long objID, Long artifactID, long tagID, boolean tagged) throws TskCoreException { Set updatedEventIDs = eventManager.setEventsTagged(objID, artifactID, tagged); - if (!updatedEventIDs.isEmpty()) { + if (isNotEmpty(updatedEventIDs)) { invalidateCaches(updatedEventIDs); } return updatedEventIDs; @@ -656,7 +658,7 @@ public final class FilteredEventsModel { for (BlackboardArtifact artifact : artifacts) { updatedEventIDs.addAll(eventManager.setEventsHashed(artifact.getObjectID(), hasHashHit)); } - if (!updatedEventIDs.isEmpty()) { + if (isNotEmpty(updatedEventIDs)) { invalidateCaches(updatedEventIDs); } return updatedEventIDs; diff --git a/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java b/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java index 56b8501c26..6e3ae4b23a 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java @@ -87,6 +87,7 @@ import org.sleuthkit.autopsy.timeline.zooming.TimeUnits; import org.sleuthkit.autopsy.timeline.zooming.ZoomState; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; +import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT; import org.sleuthkit.datamodel.DescriptionLoD; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.timeline.EventType; @@ -734,7 +735,7 @@ public class TimeLineController { break; case DATA_ADDED: ModuleDataEvent eventData = (ModuleDataEvent) evt.getOldValue(); - if (null != eventData && eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) { + if (null != eventData && eventData.getBlackboardArtifactType().getTypeID() == TSK_HASHSET_HIT.getTypeID()) { logFutureException(executor.submit(() -> filteredEvents.setHashHit(eventData.getArtifacts(), true)), "Error executing task in response to DATA_ADDED event.", "Error executing response to new data."); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/listvew/ListTimeline.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/listvew/ListTimeline.java index e591ee7af8..c77f3e4624 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/listvew/ListTimeline.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/listvew/ListTimeline.java @@ -572,7 +572,7 @@ class ListTimeline extends BorderPane { } /** - * Base class for TableCells that represent a MergedEvent by way of a + * Base class for TableCells that represent a CombinedEvent by way of a * representative TimeLineEvent. */ private abstract class EventTableCell extends TableCell { diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/listvew/datamodel/CombinedEvent.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/listvew/datamodel/CombinedEvent.java index 7f924e88c8..92b0a661bb 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/listvew/datamodel/CombinedEvent.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/listvew/datamodel/CombinedEvent.java @@ -105,8 +105,8 @@ public class CombinedEvent { /** * Get the event ID of one event that is representative of all the combined - * events. It can be used to look up a SingleEvent with more details, for - * example. + * events. It can be used to look up a TimelineEvent with more details, for + * example. wwhether the file is tagged or a hash hit. * * @return An arbitrary representative event ID for the combined events. */ From 1171408a9ed40035dfdbc1db34185fa71c625b0c Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 22 Jan 2019 15:21:11 +0100 Subject: [PATCH 5/8] don't include in map attribute that isn't actually processed. --- .../org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index c378c73534..299aae3c36 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -779,7 +779,7 @@ class ExtractRegistry extends Extract { private Collection processProfiler(NodeList myartlist, SleuthkitCase caseDB, AbstractFile regAbstractFile) throws IllegalArgumentException, DOMException { //map from node attribute names to tsk ATTRIBUTE_TYPE. Map keys = ImmutableMap.of( - "PROCESSOR_IDENTIFIER", null,// TODO: should this go into an attribute? //NON-NLS + // "PROCESSOR_IDENTIFIER", null,// TODO: should this go into an attribute? //NON-NLS "OS", TSK_VERSION, //NON-NLS "PROCESSOR_ARCHITECTURE", TSK_PROCESSOR_ARCHITECTURE, //NON-NLS "TEMP", TSK_TEMP_DIR); //NON-NLS From ec47efd206b1c11377b00782350ed0c600c20494 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 14 Feb 2019 13:41:27 +0100 Subject: [PATCH 6/8] fix merge errors --- .../autopsy/recentactivity/Chrome.java | 5 +- .../autopsy/recentactivity/Extract.java | 28 +- .../recentactivity/ExtractRegistry.java | 457 +++++++++++++++++- .../autopsy/recentactivity/Firefox.java | 315 ------------ .../recentactivity/RAImageIngestModule.java | 15 +- 5 files changed, 472 insertions(+), 348 deletions(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java index 14bdddd501..76a74fab79 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java @@ -28,8 +28,6 @@ import com.google.gson.JsonIOException; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; -import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.ingest.IngestServices; import org.sleuthkit.autopsy.datamodel.ContentUtils; import java.util.logging.Level; import java.util.*; @@ -40,10 +38,9 @@ import java.io.IOException; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.casemodule.services.FileManager; import org.sleuthkit.autopsy.coreutils.NetworkUtils; import org.sleuthkit.autopsy.ingest.IngestJobContext; -import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.BlackboardArtifact; diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Extract.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Extract.java index dccbb3fc2c..09bf37c985 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Extract.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Extract.java @@ -37,15 +37,20 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.SQLiteDBConnect; import org.sleuthkit.autopsy.ingest.IngestJobContext; import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException; -import org.sleuthkit.datamodel.*; +import org.sleuthkit.datamodel.Blackboard; +import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.TskCoreException; @Messages({"Extract.indexError.message=Failed to index artifact for keyword search.", "Extract.noOpenCase.errMsg=No open case available.", - "#{0} - the module name", + "# {0} - the module name", "Extractor.errPostingArtifacts=Error posting {0} artifacts to the blackboard."}) abstract class Extract { - private static final Logger logger = Logger.getLogger(Extract.class.getName()); + protected static final Logger logger = Logger.getLogger(Extract.class.getName()); protected Case currentCase; protected SleuthkitCase tskCase; @@ -180,21 +185,22 @@ abstract class Extract { /** * Returns a List of AbstractFile objects from TSK based on sql query. * - * @param rs is the resultset that needs to be converted to an arraylist + * @param results is the resultset that needs to be converted to an + * arraylist * * @return list returns the arraylist built from the converted resultset */ - private List> resultSetToArrayList(ResultSet rs) throws SQLException { - ResultSetMetaData md = rs.getMetaData(); - int columns = md.getColumnCount(); + private List> resultSetToArrayList(ResultSet results) throws SQLException { + ResultSetMetaData metaData = results.getMetaData(); + int columns = metaData.getColumnCount(); List> list = new ArrayList<>(50); - while (rs.next()) { + while (results.next()) { HashMap row = new HashMap<>(columns); for (int i = 1; i <= columns; ++i) { - if (rs.getObject(i) == null) { - row.put(md.getColumnName(i), ""); + if (results.getObject(i) == null) { + row.put(metaData.getColumnName(i), ""); } else { - row.put(md.getColumnName(i), rs.getObject(i)); + row.put(metaData.getColumnName(i), results.getObject(i)); } } list.add(row); diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index dae1e7e1f4..b5bc552445 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -49,7 +49,14 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import java.nio.file.Path; import static java.util.TimeZone.getTimeZone; +import org.openide.util.Lookup; +import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException; +import org.sleuthkit.autopsy.ingest.IngestServices; +import org.sleuthkit.autopsy.ingest.ModuleDataEvent; +import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService; +import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException; /** * Extract windows registry data using regripper. Runs two versions of @@ -76,8 +83,6 @@ class ExtractRegistry extends Extract { final private static int MS_IN_SEC = 1000; final private static String NEVER_DATE = "Never"; final private static String SECTION_DIVIDER = "-------------------------"; - private IngestJobContext context; - private final List rrCmd = new ArrayList<>(); private final List rrFullCmd = new ArrayList<>(); @@ -226,6 +231,7 @@ class ExtractRegistry extends Extract { } // create a report for the full output + if (!regOutputFiles.fullPlugins.isEmpty()) { //parse the full regripper output from SAM hive files if (regFileNameLocal.toLowerCase().contains("sam")) { if (parseSamPluginOutput(regOutputFiles.fullPlugins, regFile) == false) { @@ -353,6 +359,53 @@ class ExtractRegistry extends Extract { * * @return */ + private boolean parseAutopsyPluginOutput(String regFilePath, AbstractFile regFile) { + FileInputStream fstream = null; + try { + // Read the file in and create a Document and elements + File regfile = new File(regFilePath); + fstream = new FileInputStream(regfile); + String regString = new Scanner(fstream, "UTF-8").useDelimiter("\\Z").next(); //NON-NLS + String startdoc = ""; //NON-NLS + String result = regString.replaceAll("----------------------------------------", ""); + result = result.replaceAll("\\n", ""); //NON-NLS + result = result.replaceAll("\\r", ""); //NON-NLS + result = result.replaceAll("'", "'"); //NON-NLS + result = result.replaceAll("&", "&"); //NON-NLS + result = result.replace('\0', ' '); // NON-NLS + String enddoc = ""; //NON-NLS + String stringdoc = startdoc + result + enddoc; + DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + Document doc = builder.parse(new InputSource(new StringReader(stringdoc))); + + // cycle through the elements in the doc + Element oroot = doc.getDocumentElement(); + NodeList children = oroot.getChildNodes(); + int len = children.getLength(); + // Add all "usb" dataType nodes to collection of BlackboardArtifacts + // that we will submit in a ModuleDataEvent for additional processing. + Collection usbBBartifacts = new ArrayList<>(); + // Add all "ssid" dataType nodes to collection of BlackboardArtifacts + // that we will submit in a ModuleDataEvent for additional processing. + Collection wifiBBartifacts = new ArrayList<>(); + for (int i = 0; i < len; i++) { + Element tempnode = (Element) children.item(i); + + String dataType = tempnode.getNodeName(); + NodeList timenodes = tempnode.getElementsByTagName("mtime"); //NON-NLS + Long mtime = null; + if (timenodes.getLength() > 0) { + Element timenode = (Element) timenodes.item(0); + String etime = timenode.getTextContent(); + try { + Long epochtime = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy").parse(etime).getTime(); + mtime = epochtime; + String Tempdate = mtime.toString(); + mtime = Long.valueOf(Tempdate) / MS_IN_SEC; + } catch (ParseException ex) { + logger.log(Level.WARNING, "Failed to parse epoch time when parsing the registry."); //NON-NLS + } + } NodeList artroots = tempnode.getElementsByTagName("artifacts"); //NON-NLS if (artroots.getLength() == 0) { @@ -365,30 +418,402 @@ class ExtractRegistry extends Extract { String parentModuleName = NbBundle.getMessage(this.getClass(), "ExtractRegistry.parentModuleName.noSpace"); String winver = ""; - mtime = Long.valueOf(Tempdate) / MS_IN_SEC; + // If all artifact nodes should really go under one Blackboard artifact, need to process it differently + switch (dataType) { + case "WinVersion": //NON-NLS + String version = ""; + String systemRoot = ""; + String productId = ""; + String regOwner = ""; + String regOrg = ""; + Long installtime = null; + for (int j = 0; j < myartlist.getLength(); j++) { + Node artchild = myartlist.item(j); + // If it has attributes, then it is an Element (based off API) + if (artchild.hasAttributes()) { + Element artnode = (Element) artchild; + + String value = artnode.getTextContent().trim(); + String name = artnode.getAttribute("name"); //NON-NLS + switch (name) { + case "ProductName": // NON-NLS + version = value; + break; + case "CSDVersion": // NON-NLS + // This is dependant on the fact that ProductName shows up first in the module output + version = version + " " + value; + break; + case "SystemRoot": //NON-NLS + systemRoot = value; + break; + case "ProductId": //NON-NLS + productId = value; + break; + case "RegisteredOwner": //NON-NLS + regOwner = value; + break; + case "RegisteredOrganization": //NON-NLS + regOrg = value; + break; + case "InstallDate": //NON-NLS + try { + Long epochtime = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy").parse(value).getTime(); + installtime = epochtime; + String Tempdate = installtime.toString(); + installtime = Long.valueOf(Tempdate) / MS_IN_SEC; + } catch (ParseException e) { + logger.log(Level.SEVERE, "RegRipper::Conversion on DateTime -> ", e); //NON-NLS + } + break; + default: + break; + } + } + } + try { + Collection bbattributes = new ArrayList<>(); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, version)); + if (installtime != null) { + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, installtime)); + } + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH, parentModuleName, systemRoot)); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PRODUCT_ID, parentModuleName, productId)); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_OWNER, parentModuleName, regOwner)); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ORGANIZATION, parentModuleName, regOrg)); + + // Check if there is already an OS_INFO artifact for this file, and add to that if possible. + ArrayList results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId()); + if (results.isEmpty()) { + BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO); + bbart.addAttributes(bbattributes); + + // index the artifact for keyword search + this.indexArtifact(bbart); + } else { + results.get(0).addAttributes(bbattributes); + } + + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error adding installed program artifact to blackboard."); //NON-NLS } break; - case "shellfolders": // NON-NLS - // The User Shell Folders subkey stores the paths to Windows Explorer folders for the current user of the computer - // (https://technet.microsoft.com/en-us/library/Cc962613.aspx). - // No useful information. Skip. + case "Profiler": // NON-NLS + String os = ""; + String procArch = ""; + String procId = ""; + String tempDir = ""; + for (int j = 0; j < myartlist.getLength(); j++) { + Node artchild = myartlist.item(j); + // If it has attributes, then it is an Element (based off API) + if (artchild.hasAttributes()) { + Element artnode = (Element) artchild; + + String value = artnode.getTextContent().trim(); + String name = artnode.getAttribute("name"); //NON-NLS + switch (name) { + case "OS": // NON-NLS + os = value; + break; + case "PROCESSOR_ARCHITECTURE": // NON-NLS + procArch = value; + break; + case "PROCESSOR_IDENTIFIER": //NON-NLS + procId = value; + break; + case "TEMP": //NON-NLS + tempDir = value; + break; + default: + break; + } + } + } + try { + Collection bbattributes = new ArrayList<>(); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VERSION, parentModuleName, os)); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE, parentModuleName, procArch)); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TEMP_DIR, parentModuleName, tempDir)); + + // Check if there is already an OS_INFO artifact for this file and add to that if possible + ArrayList results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId()); + if (results.isEmpty()) { + BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO); + bbart.addAttributes(bbattributes); + + // index the artifact for keyword search + this.indexArtifact(bbart); + } else { + results.get(0).addAttributes(bbattributes); + } + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error adding os info artifact to blackboard."); //NON-NLS + } + break; + case "CompName": // NON-NLS + String compName = ""; + String domain = ""; + for (int j = 0; j < myartlist.getLength(); j++) { + Node artchild = myartlist.item(j); + // If it has attributes, then it is an Element (based off API) + if (artchild.hasAttributes()) { + Element artnode = (Element) artchild; + + String value = artnode.getTextContent().trim(); + String name = artnode.getAttribute("name"); //NON-NLS + + if (name.equals("ComputerName")) { // NON-NLS + compName = value; + } else if (name.equals("Domain")) { // NON-NLS + domain = value; + } + } + } + try { + Collection bbattributes = new ArrayList<>(); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, compName)); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN, parentModuleName, domain)); + + // Check if there is already an OS_INFO artifact for this file and add to that if possible + ArrayList results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId()); + if (results.isEmpty()) { + BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO); + bbart.addAttributes(bbattributes); + + // index the artifact for keyword search + this.indexArtifact(bbart); + } else { + results.get(0).addAttributes(bbattributes); + } + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error adding os info artifact to blackboard."); //NON-NLS + } break; default: - logger.log(Level.WARNING, "Unrecognized node name: {0}", dataType); //NON-NLS - break; - } - ArrayList results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId()); - ArrayList results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId()); + for (int j = 0; j < myartlist.getLength(); j++) { + Node artchild = myartlist.item(j); + // If it has attributes, then it is an Element (based off API) + if (artchild.hasAttributes()) { + Element artnode = (Element) artchild; + + String value = artnode.getTextContent().trim(); + Collection bbattributes = new ArrayList<>(); + + switch (dataType) { + case "recentdocs": //NON-NLS + // BlackboardArtifact bbart = tskCase.getContentById(orgId).newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT); + // bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "RecentActivity", dataType, mtime)); + // bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity", dataType, mtimeItem)); + // bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(), "RecentActivity", dataType, value)); + // bbart.addAttributes(bbattributes); + // @@@ BC: Why are we ignoring this... + break; + case "usb": //NON-NLS + try { + Long usbMtime = Long.parseLong(artnode.getAttribute("mtime")); //NON-NLS + usbMtime = Long.valueOf(usbMtime.toString()); + + BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, usbMtime)); + String dev = artnode.getAttribute("dev"); //NON-NLS + String make = ""; + String model = dev; + if (dev.toLowerCase().contains("vid")) { //NON-NLS + USBInfo info = USB_MAPPER.parseAndLookup(dev); + if (info.getVendor() != null) { + make = info.getVendor(); + } + if (info.getProduct() != null) { + model = info.getProduct(); + } + } + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE, parentModuleName, make)); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL, parentModuleName, model)); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, value)); + bbart.addAttributes(bbattributes); + + // index the artifact for keyword search + this.indexArtifact(bbart); + // add to collection for ModuleDataEvent + usbBBartifacts.add(bbart); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error adding device attached artifact to blackboard."); //NON-NLS + } + break; + case "uninstall": //NON-NLS + Long itemMtime = null; + try { + Long epochtime = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy").parse(artnode.getAttribute("mtime")).getTime(); //NON-NLS + itemMtime = epochtime; + itemMtime = itemMtime / MS_IN_SEC; + } catch (ParseException e) { + logger.log(Level.WARNING, "Failed to parse epoch time for installed program artifact."); //NON-NLS + } + + try { + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, value)); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, itemMtime)); + BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_INSTALLED_PROG); + bbart.addAttributes(bbattributes); + + // index the artifact for keyword search + this.indexArtifact(bbart); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error adding installed program artifact to blackboard."); //NON-NLS + } + break; + case "office": //NON-NLS + String officeName = artnode.getAttribute("name"); //NON-NLS + + try { + BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT); + // @@@ BC: Consider removing this after some more testing. It looks like an Mtime associated with the root key and not the individual item + if (mtime != null) { + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, parentModuleName, mtime)); + } + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, officeName)); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE, parentModuleName, value)); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, artnode.getNodeName())); + bbart.addAttributes(bbattributes); + + // index the artifact for keyword search + this.indexArtifact(bbart); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error adding recent object artifact to blackboard."); //NON-NLS + } + break; + + case "ProcessorArchitecture": //NON-NLS + // Architecture is now included under Profiler + //try { + // String processorArchitecture = value; + // if (processorArchitecture.equals("AMD64")) + // processorArchitecture = "x86-64"; + + // BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO); + // bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE.getTypeID(), parentModuleName, processorArchitecture)); + // bbart.addAttributes(bbattributes); + //} catch (TskCoreException ex) { + // logger.log(Level.SEVERE, "Error adding os info artifact to blackboard."); //NON-NLS + //} + break; + + case "ProfileList": //NON-NLS + try { + String homeDir = value; + String sid = artnode.getAttribute("sid"); //NON-NLS + String username = artnode.getAttribute("username"); //NON-NLS + 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.WARNING, "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)); + } 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); + // index the artifact for keyword search + this.indexArtifact(bbart); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error adding account artifact to blackboard."); //NON-NLS + } + break; + + case "NtuserNetwork": // NON-NLS + try { + String localPath = artnode.getAttribute("localPath"); //NON-NLS + String remoteName = value; + BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_REMOTE_DRIVE); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LOCAL_PATH, + parentModuleName, localPath)); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REMOTE_PATH, + parentModuleName, remoteName)); + bbart.addAttributes(bbattributes); + // index the artifact for keyword search + this.indexArtifact(bbart); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error adding network artifact to blackboard."); //NON-NLS + } + break; + case "SSID": // NON-NLS + String adapter = artnode.getAttribute("adapter"); //NON-NLS + try { + Long lastWriteTime = Long.parseLong(artnode.getAttribute("writeTime")); //NON-NLS + lastWriteTime = Long.valueOf(lastWriteTime.toString()); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SSID, parentModuleName, value)); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, lastWriteTime)); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, adapter)); + BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_WIFI_NETWORK); + bbart.addAttributes(bbattributes); + // index the artifact for keyword search + this.indexArtifact(bbart); + wifiBBartifacts.add(bbart); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error adding SSID artifact to blackboard."); //NON-NLS + } + break; + case "shellfolders": // NON-NLS + // The User Shell Folders subkey stores the paths to Windows Explorer folders for the current user of the computer + // (https://technet.microsoft.com/en-us/library/Cc962613.aspx). + // No useful information. Skip. + break; + + default: + logger.log(Level.WARNING, "Unrecognized node name: {0}", dataType); //NON-NLS + break; + } + } + } break; } } // for - // BlackboardArtifact bbart = tskCase.getContentById(orgId).newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT); - itemMtime = itemMtime / MS_IN_SEC; - + + return true; + } catch (FileNotFoundException ex) { + logger.log(Level.SEVERE, "Error finding the registry file.", ex); //NON-NLS + } catch (SAXException ex) { + logger.log(Level.SEVERE, "Error parsing the registry XML: {0}", ex); //NON-NLS + } catch (IOException ex) { + logger.log(Level.SEVERE, "Error building the document parser: {0}", ex); //NON-NLS + } catch (ParserConfigurationException ex) { + logger.log(Level.SEVERE, "Error configuring the registry parser: {0}", ex); //NON-NLS + } finally { + try { + if (fstream != null) { + fstream.close(); } } catch (IOException ex) { } - logger.log(Level.SEVERE, "Error finding the registry file.", ex); //NON-NLS } return false; } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java index f858942375..2b41d8b5ff 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java @@ -89,7 +89,6 @@ class Firefox extends Extract { private final IngestServices services = IngestServices.getInstance(); private Content dataSource; private IngestJobContext context; - private final String moduleName; Firefox() { moduleName = NbBundle.getMessage(Firefox.class, "Firefox.moduleName"); @@ -969,320 +968,6 @@ class Firefox extends Extract { } - /** - * Gets data from formshistory.sqlite database. - * Parses and creates artifacts. - */ - private void getFormsHistory() { - FileManager fileManager = currentCase.getServices().getFileManager(); - List formHistoryFiles; - - // Some fields are just noisy and can me excluded - Set excludedFieldNames = new HashSet<>(Arrays.asList( - "it", // some kind of timestamp - "ts" // some kind of timestamp - )); - - try { - formHistoryFiles = fileManager.findFiles(dataSource, "formhistory.sqlite", "Firefox"); //NON-NLS - } catch (TskCoreException ex) { - String msg = NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.errFetchingFiles"); - logger.log(Level.WARNING, msg); - this.addErrorMessage(this.getName() + ": " + msg); - return; - } - - if (formHistoryFiles.isEmpty()) { - String msg = NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.noFilesFound"); - logger.log(Level.INFO, msg); - return; - } - - dataFound = true; - Collection bbartifacts = new ArrayList<>(); - int j = 0; - for (AbstractFile formHistoryFile : formHistoryFiles) { - if (formHistoryFile.getSize() == 0) { - continue; - } - - String fileName = formHistoryFile.getName(); - String tempFilePath = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS - try { - ContentUtils.writeToFile(formHistoryFile, new File(tempFilePath), context::dataSourceIngestIsCancelled); - } catch (ReadContentInputStreamException ex) { - logger.log(Level.WARNING, String.format("Error reading Firefox web history artifacts file '%s' (id=%d).", - fileName, formHistoryFile.getId()), ex); //NON-NLS - this.addErrorMessage( - NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.errAnalyzeFile", this.getName(), - fileName)); - continue; - } catch (IOException ex) { - logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Firefox web history artifacts file '%s' (id=%d).", - tempFilePath, fileName, formHistoryFile.getId()), ex); //NON-NLS - this.addErrorMessage( - NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.errAnalyzeFile", this.getName(), - fileName)); - continue; - } - File dbFile = new File(tempFilePath); - if (context.dataSourceIngestIsCancelled()) { - dbFile.delete(); - break; - } - - // The table schema is a little different in newer version of Firefox - boolean isFirefoxV64 = Util.checkColumn("timesUsed", "moz_formhistory", tempFilePath); - String formHistoryQuery = (isFirefoxV64) ? FORMHISTORY_QUERY_V64 : FORMHISTORY_QUERY; - - List> tempList = this.dbConnect(tempFilePath, formHistoryQuery); - logger.log(Level.INFO, "{0} - Now getting history from {1} with {2} artifacts identified.", new Object[]{moduleName, tempFilePath, tempList.size()}); //NON-NLS - for (HashMap result : tempList) { - Collection bbattributes = new ArrayList<>(); - - String fieldName = ((result.get("fieldname").toString() != null) ? result.get("fieldname").toString() : ""); - // filter out unuseful values - if (excludedFieldNames.contains(fieldName.toLowerCase())) { - continue; - } - - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, - NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), - fieldName)); //NON-NLS - - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE, - NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), - ((result.get("value").toString() != null) ? result.get("value").toString() : ""))); //NON-NLS - - // Newer versions of firefox have additional columns - if (isFirefoxV64) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED, - NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), - (Long.valueOf(result.get("firstUsed").toString()) / 1000000))); //NON-NLS - - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, - NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), - (Long.valueOf(result.get("lastUsed").toString()) / 1000000))); //NON-NLS - - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT, - NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), - (Integer.valueOf(result.get("timesUsed").toString())))); //NON-NLS - - } - // Add artifact - BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_FORM_AUTOFILL, formHistoryFile, bbattributes); - if (bbart != null) { - this.indexArtifact(bbart); - bbartifacts.add(bbart); - } - } - ++j; - dbFile.delete(); - } - - services.fireModuleDataEvent(new ModuleDataEvent( - NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), - BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_FORM_AUTOFILL, bbartifacts)); - } - - - /** - * Gets data from autofill-profiles.json file. - * Parses file and makes artifacts. - * - */ - private void getAutofillProfiles() { - FileManager fileManager = currentCase.getServices().getFileManager(); - List autofillProfilesFiles; - try { - autofillProfilesFiles = fileManager.findFiles(dataSource, "autofill-profiles.json", "Firefox"); //NON-NLS - } catch (TskCoreException ex) { - String msg = NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errGettingFiles"); - logger.log(Level.SEVERE, msg, ex); - this.addErrorMessage(this.getName() + ": " + msg); - return; - } - - if (autofillProfilesFiles.isEmpty()) { - logger.log(Level.INFO, "Didn't find any Firefox Autofill Profiles files."); //NON-NLS - return; - } - - dataFound = true; - Collection bbartifacts = new ArrayList<>(); - int j = 0; - - while (j < autofillProfilesFiles.size()) { - AbstractFile profileFile = autofillProfilesFiles.get(j++); - if (profileFile.getSize() == 0) { - continue; - } - String temps = RAImageIngestModule.getRATempPath(currentCase, "Firefox") + File.separator + profileFile.getName() + j + ".json"; //NON-NLS - try { - ContentUtils.writeToFile(profileFile, new File(temps), context::dataSourceIngestIsCancelled); - } catch (ReadContentInputStreamException ex) { - logger.log(Level.WARNING, String.format("Error reading Firefox Autofill profiles artifacts file '%s' (id=%d).", - profileFile.getName(), profileFile.getId()), ex); //NON-NLS - this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile", - this.getName(), profileFile.getName())); - continue; - } catch (IOException ex) { - logger.log(Level.SEVERE, String.format("Error writing temp file '%s' for Firefox Autofill profiles file '%s' (id=%d).", - temps, profileFile.getName(), profileFile.getId()), ex); //NON-NLS - this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile", - this.getName(), profileFile.getName())); - continue; - } - - logger.log(Level.INFO, "{0}- Now getting Bookmarks from {1}", new Object[]{moduleName, temps}); //NON-NLS - File dbFile = new File(temps); - if (context.dataSourceIngestIsCancelled()) { - dbFile.delete(); - break; - } - - FileReader tempReader; - try { - tempReader = new FileReader(temps); - } catch (FileNotFoundException ex) { - logger.log(Level.SEVERE, "Error while trying to read the Autofill profiles json file for Firefox.", ex); //NON-NLS - this.addErrorMessage( - NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzeFile", this.getName(), - profileFile.getName())); - continue; - } - - final JsonParser parser = new JsonParser(); - - JsonObject jsonRootObject; - JsonArray jAddressesArray; - - try { - jsonRootObject = parser.parse(tempReader).getAsJsonObject(); - jAddressesArray = jsonRootObject.getAsJsonArray("addresses"); //NON-NLS - } catch (JsonIOException | JsonSyntaxException | IllegalStateException ex) { - logger.log(Level.WARNING, "Error parsing Json for Firefox Autofill profiles.", ex); //NON-NLS - this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile3", - this.getName(), profileFile.getName())); - continue; - } - - for (JsonElement result : jAddressesArray) { - JsonObject address = result.getAsJsonObject(); - if (address == null) { - continue; - } - - JsonElement nameEl = address.get("name"); //NON-NLS - String name = (nameEl != null) ? nameEl.getAsString() : ""; - - JsonElement emailEl = address.get("email"); //NON-NLS - String email = (emailEl != null) ? emailEl.getAsString() : ""; - - JsonElement telEl = address.get("tel"); //NON-NLS - String tel = (telEl != null) ? telEl.getAsString() : ""; - JsonElement telCountryCodeEl = address.get("tel-country-code"); //NON-NLS - String telCountryCode = (telCountryCodeEl != null) ? telCountryCodeEl.getAsString() : ""; - JsonElement telNationalEl = address.get("tel-national"); //NON-NLS - String telNational = (telNationalEl != null) ? telNationalEl.getAsString() : ""; - - String phoneNumber = makeTelNumber(tel, telCountryCode, telNational); - - JsonElement createdEl = address.get("timeCreated"); //NON-NLS - Long datetimeCreated = (createdEl != null) ? createdEl.getAsLong()/1000 : Long.valueOf(0); - JsonElement lastusedEl = address.get("timeLastUsed"); //NON-NLS - Long datetimeLastUsed = (lastusedEl != null) ? lastusedEl.getAsLong()/1000 : Long.valueOf(0); - JsonElement timesUsedEl = address.get("timesUsed"); //NON-NLS - Integer timesUsed = (timesUsedEl != null) ? timesUsedEl.getAsShort() : Integer.valueOf(0); - - JsonElement addressLine1El = address.get("address-line1"); //NON-NLS - String addressLine1 = (addressLine1El != null) ? addressLine1El.getAsString() : ""; - JsonElement addressLine2El = address.get("address-line2"); //NON-NLS - String addressLine2 = (addressLine2El != null) ? addressLine2El.getAsString() : ""; - JsonElement addressLine3El = address.get("address-line3"); //NON-NLS - String addressLine3 = (addressLine3El != null) ? addressLine3El.getAsString() : ""; - - JsonElement postalCodeEl = address.get("postal-code"); //NON-NLS - String postalCode = (postalCodeEl != null) ? postalCodeEl.getAsString() : ""; - JsonElement countryEl = address.get("country"); //NON-NLS - String country = (countryEl != null) ? countryEl.getAsString() : ""; - - String mailingAddress = makeFullAddress(addressLine1, addressLine2, addressLine3, postalCode, country ); - - try { - Collection bbattributes = new ArrayList<>(); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME_PERSON, - NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), - name)); //NON-NLS - - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL, - NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), - email)); //NON-NLS - - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, - NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), - phoneNumber)); //NON-NLS - - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LOCATION, - NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), - mailingAddress)); //NON-NLS - - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED, - NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), - datetimeCreated)); //NON-NLS - - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, - NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), - datetimeLastUsed)); //NON-NLS - - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT, - NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), - timesUsed)); //NON-NLS - - BlackboardArtifact bbart = profileFile.newArtifact(ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS); - - // index the artifact for keyword search - if (bbart != null) { - bbart.addAttributes(bbattributes); - this.indexArtifact(bbart); - bbartifacts.add(bbart); - } - - // If an email address is found, create an account instance for it - if (email != null && !email.isEmpty()) { - try { - Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.EMAIL, email, NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), profileFile); - } catch (NoCurrentCaseException | TskCoreException ex) { - logger.log(Level.SEVERE, String.format("Error creating email account instance for '%s' from Firefox profiles file '%s' .", - email, profileFile.getName()), ex); //NON-NLS - } - } - - // If a phone number is found, create an account instance for it - if (phoneNumber != null && !phoneNumber.isEmpty()) { - try { - Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.PHONE, phoneNumber, NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), profileFile); - } catch (NoCurrentCaseException | TskCoreException ex) { - logger.log(Level.SEVERE, String.format("Error creating phone number account instance for '%s' from Chrome profiles file '%s' .", - phoneNumber, profileFile.getName()), ex); //NON-NLS - } - } - - } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Error while trying to insert Firefox Autofill profile artifact{0}", ex); //NON-NLS - this.addErrorMessage( - NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile4", - this.getName(), profileFile.getName())); - } - } - dbFile.delete(); - } - - IngestServices.getInstance().fireModuleDataEvent(new ModuleDataEvent( - NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), - BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS, bbartifacts)); - } - /** * Extract the domain from the supplied URL. This method does additional * checks to detect invalid URLs. diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java index ae0ad97e9c..5f1c31664a 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java @@ -47,7 +47,7 @@ public final class RAImageIngestModule implements DataSourceIngestModule { private static final Logger logger = Logger.getLogger(RAImageIngestModule.class.getName()); private final List extractors = new ArrayList<>(); private final List browserExtractors = new ArrayList<>(); - private final IngestServices services = IngestServices.getInstance(); + private IngestServices services = IngestServices.getInstance(); private IngestJobContext context; private StringBuilder subCompleted = new StringBuilder(); @@ -68,6 +68,8 @@ public final class RAImageIngestModule implements DataSourceIngestModule { Extract registry = new ExtractRegistry(); Extract recentDocuments = new RecentDocumentsByLnk(); Extract chrome = new Chrome(); + Extract firefox = new Firefox(); + Extract SEUQA = new SearchEngineURLQueryAnalyzer(); Extract osExtract = new ExtractOs(); Extract dataSourceAnalyzer = new DataSourceUsageAnalyzer(); @@ -156,7 +158,7 @@ public final class RAImageIngestModule implements DataSourceIngestModule { historyMsg.append( NbBundle.getMessage(this.getClass(), "RAImageIngestModule.process.histMsg.title", dataSource.getName())); for (Extract module : browserExtractors) { - historyMsg.append("
  • ").append(module.getModuleName()); //NON-NLS + historyMsg.append("
  • ").append(module.getName()); //NON-NLS historyMsg.append(": ").append((module.foundData()) ? NbBundle .getMessage(this.getClass(), "RAImageIngestModule.process.histMsg.found") : NbBundle .getMessage(this.getClass(), "RAImageIngestModule.process.histMsg.notFnd")); @@ -176,6 +178,15 @@ public final class RAImageIngestModule implements DataSourceIngestModule { for (int i = 0; i < extractors.size(); i++) { Extract extracter = extractors.get(i); + try { + extracter.complete(); + } catch (Exception ex) { + logger.log(Level.SEVERE, "Exception occurred when completing " + extracter.getName(), ex); //NON-NLS + subCompleted.append(NbBundle.getMessage(this.getClass(), "RAImageIngestModule.complete.errMsg.failed", + extracter.getName())); + } + } + return ProcessResult.OK; } From 2405d5023ecece8e297925fc6b9150298b365ae9 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 20 Feb 2019 11:33:11 +0100 Subject: [PATCH 7/8] fix issues identified by codacy --- .../recentactivity/ExtractRegistry.java | 49 +++++++++---------- .../recentactivity/RAImageIngestModule.java | 10 ++-- 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index b5bc552445..f1b5fc7007 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -24,14 +24,17 @@ package org.sleuthkit.autopsy.recentactivity; import java.io.*; import java.io.File; +import java.nio.file.Path; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; +import static java.util.TimeZone.getTimeZone; import java.util.logging.Level; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.openide.modules.InstalledFileLocator; +import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.ExecUtil; import org.sleuthkit.autopsy.coreutils.Logger; @@ -39,24 +42,19 @@ import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProcessTerminator; import org.sleuthkit.autopsy.ingest.IngestJobContext; +import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException; +import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService; import org.sleuthkit.autopsy.recentactivity.UsbDeviceIdMapper.USBInfo; import org.sleuthkit.datamodel.*; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; +import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; -import java.nio.file.Path; -import static java.util.TimeZone.getTimeZone; -import org.openide.util.Lookup; -import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException; -import org.sleuthkit.autopsy.ingest.IngestServices; -import org.sleuthkit.autopsy.ingest.ModuleDataEvent; -import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService; -import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException; /** * Extract windows registry data using regripper. Runs two versions of @@ -70,9 +68,8 @@ import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamExce }) class ExtractRegistry extends Extract { - private final Logger logger = Logger.getLogger(this.getClass().getName()); - private String RR_PATH; - private String RR_FULL_PATH; + private final static Logger logger = Logger.getLogger(ExtractRegistry.class.getName()); + private Path rrHome; // Path to the Autopsy version of RegRipper private Path rrFullHome; // Path to the full version of RegRipper private Content dataSource; @@ -104,19 +101,19 @@ class ExtractRegistry extends Extract { executableToRun = RIP_PL; } rrHome = rrRoot.toPath(); - RR_PATH = rrHome.resolve(executableToRun).toString(); + String rrPath = rrHome.resolve(executableToRun).toString(); rrFullHome = rrFullRoot.toPath(); - RR_FULL_PATH = rrFullHome.resolve(executableToRun).toString(); + String rrFullPath = rrFullHome.resolve(executableToRun).toString(); - if (!(new File(RR_PATH).exists())) { + if (!(new File(rrPath).exists())) { throw new IngestModuleException(Bundle.RegRipperNotFound()); } - if (!(new File(RR_FULL_PATH).exists())) { + if (!(new File(rrFullPath).exists())) { throw new IngestModuleException(Bundle.RegRipperFullNotFound()); } if (PlatformUtil.isWindowsOS()) { - rrCmd.add(RR_PATH); - rrFullCmd.add(RR_FULL_PATH); + rrCmd.add(rrPath); + rrFullCmd.add(rrFullPath); } else { String perl; File usrBin = new File("/usr/bin/perl"); @@ -129,9 +126,9 @@ class ExtractRegistry extends Extract { throw new IngestModuleException("perl not found in your system"); } rrCmd.add(perl); - rrCmd.add(RR_PATH); + rrCmd.add(rrPath); rrFullCmd.add(perl); - rrFullCmd.add(RR_FULL_PATH); + rrFullCmd.add(rrFullPath); } } @@ -416,7 +413,6 @@ class ExtractRegistry extends Extract { Element artroot = (Element) artroots.item(0); NodeList myartlist = artroot.getChildNodes(); String parentModuleName = NbBundle.getMessage(this.getClass(), "ExtractRegistry.parentModuleName.noSpace"); - String winver = ""; // If all artifact nodes should really go under one Blackboard artifact, need to process it differently switch (dataType) { @@ -730,7 +726,7 @@ class ExtractRegistry extends Extract { } 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)); @@ -797,7 +793,7 @@ class ExtractRegistry extends Extract { break; } } // for - + return true; } catch (FileNotFoundException ex) { logger.log(Level.SEVERE, "Error finding the registry file.", ex); //NON-NLS @@ -842,7 +838,7 @@ class ExtractRegistry extends Extract { if (line.contains(SECTION_DIVIDER) && previousLine != null) { if (previousLine.contains(userInfoSection)) { readUsers(bufferedReader, userSet); - } + } } previousLine = line; line = bufferedReader.readLine(); @@ -910,7 +906,7 @@ class ExtractRegistry extends Extract { } catch (ParseException ex) { logger.log(Level.SEVERE, "Error parsing the the date from the registry file", ex); //NON-NLS } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Error updating TSK_OS_ACCOUNT artifacts to include newly parsed data.", ex); //NON-NLS + logger.log(Level.SEVERE, "Error updating TSK_OS_ACCOUNT artifacts to include newly parsed data.", ex); //NON-NLS } return false; } @@ -940,8 +936,7 @@ class ExtractRegistry extends Extract { if (line.contains(userNameLabel)) { String userNameAndIdString = line.replace(userNameLabel, ""); userName = userNameAndIdString.substring(0, userNameAndIdString.lastIndexOf('[')).trim(); - } - else if (line.contains(sidLabel) && !userName.isEmpty()){ + } else if (line.contains(sidLabel) && !userName.isEmpty()) { String sid = line.replace(sidLabel, "").trim(); UserInfo userInfo = new UserInfo(userName, sid); //continue reading this users information until end of file or a blank line between users @@ -986,7 +981,7 @@ class ExtractRegistry extends Extract { /** * Create a UserInfo object * - * @param name - the os user account name + * @param name - the os user account name * @param userSidString - the SID for the user account */ private UserInfo(String name, String userSidString) { diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java index 5f1c31664a..16262cc98a 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java @@ -32,12 +32,12 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.ingest.DataSourceIngestModule; import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress; -import org.sleuthkit.autopsy.ingest.IngestServices; +import org.sleuthkit.autopsy.ingest.IngestJobContext; import org.sleuthkit.autopsy.ingest.IngestMessage; import org.sleuthkit.autopsy.ingest.IngestMessage.MessageType; -import org.sleuthkit.datamodel.Content; import org.sleuthkit.autopsy.ingest.IngestModule.ProcessResult; -import org.sleuthkit.autopsy.ingest.IngestJobContext; +import org.sleuthkit.autopsy.ingest.IngestServices; +import org.sleuthkit.datamodel.Content; /** * Recent activity image ingest module @@ -47,9 +47,9 @@ public final class RAImageIngestModule implements DataSourceIngestModule { private static final Logger logger = Logger.getLogger(RAImageIngestModule.class.getName()); private final List extractors = new ArrayList<>(); private final List browserExtractors = new ArrayList<>(); - private IngestServices services = IngestServices.getInstance(); + private final IngestServices services = IngestServices.getInstance(); private IngestJobContext context; - private StringBuilder subCompleted = new StringBuilder(); + private final StringBuilder subCompleted = new StringBuilder(); RAImageIngestModule() { } From 96e398fd88b9a0aa47dd70295ca5931ec498609e Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 20 Feb 2019 13:12:39 +0100 Subject: [PATCH 8/8] fix issues identified by codacy --- .../autopsy/timeline/FilteredEventsModel.java | 5 ++--- .../timeline/explorernodes/EventNode.java | 3 --- .../ui/detailview/datamodel/EventStripe.java | 21 +++++++------------ .../ui/detailview/tree/BaseTypeTreeItem.java | 3 +-- .../ui/detailview/tree/TreeComparator.java | 2 -- 5 files changed, 11 insertions(+), 23 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/FilteredEventsModel.java b/Core/src/org/sleuthkit/autopsy/timeline/FilteredEventsModel.java index e1019c4164..5cea826e2a 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/FilteredEventsModel.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/FilteredEventsModel.java @@ -38,7 +38,6 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.collections.ObservableMap; import javafx.collections.ObservableSet; -import org.apache.commons.collections4.CollectionUtils; import static org.apache.commons.collections4.CollectionUtils.emptyIfNull; import static org.apache.commons.collections4.CollectionUtils.isNotEmpty; import org.joda.time.DateTimeZone; @@ -539,8 +538,8 @@ public final class FilteredEventsModel { * directly from this file (file system * timestamps). * - * @return A Set of event IDs for the events that are derived from the - * given file. + * @return A Set of event IDs for the events that are derived from the given + * file. * * @throws org.sleuthkit.datamodel.TskCoreException */ diff --git a/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java b/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java index 522be16ab6..ea37959271 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java @@ -18,15 +18,12 @@ */ package org.sleuthkit.autopsy.timeline.explorernodes; -import com.google.common.collect.Iterables; import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.NoSuchElementException; import java.util.logging.Level; -import static java.util.stream.Collectors.joining; import javax.swing.Action; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventStripe.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventStripe.java index 41e052a678..0dc45ef06b 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventStripe.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/datamodel/EventStripe.java @@ -19,19 +19,14 @@ package org.sleuthkit.autopsy.timeline.ui.detailview.datamodel; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Sets; -import java.util.Collections; import java.util.Comparator; -import java.util.LinkedHashSet; import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; -import java.util.stream.Stream; -import javax.annotation.concurrent.Immutable; import org.sleuthkit.datamodel.DescriptionLoD; import org.sleuthkit.datamodel.timeline.EventType; @@ -76,14 +71,14 @@ public final class EventStripe implements MultiEvent { */ private final Set hashHits; - public static EventStripe merge(EventStripe u, EventStripe v) { //NOPMD - Preconditions.checkNotNull(u); - Preconditions.checkNotNull(v); - Preconditions.checkArgument(Objects.equals(u.description, v.description)); - Preconditions.checkArgument(Objects.equals(u.lod, v.lod)); - Preconditions.checkArgument(Objects.equals(u.type, v.type)); - Preconditions.checkArgument(Objects.equals(u.parent, v.parent)); - return new EventStripe(u, v); + public static EventStripe merge(EventStripe stripeA, EventStripe stripeB) { + Preconditions.checkNotNull(stripeA); + Preconditions.checkNotNull(stripeB); + Preconditions.checkArgument(Objects.equals(stripeA.description, stripeB.description)); + Preconditions.checkArgument(Objects.equals(stripeA.lod, stripeB.lod)); + Preconditions.checkArgument(Objects.equals(stripeA.type, stripeB.type)); + Preconditions.checkArgument(Objects.equals(stripeA.parent, stripeB.parent)); + return new EventStripe(stripeA, stripeB); } public EventStripe withParent(EventCluster parent) { diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/BaseTypeTreeItem.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/BaseTypeTreeItem.java index f593d55f19..4e5a8842c7 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/BaseTypeTreeItem.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/BaseTypeTreeItem.java @@ -26,7 +26,6 @@ import java.util.function.Supplier; import javafx.scene.control.TreeItem; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.timeline.ui.detailview.datamodel.DetailViewEvent; -import org.sleuthkit.datamodel.timeline.EventType; import org.sleuthkit.datamodel.timeline.EventTypeZoomLevel; /** @@ -48,7 +47,7 @@ class BaseTypeTreeItem extends EventTypeTreeItem { * this tree item */ BaseTypeTreeItem(DetailViewEvent event, Comparator> comparator) { - super (event.getEventType().getBaseType(), comparator); + super(event.getEventType().getBaseType(), comparator); } @ThreadConfined(type = ThreadConfined.ThreadType.JFX) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/TreeComparator.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/TreeComparator.java index eb32552e25..8ec04e40d5 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/TreeComparator.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/tree/TreeComparator.java @@ -19,11 +19,9 @@ package org.sleuthkit.autopsy.timeline.ui.detailview.tree; import java.util.Comparator; -import java.util.function.Function; import javafx.scene.control.TreeItem; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.timeline.ui.detailview.datamodel.DetailViewEvent; -import org.sleuthkit.datamodel.timeline.EventType; /** * Comparators of TreeItems: these are the ways the EventsTree can be sorted.