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.List;
 
   32 import java.util.logging.Level;
 
   33 import org.openide.util.NbBundle.Messages;
 
   47 class ContactAnalyzer {
 
   49     private Connection connection = null;
 
   50     private ResultSet resultSet = null;
 
   51     private Statement statement = null;
 
   52     private String dbPath = 
"";
 
   53     private long fileId = 0;
 
   54     private java.io.File jFile = null;
 
   55     private String moduleName = iOSModuleFactory.getModuleName();
 
   56     private static final Logger logger = Logger.getLogger(ContactAnalyzer.class.getName());
 
   57     private Blackboard blackboard;
 
   59     public void findContacts(IngestJobContext context) {
 
   61         blackboard = Case.getCurrentCase().getServices().getBlackboard();
 
   62         List<AbstractFile> absFiles;
 
   64             SleuthkitCase skCase = Case.getCurrentCase().getSleuthkitCase();
 
   65             absFiles = skCase.findAllFilesWhere(
"LOWER(name) LIKE LOWER('%call_history%') "); 
 
   66             if (absFiles.isEmpty()) {
 
   69             for (AbstractFile AF : absFiles) {
 
   71                     jFile = 
new java.io.File(Case.getCurrentCase().getTempDirectory(), AF.getName().replaceAll(
"[<>%|\"/:*\\\\]", 
""));
 
   73                     ContentUtils.writeToFile(AF, jFile, context::dataSourceIngestIsCancelled);
 
   76                     dbPath = jFile.toString(); 
 
   79                 } 
catch (Exception e) {
 
   80                     logger.log(Level.SEVERE, 
"Error parsing Contacts", e); 
 
   83         } 
catch (TskCoreException e) {
 
   84             logger.log(Level.SEVERE, 
"Error finding Contacts", e); 
 
   95     @Messages({
"ContactAnalyzer.indexError.message=Failed to index contact artifact for keyword search."})
 
   96     private void findContactsInDB(String DatabasePath, 
long fId) {
 
   97         if (DatabasePath == null || DatabasePath.isEmpty()) {
 
  101             Class.forName(
"org.sqlite.JDBC"); 
 
  102             connection = DriverManager.getConnection(
"jdbc:sqlite:" + DatabasePath); 
 
  103             statement = connection.createStatement();
 
  104         } 
catch (ClassNotFoundException | SQLException e) {
 
  105             logger.log(Level.SEVERE, 
"Error opening database", e); 
 
  108         Case currentCase = Case.getCurrentCase();
 
  109         SleuthkitCase skCase = currentCase.getSleuthkitCase();
 
  111             AbstractFile f = skCase.getAbstractFileById(fId);
 
  113                 logger.log(Level.SEVERE, 
"Error getting abstract file " + fId); 
 
  120                 resultSet = statement.executeQuery(
 
  121                         "SELECT mimetype,data1, name_raw_contact.display_name AS display_name \n"  
  122                         + 
"FROM raw_contacts JOIN contacts ON (raw_contacts.contact_id=contacts._id) \n"  
  123                         + 
"JOIN raw_contacts AS name_raw_contact ON(name_raw_contact_id=name_raw_contact._id) "  
  124                         + 
"LEFT OUTER JOIN data ON (data.raw_contact_id=raw_contacts._id) \n"  
  125                         + 
"LEFT OUTER JOIN mimetypes ON (data.mimetype_id=mimetypes._id) \n"  
  126                         + 
"WHERE mimetype = 'vnd.android.cursor.item/phone_v2' OR mimetype = 'vnd.android.cursor.item/email_v2'\n"  
  127                         + 
"ORDER BY name_raw_contact.display_name ASC;"); 
 
  129                 BlackboardArtifact bba;
 
  130                 bba = f.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT);
 
  135                 while (resultSet.next()) {
 
  136                     name = resultSet.getString(
"display_name"); 
 
  137                     data1 = resultSet.getString(
"data1"); 
 
  138                     mimetype = resultSet.getString(
"mimetype"); 
 
  139                     if (name.equals(oldName) == 
false) {
 
  140                         bba = f.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT);
 
  141                         bba.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, moduleName, name));
 
  143                     if (mimetype.equals(
"vnd.android.cursor.item/phone_v2")) { 
 
  144                         bba.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, moduleName, data1));
 
  146                         bba.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL, moduleName, data1));
 
  152                         blackboard.indexArtifact(bba);
 
  153                     } 
catch (Blackboard.BlackboardException ex) {
 
  154                         logger.log(Level.SEVERE, 
"Unable to index blackboard artifact " + bba.getArtifactID(), ex); 
 
  155                         MessageNotifyUtil.Notify.error(
 
  156                                 Bundle.ContactAnalyzer_indexError_message(), bba.getDisplayName());
 
  160             } 
catch (Exception e) {
 
  161                 logger.log(Level.SEVERE, 
"Error parsing Contacts to Blackboard", e); 
 
  167                 } 
catch (Exception e) {
 
  168                     logger.log(Level.SEVERE, 
"Error closing database", e); 
 
  171         } 
catch (Exception e) {
 
  172             logger.log(Level.SEVERE, 
"Error parsing Contacts to Blackboard", e); 
 
  177     public static void copyFileUsingStream(AbstractFile file, File jFile) 
throws IOException {
 
  178         InputStream is = 
new ReadContentInputStream(file);
 
  179         OutputStream os = 
new FileOutputStream(jFile);
 
  180         byte[] buffer = 
new byte[8192];
 
  183             while ((length = is.read(buffer)) != -1) {
 
  184                 os.write(buffer, 0, length);
 
  185                 System.out.println(length);
 
  196     public static void copyFileUsingStreams(AbstractFile file, File jFile) {
 
  198         OutputStream ostream = null;
 
  201         istream = 
new ReadContentInputStream(file);
 
  203             ostream = 
new FileOutputStream(jFile);
 
  204             while ((c = istream.read()) != EOF) {
 
  207         } 
catch (IOException e) {
 
  208             System.out.println(
"Error: " + e.getMessage()); 
 
  213             } 
catch (IOException e) {
 
  214                 System.out.println(
"File did not close");