Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
MessageNode.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2019-2020 Basis Technology Corp.
5 * Contact: carrier <at> sleuthkit <dot> org
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19package org.sleuthkit.autopsy.communications.relationships;
20
21import java.awt.event.ActionEvent;
22import java.util.logging.Level;
23import javax.swing.AbstractAction;
24import javax.swing.Action;
25import org.apache.commons.lang3.StringUtils;
26import org.openide.nodes.Sheet;
27import org.openide.util.Exceptions;
28import org.openide.util.NbBundle.Messages;
29import org.sleuthkit.autopsy.casemodule.Case;
30import org.sleuthkit.autopsy.coreutils.Logger;
31import org.sleuthkit.autopsy.datamodel.NodeProperty;
32import org.sleuthkit.datamodel.BlackboardArtifact;
33import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME;
34import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT;
35import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM;
36import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO;
37import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM;
38import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO;
39import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT;
40import org.sleuthkit.datamodel.TskCoreException;
41import static org.sleuthkit.autopsy.communications.relationships.RelationshipsNodeUtilities.getAttributeDisplayString;
42import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
43import org.sleuthkit.datamodel.Account;
44import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
45import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE;
46import org.sleuthkit.datamodel.BlackboardAttribute;
47import org.sleuthkit.datamodel.CommunicationsManager;
48import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil;
49import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments;
50
54class MessageNode extends BlackboardArtifactNode {
55
56 public static final String UNTHREADED_ID = "<UNTHREADED>";
57
58 private static final Logger logger = Logger.getLogger(MessageNode.class.getName());
59
60 private final String threadID;
61
62 private final Action preferredAction;
63
64 private final Action defaultNoopAction = new DefaultMessageAction();
65
66 MessageNode(BlackboardArtifact artifact, String threadID, Action preferredAction) {
67 super(artifact);
68
69 this.preferredAction = preferredAction;
70
71 final String stripEnd = StringUtils.stripEnd(artifact.getDisplayName(), "s"); // NON-NLS
72 String removeEndIgnoreCase = StringUtils.removeEndIgnoreCase(stripEnd, "message"); // NON-NLS
73 setDisplayName(removeEndIgnoreCase.isEmpty() ? stripEnd : removeEndIgnoreCase);
74
75 this.threadID = threadID;
76 }
77
78 @Messages({
79 "MessageNode_Node_Property_Type=Type",
80 "MessageNode_Node_Property_From=From",
81 "MessageNode_Node_Property_To=To",
82 "MessageNode_Node_Property_Date=Date",
83 "MessageNode_Node_Property_Subject=Subject",
84 "MessageNode_Node_Property_Attms=Attachment Count"
85 })
86
87 @Override
88 protected Sheet createSheet() {
89 Sheet sheet = Sheet.createDefault();
90 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
91 if (sheetSet == null) {
92 sheetSet = Sheet.createPropertiesSet();
93 sheet.put(sheetSet);
94 }
95
96 sheetSet.put(new NodeProperty<>("Type", Bundle.MessageNode_Node_Property_Type(), "", getDisplayName())); //NON-NLS
97
98 final BlackboardArtifact artifact = getArtifact();
99 BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(artifact.getArtifactTypeID());
100
101 if (fromID == null
102 || (fromID != TSK_EMAIL_MSG
103 && fromID != TSK_MESSAGE)) {
104 return sheet;
105 }
106 if (threadID != null) {
107 sheetSet.put(new NodeProperty<>("ThreadID", "ThreadID", "", threadID)); //NON-NLS
108 }
109 sheetSet.put(new NodeProperty<>("Subject", Bundle.MessageNode_Node_Property_Subject(), "",
110 getAttributeDisplayString(artifact, TSK_SUBJECT))); //NON-NLS
111 try {
112 sheetSet.put(new NodeProperty<>("Attms", Bundle.MessageNode_Node_Property_Attms(), "", getAttachmentsCount())); //NON-NLS
113 } catch (TskCoreException ex) {
114 logger.log(Level.WARNING, "Error loading attachment count for " + artifact, ex); //NON-NLS
115 }
116
117 String msg_from = getAttributeDisplayString(artifact, TSK_EMAIL_FROM);
118 String msg_to = getAttributeDisplayString(artifact, TSK_EMAIL_TO);
119 String date = getAttributeDisplayString(artifact, TSK_DATETIME_SENT);
120
121 Account account_from = null;
122 Account account_to = null;
123
124 try {
125 CommunicationsManager manager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager();
126
127 if (msg_from.isEmpty()) {
128 msg_from = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM);
129 if(manager != null && !msg_from.isEmpty()) {
130 account_from = manager.getAccount(Account.Type.PHONE, msg_from);
131 }
132 } else if(manager != null) {
133 // To email address sometime is in the format <name>: <email>
134 String toStr = msg_to;
135 String[] strSplit = msg_to.split(":");
136 if(strSplit.length > 0) {
137 toStr = strSplit[strSplit.length-1].trim();
138 }
139 account_from = manager.getAccount(Account.Type.EMAIL, toStr);
140 }
141
142 if (msg_to.isEmpty()) {
143 msg_to = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO);
144 if(manager != null && !msg_to.isEmpty()) {
145 account_to = manager.getAccount(Account.Type.PHONE, msg_to);
146 }
147 } else if(manager != null) {
148 account_to = manager.getAccount(Account.Type.EMAIL, msg_to);
149 }
150
151 if (date.isEmpty()) {
152 date = getAttributeDisplayString(artifact, TSK_DATETIME);
153 }
154 } catch (TskCoreException ex) {
155
156 }
157
158 sheetSet.put(new AccountNodeProperty<>("From", Bundle.MessageNode_Node_Property_From(),
159 msg_from, account_from)); //NON-NLS
160 sheetSet.put(new AccountNodeProperty<>("To", Bundle.MessageNode_Node_Property_To(),
161 msg_to, account_to)); //NON-NLS
162 sheetSet.put(new NodeProperty<>("Date", Bundle.MessageNode_Node_Property_Date(), "",
163 date)); //NON-NLS
164
165 return sheet;
166 }
167
174 @Override
175 public String getSourceName() {
176 return getDisplayName();
177 }
178
179 String getThreadID() {
180 return threadID;
181 }
182
183 @Override
184 public Action getPreferredAction() {
185 return preferredAction != null ? preferredAction : defaultNoopAction;
186 }
187
188 private int getAttachmentsCount() throws TskCoreException {
189 final BlackboardArtifact artifact = getArtifact();
190 int attachmentsCount;
191
192 // Attachments are specified in an attribute TSK_ATTACHMENTS as JSON attribute
193 BlackboardAttribute attachmentsAttr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ATTACHMENTS));
194 if (attachmentsAttr != null) {
195 try {
196 MessageAttachments msgAttachments = BlackboardJsonAttrUtil.fromAttribute(attachmentsAttr, MessageAttachments.class);
197 return msgAttachments.getAttachmentsCount();
198 } catch (BlackboardJsonAttrUtil.InvalidJsonException ex) {
199 logger.log(Level.WARNING, String.format("Unable to parse json for MessageAttachments object in artifact: %s", artifact.getName()), ex);
200 return 0;
201 }
202 } else { // legacy attachments may be children of message artifact.
203 attachmentsCount = artifact.getChildrenCount();
204 }
205
206 return attachmentsCount;
207 }
208
212 private class DefaultMessageAction extends AbstractAction {
213
214 private static final long serialVersionUID = 1L;
215
216 @Override
217 public void actionPerformed(ActionEvent e) {
218 // Do Nothing.
219 }
220 }
221}

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.