19 package org.sleuthkit.autopsy.modules.iOS;
21 import java.sql.Connection;
22 import java.sql.DriverManager;
23 import java.sql.ResultSet;
24 import java.sql.SQLException;
25 import java.sql.Statement;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.List;
29 import java.util.logging.Level;
30 import org.openide.util.NbBundle;
31 import org.openide.util.NbBundle.Messages;
50 class TextMessageAnalyzer {
52 private Connection connection = null;
53 private ResultSet resultSet = null;
54 private Statement statement = null;
55 private String dbPath =
"";
56 private long fileId = 0;
57 private java.io.File jFile = null;
58 List<AbstractFile> absFiles;
59 private final String moduleName = iOSModuleFactory.getModuleName();
60 private static final Logger logger = Logger.getLogger(TextMessageAnalyzer.class.getName());
61 private Blackboard blackboard;
68 void findTexts(IngestJobContext context) {
71 openCase = Case.getCurrentCaseThrows();
72 }
catch (NoCurrentCaseException ex) {
73 logger.log(Level.SEVERE,
"Exception while getting open case.", ex);
76 blackboard = openCase.getSleuthkitCase().getBlackboard();
78 SleuthkitCase skCase = openCase.getSleuthkitCase();
79 absFiles = skCase.findAllFilesWhere(
"name ='mmssms.db'");
80 if (absFiles.isEmpty()) {
83 for (AbstractFile file : absFiles) {
85 jFile =
new java.io.File(Case.getCurrentCaseThrows().getTempDirectory(), file.getName().replaceAll(
"[<>%|\"/:*\\\\]",
""));
86 dbPath = jFile.toString();
87 fileId = file.getId();
88 ContentUtils.writeToFile(file, jFile, context::dataSourceIngestIsCancelled);
89 findTextsInDB(dbPath, fileId);
90 }
catch (ReadContentInputStream.ReadContentInputStreamException ex) {
91 logger.log(Level.WARNING, String.format(
"Error reading content from file '%s' (id=%d).", file.getName(), fileId), ex);
92 }
catch (Exception ex) {
93 logger.log(Level.SEVERE, String.format(
"Error writing content from file '%s' (id=%d) to '%s'.", file.getName(), fileId, dbPath), ex);
96 }
catch (TskCoreException e) {
97 logger.log(Level.SEVERE,
"Error finding text messages", e);
108 @Messages({
"TextMessageAnalyzer.indexError.message=Failed to index text message artifact for keyword search."})
109 private void findTextsInDB(String DatabasePath,
long fileId) {
110 if (DatabasePath == null || DatabasePath.isEmpty()) {
115 currentCase = Case.getCurrentCaseThrows();
116 }
catch (NoCurrentCaseException ex) {
117 logger.log(Level.SEVERE,
"Exception while getting open case.", ex);
121 Class.forName(
"org.sqlite.JDBC");
122 connection = DriverManager.getConnection(
"jdbc:sqlite:" + DatabasePath);
123 statement = connection.createStatement();
124 }
catch (ClassNotFoundException | SQLException e) {
125 logger.log(Level.SEVERE,
"Error opening database", e);
128 SleuthkitCase skCase = currentCase.getSleuthkitCase();
130 AbstractFile file = skCase.getAbstractFileById(fileId);
132 logger.log(Level.SEVERE,
"Error getting abstract file {0}", fileId);
137 resultSet = statement.executeQuery(
138 "SELECT address,date,type,subject,body FROM sms;");
140 BlackboardArtifact bba;
146 while (resultSet.next()) {
147 address = resultSet.getString(
"address");
148 date = resultSet.getString(
"date");
149 type = resultSet.getString(
"type");
150 subject = resultSet.getString(
"subject");
151 body = resultSet.getString(
"body");
153 bba = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE);
154 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
156 if (type.equals(
"1")) {
157 attributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION, moduleName, NbBundle.getMessage(
this.getClass(),
"TextMessageAnalyzer.bbAttribute.incoming")));
158 attributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM, moduleName, address));
160 attributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION, moduleName, NbBundle.getMessage(
this.getClass(),
"TextMessageAnalyzer.bbAttribute.outgoing")));
161 attributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO, moduleName, address));
163 attributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, moduleName, date));
164 attributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION, moduleName, type));
165 attributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT, moduleName, subject));
166 attributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT, moduleName, body));
167 attributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, moduleName, NbBundle.getMessage(
this.getClass(),
"TextMessageAnalyzer.bbAttribute.smsMessage")));
169 bba.addAttributes(attributes);
175 blackboard.postArtifact(bba, moduleName);
176 }
catch (Blackboard.BlackboardException ex) {
177 logger.log(Level.SEVERE,
"Unable to index blackboard artifact " + bba.getArtifactID(), ex);
178 MessageNotifyUtil.Notify.error(
179 Bundle.TextMessageAnalyzer_indexError_message(), bba.getDisplayName());
183 }
catch (Exception e) {
184 logger.log(Level.SEVERE,
"Error parsing text messages to Blackboard", e);
190 }
catch (Exception e) {
191 logger.log(Level.SEVERE,
"Error closing database", e);
194 }
catch (Exception e) {
195 logger.log(Level.SEVERE,
"Error parsing text messages to Blackboard", e);