19 package org.sleuthkit.autopsy.modules.iOS;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.OutputStream;
26 import java.sql.Connection;
27 import java.sql.DriverManager;
28 import java.sql.ResultSet;
29 import java.sql.SQLException;
30 import java.sql.Statement;
31 import java.util.ArrayList;
32 import java.util.Collection;
33 import java.util.List;
34 import java.util.logging.Level;
35 import org.openide.util.NbBundle.Messages;
49 class ContactAnalyzer {
51 private Connection connection = null;
52 private ResultSet resultSet = null;
53 private Statement statement = null;
54 private String dbPath =
"";
55 private long fileId = 0;
56 private java.io.File jFile = null;
57 private String moduleName = iOSModuleFactory.getModuleName();
58 private static final Logger logger = Logger.getLogger(ContactAnalyzer.class.getName());
59 private Blackboard blackboard;
61 public void findContacts(IngestJobContext context) {
63 blackboard = Case.getCurrentCase().getServices().getBlackboard();
64 List<AbstractFile> absFiles;
66 SleuthkitCase skCase = Case.getCurrentCase().getSleuthkitCase();
67 absFiles = skCase.findAllFilesWhere(
"LOWER(name) LIKE LOWER('%call_history%') ");
68 if (absFiles.isEmpty()) {
71 for (AbstractFile AF : absFiles) {
73 jFile =
new java.io.File(Case.getCurrentCase().getTempDirectory(), AF.getName().replaceAll(
"[<>%|\"/:*\\\\]",
""));
75 ContentUtils.writeToFile(AF, jFile, context::dataSourceIngestIsCancelled);
78 dbPath = jFile.toString();
81 }
catch (Exception e) {
82 logger.log(Level.SEVERE,
"Error parsing Contacts", e);
85 }
catch (TskCoreException e) {
86 logger.log(Level.SEVERE,
"Error finding Contacts", e);
97 @Messages({
"ContactAnalyzer.indexError.message=Failed to index contact artifact for keyword search."})
98 private void findContactsInDB(String DatabasePath,
long fId) {
99 if (DatabasePath == null || DatabasePath.isEmpty()) {
103 Class.forName(
"org.sqlite.JDBC");
104 connection = DriverManager.getConnection(
"jdbc:sqlite:" + DatabasePath);
105 statement = connection.createStatement();
106 }
catch (ClassNotFoundException | SQLException e) {
107 logger.log(Level.SEVERE,
"Error opening database", e);
110 Case currentCase = Case.getCurrentCase();
111 SleuthkitCase skCase = currentCase.getSleuthkitCase();
113 AbstractFile f = skCase.getAbstractFileById(fId);
115 logger.log(Level.SEVERE,
"Error getting abstract file " + fId);
122 resultSet = statement.executeQuery(
123 "SELECT mimetype,data1, name_raw_contact.display_name AS display_name \n"
124 +
"FROM raw_contacts JOIN contacts ON (raw_contacts.contact_id=contacts._id) \n"
125 +
"JOIN raw_contacts AS name_raw_contact ON(name_raw_contact_id=name_raw_contact._id) "
126 +
"LEFT OUTER JOIN data ON (data.raw_contact_id=raw_contacts._id) \n"
127 +
"LEFT OUTER JOIN mimetypes ON (data.mimetype_id=mimetypes._id) \n"
128 +
"WHERE mimetype = 'vnd.android.cursor.item/phone_v2' OR mimetype = 'vnd.android.cursor.item/email_v2'\n"
129 +
"ORDER BY name_raw_contact.display_name ASC;");
131 BlackboardArtifact bba;
132 bba = f.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT);
133 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
138 while (resultSet.next()) {
139 name = resultSet.getString(
"display_name");
140 data1 = resultSet.getString(
"data1");
141 mimetype = resultSet.getString(
"mimetype");
142 if (name.equals(oldName) ==
false) {
143 attributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, moduleName, name));
145 if (mimetype.equals(
"vnd.android.cursor.item/phone_v2")) {
146 attributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, moduleName, data1));
148 attributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL, moduleName, data1));
152 bba.addAttributes(attributes);
155 blackboard.indexArtifact(bba);
156 }
catch (Blackboard.BlackboardException ex) {
157 logger.log(Level.SEVERE,
"Unable to index blackboard artifact " + bba.getArtifactID(), ex);
158 MessageNotifyUtil.Notify.error(
159 Bundle.ContactAnalyzer_indexError_message(), bba.getDisplayName());
163 }
catch (Exception e) {
164 logger.log(Level.SEVERE,
"Error parsing Contacts to Blackboard", e);
170 }
catch (Exception e) {
171 logger.log(Level.SEVERE,
"Error closing database", e);
174 }
catch (Exception e) {
175 logger.log(Level.SEVERE,
"Error parsing Contacts to Blackboard", e);
180 public static void copyFileUsingStream(AbstractFile file, File jFile)
throws IOException {
181 InputStream is =
new ReadContentInputStream(file);
182 OutputStream os =
new FileOutputStream(jFile);
183 byte[] buffer =
new byte[8192];
186 while ((length = is.read(buffer)) != -1) {
187 os.write(buffer, 0, length);
188 System.out.println(length);
199 public static void copyFileUsingStreams(AbstractFile file, File jFile) {
201 OutputStream ostream = null;
204 istream =
new ReadContentInputStream(file);
206 ostream =
new FileOutputStream(jFile);
207 while ((c = istream.read()) != EOF) {
210 }
catch (IOException e) {
211 System.out.println(
"Error: " + e.getMessage());
216 }
catch (IOException e) {
217 System.out.println(
"File did not close");