Autopsy  4.19.3
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  */
19 package org.sleuthkit.autopsy.communications.relationships;
20 
21 import java.awt.event.ActionEvent;
22 import java.util.logging.Level;
23 import javax.swing.AbstractAction;
24 import javax.swing.Action;
25 import org.apache.commons.lang3.StringUtils;
26 import org.openide.nodes.Sheet;
27 import org.openide.util.Exceptions;
28 import org.openide.util.NbBundle.Messages;
32 import org.sleuthkit.datamodel.BlackboardArtifact;
33 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME;
34 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT;
35 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM;
36 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO;
37 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM;
38 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO;
39 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT;
40 import org.sleuthkit.datamodel.TskCoreException;
41 import static org.sleuthkit.autopsy.communications.relationships.RelationshipsNodeUtilities.getAttributeDisplayString;
43 import org.sleuthkit.datamodel.Account;
44 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
45 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE;
46 import org.sleuthkit.datamodel.BlackboardAttribute;
47 import org.sleuthkit.datamodel.CommunicationsManager;
48 import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil;
49 import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments;
50 
54 class 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-2022 Basis Technology. Generated on: Tue Jun 27 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.