diff --git a/Core/src/org/sleuthkit/autopsy/core/layer.xml b/Core/src/org/sleuthkit/autopsy/core/layer.xml index 8bdde0f317..546ec757ec 100644 --- a/Core/src/org/sleuthkit/autopsy/core/layer.xml +++ b/Core/src/org/sleuthkit/autopsy/core/layer.xml @@ -78,6 +78,7 @@ + @@ -201,6 +202,10 @@ + + + + diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java index 002f87acba..dbd06ac8dc 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java @@ -29,6 +29,8 @@ import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootChildren.FileSizeNod import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootNode; import org.sleuthkit.autopsy.datamodel.FileTypes.FileTypesNode; import org.sleuthkit.autopsy.datamodel.accounts.Accounts; +import org.sleuthkit.autopsy.md5search.CorrelationAttributeInstanceChildNode; +import org.sleuthkit.autopsy.md5search.DlgCorrelationAttributeInstanceNode; /** * Visitor pattern that goes over all nodes in the directory tree. This includes @@ -125,6 +127,10 @@ public interface DisplayableItemNodeVisitor { T visit(CentralRepoCommonAttributeInstanceNode crfin); T visit(InstanceCountNode icn); + + T visit(CorrelationAttributeInstanceChildNode caicn); + + T visit(DlgCorrelationAttributeInstanceNode cain); //DLG: /* * Tags @@ -214,6 +220,16 @@ public interface DisplayableItemNodeVisitor { return defaultVisit(icn); } + @Override + public T visit(CorrelationAttributeInstanceChildNode caicn){ + return defaultVisit(caicn); + } + + @Override + public T visit(DlgCorrelationAttributeInstanceNode cain) { + return defaultVisit(cain); + } + @Override public T visit(CentralRepoCommonAttributeInstanceNode crfin){ return defaultVisit(crfin); diff --git a/Core/src/org/sleuthkit/autopsy/md5search/Bundle.properties b/Core/src/org/sleuthkit/autopsy/md5search/Bundle.properties new file mode 100755 index 0000000000..59bdbf31bf --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/Bundle.properties @@ -0,0 +1,6 @@ + +Md5SearchDialog.jButton1.text=Search +Md5SearchDialog.jTextField1.text= +Md5SearchDialog.jLabel1.text=Correlation Property Value: +Md5SearchDialog.jLabel2.text=Correlation Property Type: +Md5SearchDialog.jTextArea1.text=Type a value into the Correlation Property Value field. When the input type is detected, the Correlation Property Type field will become available and default to the detected input type. diff --git a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNode.java b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNode.java new file mode 100755 index 0000000000..49c525bd7a --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNode.java @@ -0,0 +1,123 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import javax.swing.Action; +import org.openide.nodes.Children; +import org.openide.nodes.Sheet; +import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.commonfilesearch.CaseDBCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; +import org.sleuthkit.autopsy.datamodel.NodeProperty; + +/** + * //DLG: + */ +public final class CorrelationAttributeInstanceChildNode extends DisplayableItemNode { + private String caseName; + private String dataSourceName; + //DLG: final ? knownStatus + private String fullPath; + //DLG: final String comment + //DLG: final String deviceId + private String name; + private String parent; + + public CorrelationAttributeInstanceChildNode(Children children) { + super(children); + } + + //CorrelationAttributeInstanceChildNode(Children children) { + // init(null); + //} + + private void init(Map map) { + caseName = (String)map.get("caseName"); + dataSourceName = (String)map.get("dataSourceName"); + fullPath = (String)map.get("fullPath"); + name = (String)map.get("name"); + parent = (String)map.get("parent"); + } + + @Override + public Action[] getActions(boolean context){ + List actionsList = new ArrayList<>(); + + actionsList.addAll(Arrays.asList(super.getActions(true))); + + return actionsList.toArray(new Action[actionsList.size()]); + } + + /*@Override + public T accept(DisplayableItemNodeVisitor visitor) { + return visitor.visit(this); + }*/ + + @Override + public T accept(DisplayableItemNodeVisitor visitor) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public boolean isLeafTypeNode() { + return true; + } + + @Override + public String getItemType() { + //objects of type FileNode will co-occur in the treetable with objects + // of this type and they will need to provide the same key + return CorrelationAttributeInstanceChildNode.class.getName(); + } + + @NbBundle.Messages({ + "CorrelationAttributeInstanceChildNode.columnName.case=Case", + "CorrelationAttributeInstanceChildNode.columnName.dataSource=Data Source", + "CorrelationAttributeInstanceChildNode.columnName.known=Known", + "CorrelationAttributeInstanceChildNode.columnName.path=Path", + "CorrelationAttributeInstanceChildNode.columnName.comment=Comment", + "CorrelationAttributeInstanceChildNode.columnName.device=Device" + }) + @Override + protected Sheet createSheet(){ + Sheet sheet = new Sheet(); + Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); + + if(sheetSet == null){ + sheetSet = Sheet.createPropertiesSet(); + sheet.put(sheetSet); + } + + + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_case(), + Bundle.CorrelationAttributeInstanceNode_columnName_case(), "", name)); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_dataSource(), + Bundle.CorrelationAttributeInstanceNode_columnName_dataSource(), "", parent)); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_known(), + Bundle.CorrelationAttributeInstanceNode_columnName_known(), "", "")); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_path(), + Bundle.CorrelationAttributeInstanceNode_columnName_path(), "", dataSourceName)); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_comment(), + Bundle.CorrelationAttributeInstanceNode_columnName_comment(), "", "")); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_device(), + Bundle.CorrelationAttributeInstanceNode_columnName_device(), "", caseName)); + + return sheet; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNodeFactory.java b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNodeFactory.java new file mode 100755 index 0000000000..b30a11e06f --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNodeFactory.java @@ -0,0 +1,68 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import java.io.File; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.openide.nodes.ChildFactory; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.openide.util.lookup.Lookups; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.datamodel.KeyValue; +import org.sleuthkit.autopsy.datamodel.KeyValueNode; + +/** + * //DLG: + */ +final class CorrelationAttributeInstanceChildNodeFactory extends ChildFactory { + private final Collection correlationInstances; + + CorrelationAttributeInstanceChildNodeFactory(Collection correlationInstances) { + this.correlationInstances = correlationInstances; + } + + @Override + protected boolean createKeys(List list) { + for (CorrelationAttributeInstance instance : correlationInstances) { + Map properties = new HashMap<>(); //DLG: + + final String caseName = instance.getCorrelationCase().getDisplayName(); + final String dataSourceName = instance.getCorrelationDataSource().getName(); + //DLG: final ? knownStatus + final String fullPath = instance.getFilePath(); + //DLG: final String comment + //DLG: final String deviceId + + final File file = new File(fullPath); + final String name = file.getName(); + final String parent = file.getParent(); + + properties.put("caseName", caseName); + properties.put("dataSourceName", dataSourceName); + properties.put("knownStatus", ""); //DLG: + properties.put("fullPath", fullPath); + properties.put("comment", ""); //DLG: + properties.put("deviceId", ""); //DLG: + properties.put("name", name); + properties.put("parent", parent); + + list.add(new KeyValue(String.valueOf(instance.getID()), properties, instance.getID())); + } + return true; + } + + @Override + protected Node createNodeForKey(KeyValue key) { + Map map = key.getMap(); + Node kvNode = new KeyValueNode(key, Children.LEAF, Lookups.fixed(correlationInstances.toArray())); + //DLG: Node resultNode = new CorrelationAttributeInstanceChildNode(kvNode); + return null; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceRootNode.java b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceRootNode.java new file mode 100755 index 0000000000..43b67b57a9 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceRootNode.java @@ -0,0 +1,162 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.md5search; + +import org.sleuthkit.autopsy.commonfilesearch.*; +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.swing.Action; +import org.openide.nodes.ChildFactory; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.openide.nodes.Sheet; +import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; +import org.sleuthkit.autopsy.datamodel.NodeProperty; + +/** + * Used by the Common Files search feature to encapsulate instances of a given + * MD5s matched in the search. These nodes will be children of Md5Nodes. + * + * Use this type for files which are not in the current case, but from the + * Central Repo. Contrast with SleuthkitCase which should be used + * when the FileInstance was found in the case presently open in Autopsy. + */ +final class CorrelationAttributeInstanceRootNode extends DisplayableItemNode { + + public CorrelationAttributeInstanceRootNode(Children children) { + super(children); + } + + //private final CorrelationAttributeInstance crFile; + + //CorrelationAttributeInstanceRootNode(CorrelationAttributeSearchResults data) { + //super(Children.create(new FileInstanceNodeFactory(data), true)); + //} + + @Override + public Action[] getActions(boolean context){ + List actionsList = new ArrayList<>(); + + actionsList.addAll(Arrays.asList(super.getActions(true))); + + return actionsList.toArray(new Action[actionsList.size()]); + } + + @Override + public T accept(DisplayableItemNodeVisitor visitor) { + return null; + //return visitor.visit(this); + } + + @Override + public boolean isLeafTypeNode() { + return true; + } + + @Override + public String getItemType() { + //objects of type FileNode will co-occur in the treetable with objects + // of this type and they will need to provide the same key + return CaseDBCommonAttributeInstanceNode.class.getName(); + } + + @NbBundle.Messages({ + "CorrelationAttributeInstanceNode.columnName.case=Case", + "CorrelationAttributeInstanceNode.columnName.dataSource=Data Source", + "CorrelationAttributeInstanceNode.columnName.known=Known", + "CorrelationAttributeInstanceNode.columnName.path=Path", + "CorrelationAttributeInstanceNode.columnName.comment=Comment", + "CorrelationAttributeInstanceNode.columnName.device=Device" + }) + @Override + protected Sheet createSheet(){ + Sheet sheet = new Sheet(); + /*Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); + + if(sheetSet == null){ + sheetSet = Sheet.createPropertiesSet(); + sheet.put(sheetSet); + } + + final CorrelationAttributeInstance centralRepoFile = this.getCorrelationAttributeInstance(); + + final String caseName = centralRepoFile.getCorrelationCase().getDisplayName(); + final String dataSourceName = centralRepoFile.getCorrelationDataSource().getName(); + //DLG: final ? knownStatus + final String fullPath = centralRepoFile.getFilePath(); + //DLG: final String comment + //DLG: final String deviceId + + final File file = new File(fullPath); + final String name = file.getName(); + final String parent = file.getParent(); + + + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_case(), + Bundle.CorrelationAttributeInstanceNode_columnName_case(), "", name)); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_dataSource(), + Bundle.CorrelationAttributeInstanceNode_columnName_dataSource(), "", parent)); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_known(), + Bundle.CorrelationAttributeInstanceNode_columnName_known(), "", "")); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_path(), + Bundle.CorrelationAttributeInstanceNode_columnName_path(), "", dataSourceName)); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_comment(), + Bundle.CorrelationAttributeInstanceNode_columnName_comment(), "", "")); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_device(), + Bundle.CorrelationAttributeInstanceNode_columnName_device(), "", caseName));*/ + + return sheet; + } + + /** + * Child generator for SleuthkitCaseFileInstanceNode of + * CommonAttributeValueNode. + */ + static class FileInstanceNodeFactory extends ChildFactory { + + private final CommonAttributeValue descendants; + + FileInstanceNodeFactory(CommonAttributeValue descendants) { + this.descendants = descendants; + } + + @Override + protected boolean createKeys(List list) { + return true; + } + + /*@Override + protected Node[] createNodesForKey(AbstractCommonAttributeInstance searchResult) { + return null; + //return searchResult.generateNodes(); + }*/ + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeSearchResults.java new file mode 100755 index 0000000000..5c1e0ee004 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeSearchResults.java @@ -0,0 +1,25 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import java.util.ArrayList; +import java.util.List; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; + +/** + * //DLG: + */ +public class CorrelationAttributeSearchResults { + List correlationInstances = new ArrayList<>(); + + CorrelationAttributeSearchResults(List correlationInstances) { + this.correlationInstances = correlationInstances; + } + + List getCorrelationAttributeInstances() { + return correlationInstances; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/DlgCorrelationAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/md5search/DlgCorrelationAttributeInstanceNode.java new file mode 100755 index 0000000000..1e6a51850c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/DlgCorrelationAttributeInstanceNode.java @@ -0,0 +1,143 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.md5search; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.swing.Action; +import org.openide.nodes.Children; +import org.openide.nodes.Sheet; +import org.openide.util.NbBundle; +import org.openide.util.lookup.Lookups; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; +import org.sleuthkit.autopsy.datamodel.NodeProperty; + +/** + * Used by the Common Files search feature to encapsulate instances of a given + * MD5s matched in the search. These nodes will be children of Md5Nodes. + * + * Use this type for files which are not in the current case, but from the + * Central Repo. Contrast with SleuthkitCase which should be used + * when the FileInstance was found in the case presently open in Autopsy. + */ +public class DlgCorrelationAttributeInstanceNode extends DisplayableItemNode { + + private final CorrelationAttributeInstance crFile; + + DlgCorrelationAttributeInstanceNode(CorrelationAttributeInstance content) { + super(Children.LEAF, Lookups.fixed(content)); + this.crFile = content; + this.setDisplayName(new File(this.crFile.getFilePath()).getName()); + } + + public CorrelationAttributeInstance getCorrelationAttributeInstance(){ + return this.crFile; + } + + @Override + public Action[] getActions(boolean context){ + List actionsList = new ArrayList<>(); + + actionsList.addAll(Arrays.asList(super.getActions(true))); + + return actionsList.toArray(new Action[actionsList.size()]); + } + + @Override + public T accept(DisplayableItemNodeVisitor visitor) { + return visitor.visit(this); + } + + @Override + public boolean isLeafTypeNode() { + return true; + } + + @Override + public String getItemType() { + //objects of type FileNode will co-occur in the treetable with objects + // of this type and they will need to provide the same key + return DlgCorrelationAttributeInstanceNode.class.getName(); + } + + @NbBundle.Messages({ + "DlgCorrelationAttributeInstanceNode.columnName.name=Name", + "DlgCorrelationAttributeInstanceNode.columnName.case=Case", + "DlgCorrelationAttributeInstanceNode.columnName.dataSource=Data Source", + "DlgCorrelationAttributeInstanceNode.columnName.known=Known", + "DlgCorrelationAttributeInstanceNode.columnName.path=Path", + "DlgCorrelationAttributeInstanceNode.columnName.comment=Comment", + "DlgCorrelationAttributeInstanceNode.columnName.device=Device" + }) + @Override + protected Sheet createSheet(){ + Sheet sheet = new Sheet(); + Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); + + if(sheetSet == null){ + sheetSet = Sheet.createPropertiesSet(); + sheet.put(sheetSet); + } + + final CorrelationAttributeInstance centralRepoFile = this.getCorrelationAttributeInstance(); + + final String path = centralRepoFile.getFilePath(); + final File file = new File(path); + final String name = file.getName(); + //DLG: final String parent = file.getParent(); + final String caseName = centralRepoFile.getCorrelationCase().getDisplayName(); + final CorrelationDataSource dataSource = centralRepoFile.getCorrelationDataSource(); + final String dataSourceName = dataSource.getName(); + final String known = centralRepoFile.getKnownStatus().getName(); + final String comment = centralRepoFile.getComment(); + final String device = dataSource.getDeviceID(); + + final String NO_DESCR = ""; + + sheetSet.put(new NodeProperty<>( + Bundle.DlgCorrelationAttributeInstanceNode_columnName_name(), + Bundle.DlgCorrelationAttributeInstanceNode_columnName_name(), NO_DESCR, name)); + sheetSet.put(new NodeProperty<>( + Bundle.DlgCorrelationAttributeInstanceNode_columnName_case(), + Bundle.DlgCorrelationAttributeInstanceNode_columnName_case(), NO_DESCR, caseName)); + sheetSet.put(new NodeProperty<>( + Bundle.DlgCorrelationAttributeInstanceNode_columnName_dataSource(), + Bundle.DlgCorrelationAttributeInstanceNode_columnName_dataSource(), NO_DESCR, dataSourceName)); + sheetSet.put(new NodeProperty<>( + Bundle.DlgCorrelationAttributeInstanceNode_columnName_known(), + Bundle.DlgCorrelationAttributeInstanceNode_columnName_known(), NO_DESCR, known)); + sheetSet.put(new NodeProperty<>( + Bundle.DlgCorrelationAttributeInstanceNode_columnName_path(), + Bundle.DlgCorrelationAttributeInstanceNode_columnName_path(), NO_DESCR, path)); + sheetSet.put(new NodeProperty<>( + Bundle.DlgCorrelationAttributeInstanceNode_columnName_comment(), + Bundle.DlgCorrelationAttributeInstanceNode_columnName_comment(), NO_DESCR, comment)); + sheetSet.put(new NodeProperty<>( + Bundle.DlgCorrelationAttributeInstanceNode_columnName_device(), + Bundle.DlgCorrelationAttributeInstanceNode_columnName_device(), NO_DESCR, device)); + + return sheet; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterChildren.java b/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterChildren.java new file mode 100755 index 0000000000..6ca7c7540c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterChildren.java @@ -0,0 +1,39 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import org.openide.nodes.Children; +import org.openide.nodes.FilterNode; +import org.openide.nodes.Node; + +/** + * //DLG: + */ +class DlgFilterChildren extends FilterNode.Children { + + public static Children createInstance(Node wrappedNode, boolean createChildren) { + + if (createChildren) { + return new DlgFilterChildren(wrappedNode); + } else { + return Children.LEAF; + } + } + + DlgFilterChildren(Node wrappedNode) { + super(wrappedNode); + } + + @Override + protected Node copyNode(Node nodeToCopy) { + return new DlgFilterNode(nodeToCopy, false); + } + + @Override + protected Node[] createNodes(Node key) { + return new Node[]{this.copyNode(key)}; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterNode.java b/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterNode.java new file mode 100755 index 0000000000..c746637544 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterNode.java @@ -0,0 +1,79 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import org.openide.nodes.FilterNode; +import org.openide.nodes.Node; +import org.openide.util.NbBundle; +import org.openide.util.lookup.Lookups; +import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo; +import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; + +/** + * //DLG: + */ +public class DlgFilterNode extends FilterNode { + + private final boolean createChildren; + private final boolean forceUseWrappedDisplayName; + private String columnOrderKey = "NONE"; + + public DlgFilterNode(Node node, boolean createChildren) { + super(node, DlgFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); + this.forceUseWrappedDisplayName = false; + this.createChildren = createChildren; + } + + public DlgFilterNode(Node node, boolean createChildren, String columnOrderKey) { + super(node, DlgFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); + this.forceUseWrappedDisplayName = false; + this.createChildren = createChildren; + this.columnOrderKey = columnOrderKey; + } + + /*public DlgFilterNode(Node node, int childLayerDepth) { + super(node, TableFilterChildrenWithDescendants.createInstance(node, childLayerDepth), Lookups.proxy(node)); + this.createChildren = true; + this.forceUseWrappedDisplayName = true; + }*/ + + @Override + public String getDisplayName() { + if (this.forceUseWrappedDisplayName) { + return super.getDisplayName(); + } else if (createChildren) { + return NbBundle.getMessage(this.getClass(), "TableFilterNode.displayName.text"); + } else { + return super.getDisplayName(); + } + } + + public void setChildNodeSelectionInfo(NodeSelectionInfo selectedChildNodeInfo) { + /* + * Currently, child selection is only supported for nodes selected in + * the tree view and decorated with a DataResultFilterNode. + */ + if (getOriginal() instanceof DataResultFilterNode) { + ((DataResultFilterNode) getOriginal()).setChildNodeSelectionInfo(selectedChildNodeInfo); + } + } + + public NodeSelectionInfo getChildNodeSelectionInfo() { + /* + * Currently, child selection is only supported for nodes selected in + * the tree view and decorated with a DataResultFilterNode. + */ + if (getOriginal() instanceof DataResultFilterNode) { + return ((DataResultFilterNode) getOriginal()).getChildNodeSelectionInfo(); + } else { + return null; + } + } + + public String getColumnOrderKey() { + return columnOrderKey; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchChildren.java b/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchChildren.java new file mode 100755 index 0000000000..3f2c2ad403 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchChildren.java @@ -0,0 +1,34 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import java.util.List; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; +import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; + +/** + * //DLG: + */ +class DlgSearchChildren extends Children.Keys { + + DlgSearchChildren(boolean lazy, List fileList) { + super(lazy); + this.setKeys(fileList); + } + + @Override + protected Node[] createNodes(CorrelationAttributeInstance t) { + //DLG: + Node[] node = new Node[1]; + //DLG: + node[0] = new DlgCorrelationAttributeInstanceNode(t); + return node; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchNode.java b/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchNode.java new file mode 100755 index 0000000000..6d1a75d39b --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchNode.java @@ -0,0 +1,29 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import java.util.List; +import org.openide.nodes.AbstractNode; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; + +/** + * //DLG: + */ +class DlgSearchNode extends AbstractNode { + + private DlgSearchChildren children; + + DlgSearchNode(List keys) { + super(new DlgSearchChildren(true, keys)); + this.children = (DlgSearchChildren) this.getChildren(); + } + + @Override + public String getName() { + //DLG: + return /*NbBundle.getMessage(this.getClass(), */"SearchNode.getName.text"/*)*/; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchAction.java b/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchAction.java new file mode 100755 index 0000000000..a231e389fb --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchAction.java @@ -0,0 +1,60 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.md5search; + +import java.awt.event.ActionEvent; +import org.openide.util.HelpCtx; +import org.openide.util.NbBundle; +import org.openide.util.actions.CallableSystemAction; +import org.sleuthkit.autopsy.casemodule.Case; + +/** + * //DLG: + */ +public class Md5SearchAction extends CallableSystemAction { + + @Override + public boolean isEnabled() { + return super.isEnabled() && Case.isCaseOpen(); + } + + @Override + public void actionPerformed(ActionEvent event) { + performAction(); + } + + @Override + public void performAction() { + Md5SearchDialog dialog = new Md5SearchDialog(); + dialog.display(); + } + + @NbBundle.Messages({ + "Md5SearchAction.getName.text=Correlation Attribute Search"}) + @Override + public String getName() { + return Bundle.Md5SearchAction_getName_text(); + } + + @Override + public HelpCtx getHelpCtx() { + return HelpCtx.DEFAULT_HELP; + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.form b/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.form new file mode 100755 index 0000000000..2ecd2f4475 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.form @@ -0,0 +1,145 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.java b/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.java new file mode 100755 index 0000000000..3d6413e82a --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.java @@ -0,0 +1,282 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.swing.JFrame; +import javax.swing.SwingWorker; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import org.openide.explorer.ExplorerManager; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.openide.util.Exceptions; +import org.openide.util.NbBundle; +import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributesSearchResultsViewerTable; +import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; +import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent; +import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; +import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; + +/** + * + * @author dgrove + */ +public class Md5SearchDialog extends javax.swing.JDialog { + private static final String FILES_CORRELATION_TYPE = "Files"; + private final List correlationTypes; + private final Pattern md5Pattern; + + /** + * Creates new form Md5SearchDialog + */ + @NbBundle.Messages({"Md5SearchDialog.title=Correlation Property Search"}) + public Md5SearchDialog() { + super((JFrame) WindowManager.getDefault().getMainWindow(), Bundle.Md5SearchDialog_title(), true); + this.correlationTypes = new ArrayList<>(); + this.md5Pattern = Pattern.compile("^[a-fA-F0-9]{32}$"); // NON-NLS + initComponents(); + customizeComponents(); + } + + private void search() { + new SwingWorker, Void>() { + + @Override + protected List doInBackground() { + List correlationTypes; + List correlationInstances = new ArrayList<>(); + + try { + correlationTypes = EamDb.getInstance().getDefinedCorrelationTypes(); + for (CorrelationAttributeInstance.Type type : correlationTypes) { + if (type.getId() == CorrelationAttributeInstance.FILES_TYPE_ID) { + correlationInstances = EamDb.getInstance().getArtifactInstancesByTypeValue(type, jTextField1.getText()); + break; + } + } + } catch (Exception ex) { + //DLG: + } + + return correlationInstances; + } + + @Override + protected void done() { + try { + super.done(); + List correlationInstances = this.get(); + //DLG: Node rootNode = new CorrelationAttributeInstanceRootNode(searchResults); + //DataResultFilterNode dataResultFilterNode = new DataResultFilterNode(rootNode, ExplorerManager.find(Md5SearchDialog.this)); + //TableFilterNode tableFilterWithDescendantsNode = new TableFilterNode(dataResultFilterNode, 3); + DataResultViewerTable table = new CommonAttributesSearchResultsViewerTable(); + Collection viewers = new ArrayList<>(1); + viewers.add(table); + + DlgSearchNode searchNode = new DlgSearchNode(correlationInstances); + DlgFilterNode tableFilterNode = new DlgFilterNode(searchNode, true, searchNode.getName()); + + //Node rootNode; + //Children childNodes = Children.create(new CorrelationAttributeInstanceChildNodeFactory(correlationInstances), true); + //rootNode = new AbstractNode(childNodes); + DataResultTopComponent results = DataResultTopComponent.createInstance( + "Files", "Correlation Property Search", tableFilterNode, HIDE_ON_CLOSE, viewers); + } catch (InterruptedException ex) { + Exceptions.printStackTrace(ex); //DLG: + } catch (ExecutionException ex) { + Exceptions.printStackTrace(ex); //DLG: + } + } + }.execute(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + jTextField1 = new javax.swing.JTextField(); + jButton1 = new javax.swing.JButton(); + correlationTypeComboBox = new javax.swing.JComboBox<>(); + jLabel2 = new javax.swing.JLabel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jTextArea1 = new javax.swing.JTextArea(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setResizable(false); + + org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(Md5SearchDialog.class, "Md5SearchDialog.jLabel1.text")); // NOI18N + + jTextField1.setText(org.openide.util.NbBundle.getMessage(Md5SearchDialog.class, "Md5SearchDialog.jTextField1.text")); // NOI18N + jTextField1.addInputMethodListener(new java.awt.event.InputMethodListener() { + public void caretPositionChanged(java.awt.event.InputMethodEvent evt) { + } + public void inputMethodTextChanged(java.awt.event.InputMethodEvent evt) { + jTextField1InputMethodTextChanged(evt); + } + }); + jTextField1.addPropertyChangeListener(new java.beans.PropertyChangeListener() { + public void propertyChange(java.beans.PropertyChangeEvent evt) { + jTextField1PropertyChange(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(Md5SearchDialog.class, "Md5SearchDialog.jButton1.text")); // NOI18N + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(Md5SearchDialog.class, "Md5SearchDialog.jLabel2.text")); // NOI18N + + jTextArea1.setEditable(false); + jTextArea1.setColumns(20); + jTextArea1.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N + jTextArea1.setLineWrap(true); + jTextArea1.setRows(5); + jTextArea1.setText(org.openide.util.NbBundle.getMessage(Md5SearchDialog.class, "Md5SearchDialog.jTextArea1.text")); // NOI18N + jTextArea1.setWrapStyleWord(true); + jTextArea1.setBorder(null); + jTextArea1.setOpaque(false); + jScrollPane1.setViewportView(jTextArea1); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(11, 11, 11) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jButton1, javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2) + .addComponent(jLabel1)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(correlationTypeComboBox, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jTextField1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(correlationTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jButton1) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + + private void jTextField1PropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_jTextField1PropertyChange + //DLG: + }//GEN-LAST:event_jTextField1PropertyChange + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + search(); + }//GEN-LAST:event_jButton1ActionPerformed + + private void jTextField1InputMethodTextChanged(java.awt.event.InputMethodEvent evt) {//GEN-FIRST:event_jTextField1InputMethodTextChanged + //DLG: + }//GEN-LAST:event_jTextField1InputMethodTextChanged + + private void customizeComponents() { + jButton1.setEnabled(false); + correlationTypeComboBox.setEnabled(false); + + /* + * Add correlation types to the combo-box. + */ + try { + EamDb dbManager = EamDb.getInstance(); + correlationTypes.clear(); + correlationTypes.addAll(dbManager.getDefinedCorrelationTypes()); + } catch (EamDbException ex) { + Exceptions.printStackTrace(ex); + } + + for (CorrelationAttributeInstance.Type type : correlationTypes) { + correlationTypeComboBox.addItem(type.getDisplayName()); + } + + /* + * Create listener for text input. + */ + jTextField1.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void changedUpdate(DocumentEvent e) { + validateInput(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + validateInput(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + validateInput(); + } + + private void validateInput() { + Matcher matcher = md5Pattern.matcher(jTextField1.getText().trim()); + if (matcher.find()) { + jButton1.setEnabled(true); + correlationTypeComboBox.setEnabled(true); + correlationTypeComboBox.setSelectedItem(FILES_CORRELATION_TYPE); + } else { + jButton1.setEnabled(false); + correlationTypeComboBox.setEnabled(false); + } + } + }); + } + + public void display() { + this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); + setVisible(true); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox correlationTypeComboBox; + private javax.swing.JButton jButton1; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTextArea jTextArea1; + private javax.swing.JTextField jTextField1; + // End of variables declaration//GEN-END:variables +}