23 package org.sleuthkit.autopsy.recentactivity;
 
   25 import com.google.common.collect.ImmutableMap;
 
   26 import com.google.gson.JsonArray;
 
   27 import com.google.gson.JsonElement;
 
   28 import com.google.gson.JsonIOException;
 
   29 import com.google.gson.JsonObject;
 
   30 import com.google.gson.JsonParser;
 
   31 import com.google.gson.JsonSyntaxException;
 
   32 import org.openide.util.NbBundle;
 
   34 import java.util.logging.Level;
 
   36 import java.io.FileNotFoundException;
 
   37 import java.io.FileReader;
 
   38 import java.io.IOException;
 
   39 import java.util.Collection;
 
   40 import java.util.List;
 
   42 import java.util.HashMap;
 
   43 import java.util.ArrayList;
 
   44 import java.util.Arrays;
 
   45 import org.apache.commons.io.FilenameUtils;
 
   46 import org.openide.util.NbBundle.Messages;
 
   57 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
 
   58 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK;
 
   60 import org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
 
   62 import org.
sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
 
   66 import org.
sleuthkit.datamodel.blackboardutils.WebBrowserArtifactsHelper;
 
   71 class Chromium 
extends Extract {
 
   73     private static final String HISTORY_QUERY = 
"SELECT urls.url, urls.title, urls.visit_count, urls.typed_count, "  
   74             + 
"last_visit_time, urls.hidden, visits.visit_time, (SELECT urls.url FROM urls WHERE urls.id=visits.url) AS from_visit, visits.transition FROM urls, visits WHERE urls.id = visits.url"; 
 
   75     private static final String COOKIE_QUERY = 
"SELECT name, value, host_key, expires_utc,last_access_utc, creation_utc FROM cookies"; 
 
   76     private static final String DOWNLOAD_QUERY = 
"SELECT full_path, url, start_time, received_bytes FROM downloads"; 
 
   77     private static final String DOWNLOAD_QUERY_V30 = 
"SELECT current_path AS full_path, url, start_time, received_bytes FROM downloads, downloads_url_chains WHERE downloads.id=downloads_url_chains.id"; 
 
   78     private static final String LOGIN_QUERY = 
"SELECT origin_url, username_value, date_created, signon_realm from logins"; 
 
   79     private static final String AUTOFILL_QUERY = 
"SELECT name, value, count, date_created " 
   80             + 
" FROM autofill, autofill_dates " 
   81             + 
" WHERE autofill.pair_id = autofill_dates.pair_id"; 
 
   82     private static final String AUTOFILL_QUERY_V8X = 
"SELECT name, value, count, date_created, date_last_used from autofill"; 
 
   83     private static final String WEBFORM_ADDRESS_QUERY = 
"SELECT first_name, middle_name, last_name, address_line_1, address_line_2, city, state, zipcode, country_code, number, email, date_modified " 
   84             + 
" FROM autofill_profiles, autofill_profile_names, autofill_profile_emails, autofill_profile_phones" 
   85             + 
" WHERE autofill_profiles.guid = autofill_profile_names.guid AND autofill_profiles.guid = autofill_profile_emails.guid AND autofill_profiles.guid = autofill_profile_phones.guid";
 
   87     private static final String WEBFORM_ADDRESS_QUERY_V8X = 
"SELECT first_name, middle_name, last_name, full_name, street_address, city, state, zipcode, country_code, number, email, date_modified, use_date, use_count" 
   88             + 
" FROM autofill_profiles, autofill_profile_names, autofill_profile_emails, autofill_profile_phones" 
   89             + 
" WHERE autofill_profiles.guid = autofill_profile_names.guid AND autofill_profiles.guid = autofill_profile_emails.guid AND autofill_profiles.guid = autofill_profile_phones.guid";
 
   90     private static final String HISTORY_FILE_NAME = 
"History";
 
   91     private static final String BOOKMARK_FILE_NAME = 
"Bookmarks";
 
   92     private static final String COOKIE_FILE_NAME = 
"Cookies";
 
   93     private static final String LOGIN_DATA_FILE_NAME = 
"Login Data";
 
   94     private static final String WEB_DATA_FILE_NAME = 
"Web Data";
 
   95     private static final String UC_BROWSER_NAME = 
"UC Browser";
 
   96     private static final String ENCRYPTED_FIELD_MESSAGE = 
"The data was encrypted.";
 
   98     private Boolean databaseEncrypted = 
false;
 
   99     private Boolean fieldEncrypted = 
false;
 
  101     private final Logger logger = Logger.getLogger(this.getClass().getName());
 
  102     private Content dataSource;
 
  103     private IngestJobContext context;
 
  105     private static final Map<String, String> BROWSERS_MAP = ImmutableMap.<String, String>builder()
 
  106             .put(
"Microsoft Edge", 
"Microsoft/Edge/User Data/Default")
 
  107             .put(
"Yandex", 
"YandexBrowser/User Data/Default")
 
  108             .put(
"Opera", 
"Opera Software/Opera Stable")
 
  109             .put(
"SalamWeb", 
"SalamWeb/User Data/Default")
 
  110             .put(
"UC Browser", 
"UCBrowser/User Data%/Default")
 
  111             .put(
"Brave", 
"BraveSoftware/Brave-Browser/User Data/Default")
 
  112             .put(
"Google Chrome", 
"Chrome/User Data/Default")
 
  115     @Messages({
"# {0} - browserName",
 
  116         "Progress_Message_Chrome_History=Chrome History Browser {0}",
 
  117         "# {0} - browserName",
 
  118         "Progress_Message_Chrome_Bookmarks=Chrome Bookmarks Browser {0}",
 
  119         "# {0} - browserName",
 
  120         "Progress_Message_Chrome_Cookies=Chrome Cookies Browser {0}",
 
  121         "# {0} - browserName",
 
  122         "Progress_Message_Chrome_Downloads=Chrome Downloads Browser {0}",
 
  123         "Progress_Message_Chrome_FormHistory=Chrome Form History",
 
  124         "# {0} - browserName",
 
  125         "Progress_Message_Chrome_AutoFill=Chrome Auto Fill Browser {0}",
 
  126         "# {0} - browserName",
 
  127         "Progress_Message_Chrome_Logins=Chrome Logins Browser {0}",
 
  128         "Progress_Message_Chrome_Cache=Chrome Cache",})
 
  131         super(NbBundle.getMessage(Chromium.class, 
"Chrome.moduleName"));
 
  135     public void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
 
  136         this.dataSource = dataSource;
 
  137         this.context = context;
 
  139         long ingestJobId = context.getJobId();
 
  141         for (Map.Entry<String, String> browser : BROWSERS_MAP.entrySet()) {
 
  142             String browserName = browser.getKey();
 
  143             String browserLocation = browser.getValue();
 
  144             progressBar.progress(NbBundle.getMessage(
this.getClass(), 
"Progress_Message_Chrome_History", browserName));
 
  145             this.getHistory(browser.getKey(), browser.getValue(), ingestJobId);
 
  146             if (context.dataSourceIngestIsCancelled()) {
 
  150             progressBar.progress(NbBundle.getMessage(
this.getClass(), 
"Progress_Message_Chrome_Bookmarks", browserName));
 
  151             this.getBookmark(browser.getKey(), browser.getValue(), ingestJobId);
 
  152             if (context.dataSourceIngestIsCancelled()) {
 
  156             progressBar.progress(NbBundle.getMessage(
this.getClass(), 
"Progress_Message_Chrome_Cookies", browserName));
 
  157             this.getCookie(browser.getKey(), browser.getValue(), ingestJobId);
 
  158             if (context.dataSourceIngestIsCancelled()) {
 
  162             progressBar.progress(NbBundle.getMessage(
this.getClass(), 
"Progress_Message_Chrome_Logins", browserName));
 
  163             this.getLogins(browser.getKey(), browser.getValue(), ingestJobId);
 
  164             if (context.dataSourceIngestIsCancelled()) {
 
  168             progressBar.progress(NbBundle.getMessage(
this.getClass(), 
"Progress_Message_Chrome_AutoFill", browserName));
 
  169             this.getAutofill(browser.getKey(), browser.getValue(), ingestJobId);
 
  170             if (context.dataSourceIngestIsCancelled()) {
 
  174             progressBar.progress(NbBundle.getMessage(
this.getClass(), 
"Progress_Message_Chrome_Downloads", browserName));
 
  175             this.getDownload(browser.getKey(), browser.getValue(), ingestJobId);
 
  176             if (context.dataSourceIngestIsCancelled()) {
 
  181         progressBar.progress(Bundle.Progress_Message_Chrome_Cache());
 
  182         ChromeCacheExtractor chromeCacheExtractor = 
new ChromeCacheExtractor(dataSource, context, progressBar);
 
  183         chromeCacheExtractor.processCaches();
 
  193     private void getHistory(String browser, String browserLocation, 
long ingestJobId) {
 
  194         FileManager fileManager = currentCase.getServices().getFileManager();
 
  195         List<AbstractFile> historyFiles;
 
  196         String historyFileName = HISTORY_FILE_NAME;
 
  197         if (browser.equals(UC_BROWSER_NAME)) {
 
  198             historyFileName = HISTORY_FILE_NAME + 
"%";
 
  201             historyFiles = fileManager.findFiles(dataSource, historyFileName, browserLocation); 
 
  202         } 
catch (TskCoreException ex) {
 
  203             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getHistory.errMsg.errGettingFiles");
 
  204             logger.log(Level.SEVERE, msg, ex);
 
  205             this.addErrorMessage(this.getName() + 
": " + msg);
 
  210         List<AbstractFile> allocatedHistoryFiles = 
new ArrayList<>();
 
  211         for (AbstractFile historyFile : historyFiles) {
 
  212             if (historyFile.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC)) {
 
  213                 allocatedHistoryFiles.add(historyFile);
 
  218         if (allocatedHistoryFiles.isEmpty()) {
 
  219             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getHistory.errMsg.couldntFindAnyFiles");
 
  220             logger.log(Level.INFO, msg);
 
  225         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  227         while (j < allocatedHistoryFiles.size()) {
 
  228             String temps = RAImageIngestModule.getRATempPath(currentCase, browser, ingestJobId) + File.separator + allocatedHistoryFiles.get(j).getName() + j + 
".db"; 
 
  229             final AbstractFile historyFile = allocatedHistoryFiles.get(j++);
 
  230             if ((historyFile.getSize() == 0) || (historyFile.getName().toLowerCase().contains(
"-slack"))
 
  231                     || (historyFile.getName().toLowerCase().contains(
"cache")) || (historyFile.getName().toLowerCase().contains(
"media"))
 
  232                     || (historyFile.getName().toLowerCase().contains(
"index"))) {
 
  236                 ContentUtils.writeToFile(historyFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  237             } 
catch (ReadContentInputStreamException ex) {
 
  238                 logger.log(Level.WARNING, String.format(
"Error reading Chrome web history artifacts file '%s' (id=%d).",
 
  239                         historyFile.getName(), historyFile.getId()), ex); 
 
  240                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getHistory.errMsg.errAnalyzingFile",
 
  241                         this.getName(), historyFile.getName()));
 
  243             } 
catch (IOException ex) {
 
  244                 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Chrome web history artifacts file '%s' (id=%d).",
 
  245                         temps, historyFile.getName(), historyFile.getId()), ex); 
 
  246                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getHistory.errMsg.errAnalyzingFile",
 
  247                         this.getName(), historyFile.getName()));
 
  250             File dbFile = 
new File(temps);
 
  251             if (context.dataSourceIngestIsCancelled()) {
 
  255             List<HashMap<String, Object>> tempList;
 
  256             tempList = this.dbConnect(temps, HISTORY_QUERY);
 
  257             logger.log(Level.INFO, 
"{0}- Now getting history from {1} with {2} artifacts identified.", 
new Object[]{getName(), temps, tempList.size()}); 
 
  258             for (HashMap<String, Object> result : tempList) {
 
  259                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  260                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  261                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  262                         ((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
""))); 
 
  263                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
 
  264                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  265                         (Long.valueOf(result.get(
"last_visit_time").toString()) / 1000000) - Long.valueOf(
"11644473600"))); 
 
  266                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER,
 
  267                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  268                         ((result.get(
"from_visit").toString() != null) ? result.get(
"from_visit").toString() : 
""))); 
 
  269                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
 
  270                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  271                         ((result.get(
"title").toString() != null) ? result.get(
"title").toString() : 
""))); 
 
  272                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  273                         RecentActivityExtracterModuleFactory.getModuleName(), browser));
 
  274                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  275                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  276                         (NetworkUtils.extractDomain((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
"")))); 
 
  279                      bbartifacts.add(createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_HISTORY, historyFile, bbattributes));
 
  280                 } 
catch (TskCoreException ex) {
 
  281                     logger.log(Level.SEVERE, String.format(
"Failed to create history artifact for file (%d)", historyFile.getId()), ex);
 
  287         if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
 
  288             postArtifacts(bbartifacts);
 
  298     private void getBookmark(String browser, String browserLocation, 
long ingestJobId) {
 
  299         FileManager fileManager = currentCase.getServices().getFileManager();
 
  300         List<AbstractFile> bookmarkFiles;
 
  301         String bookmarkFileName = BOOKMARK_FILE_NAME;
 
  302         if (browser.equals(UC_BROWSER_NAME)) {
 
  303             bookmarkFileName = BOOKMARK_FILE_NAME + 
"%";
 
  306             bookmarkFiles = fileManager.findFiles(dataSource, bookmarkFileName, browserLocation); 
 
  307         } 
catch (TskCoreException ex) {
 
  308             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getBookmark.errMsg.errGettingFiles");
 
  309             logger.log(Level.SEVERE, msg, ex);
 
  310             this.addErrorMessage(this.getName() + 
": " + msg);
 
  314         if (bookmarkFiles.isEmpty()) {
 
  315             logger.log(Level.INFO, 
"Didn't find any Chrome bookmark files."); 
 
  320         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  323         while (j < bookmarkFiles.size()) {
 
  324             AbstractFile bookmarkFile = bookmarkFiles.get(j++);
 
  325             if ((bookmarkFile.getSize() == 0) || (bookmarkFile.getName().toLowerCase().contains(
"-slack"))
 
  326                     || (bookmarkFile.getName().toLowerCase().contains(
"extras")) || (bookmarkFile.getName().toLowerCase().contains(
"log"))
 
  327                     || (bookmarkFile.getName().toLowerCase().contains(
"backup")) || (bookmarkFile.getName().toLowerCase().contains(
"visualized"))
 
  328                     || (bookmarkFile.getName().toLowerCase().contains(
"bak")) || (bookmarkFile.getParentPath().toLowerCase().contains(
"backup"))) {
 
  331             String temps = RAImageIngestModule.getRATempPath(currentCase, browser, ingestJobId) + File.separator + bookmarkFile.getName() + j + 
".db"; 
 
  333                 ContentUtils.writeToFile(bookmarkFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  334             } 
catch (ReadContentInputStreamException ex) {
 
  335                 logger.log(Level.WARNING, String.format(
"Error reading Chrome bookmark artifacts file '%s' (id=%d).",
 
  336                         bookmarkFile.getName(), bookmarkFile.getId()), ex); 
 
  337                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getBookmark.errMsg.errAnalyzingFile",
 
  338                         this.getName(), bookmarkFile.getName()));
 
  340             } 
catch (IOException ex) {
 
  341                 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Chrome bookmark artifacts file '%s' (id=%d).",
 
  342                         temps, bookmarkFile.getName(), bookmarkFile.getId()), ex); 
 
  343                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getBookmark.errMsg.errAnalyzingFile",
 
  344                         this.getName(), bookmarkFile.getName()));
 
  348             logger.log(Level.INFO, 
"{0}- Now getting Bookmarks from {1}", 
new Object[]{getName(), temps}); 
 
  349             File dbFile = 
new File(temps);
 
  350             if (context.dataSourceIngestIsCancelled()) {
 
  355             FileReader tempReader;
 
  357                 tempReader = 
new FileReader(temps);
 
  358             } 
catch (FileNotFoundException ex) {
 
  359                 logger.log(Level.WARNING, 
"Error while trying to read into the Bookmarks for Chrome.", ex); 
 
  363             final JsonParser parser = 
new JsonParser();
 
  364             JsonElement jsonElement;
 
  365             JsonObject jElement, jRoot, jBookmark;
 
  366             JsonArray jBookmarkArray;
 
  369                 jsonElement = parser.parse(tempReader);
 
  370                 jElement = jsonElement.getAsJsonObject();
 
  371                 jRoot = jElement.get(
"roots").getAsJsonObject(); 
 
  372                 jBookmark = jRoot.get(
"bookmark_bar").getAsJsonObject(); 
 
  373                 jBookmarkArray = jBookmark.getAsJsonArray(
"children"); 
 
  374             } 
catch (JsonIOException | JsonSyntaxException | IllegalStateException ex) {
 
  375                 logger.log(Level.WARNING, 
"Error parsing Json from Chrome Bookmark.", ex); 
 
  376                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getBookmark.errMsg.errAnalyzingFile3",
 
  377                         this.getName(), bookmarkFile.getName()));
 
  381             for (JsonElement result : jBookmarkArray) {
 
  382                 JsonObject address = result.getAsJsonObject();
 
  383                 if (address == null) {
 
  386                 JsonElement urlEl = address.get(
"url"); 
 
  389                     url = urlEl.getAsString();
 
  394                 JsonElement nameEl = address.get(
"name"); 
 
  395                 if (nameEl != null) {
 
  396                     name = nameEl.getAsString();
 
  401                 JsonElement dateEl = address.get(
"date_added"); 
 
  402                 if (dateEl != null) {
 
  403                     date = dateEl.getAsLong();
 
  405                     date = Long.valueOf(0);
 
  407                 String domain = NetworkUtils.extractDomain(url);
 
  408                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  410                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  411                         RecentActivityExtracterModuleFactory.getModuleName(), url));
 
  412                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
 
  413                         RecentActivityExtracterModuleFactory.getModuleName(), name));
 
  414                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
 
  415                         RecentActivityExtracterModuleFactory.getModuleName(), (date / 1000000) - Long.valueOf(
"11644473600")));
 
  416                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  417                         RecentActivityExtracterModuleFactory.getModuleName(), browser));
 
  418                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  419                         RecentActivityExtracterModuleFactory.getModuleName(), domain));
 
  422                     bbartifacts.add(createArtifactWithAttributes(TSK_WEB_BOOKMARK, bookmarkFile, bbattributes));
 
  423                 } 
catch (TskCoreException ex) {
 
  424                     logger.log(Level.SEVERE, String.format(
"Failed to create bookmark artifact for file (%d)", bookmarkFile.getId()), ex);
 
  429             if(!context.dataSourceIngestIsCancelled()) {
 
  430                 postArtifacts(bbartifacts);
 
  443     private void getCookie(String browser, String browserLocation, 
long ingestJobId) {
 
  445         FileManager fileManager = currentCase.getServices().getFileManager();
 
  446         List<AbstractFile> cookiesFiles;
 
  447         String cookieFileName = COOKIE_FILE_NAME;
 
  448         if (browser.equals(UC_BROWSER_NAME)) {
 
  451             cookieFileName = 
"%" + COOKIE_FILE_NAME + 
"%";
 
  454             cookiesFiles = fileManager.findFiles(dataSource, cookieFileName, browserLocation); 
 
  455         } 
catch (TskCoreException ex) {
 
  456             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getCookie.errMsg.errGettingFiles");
 
  457             logger.log(Level.SEVERE, msg, ex);
 
  458             this.addErrorMessage(this.getName() + 
": " + msg);
 
  462         if (cookiesFiles.isEmpty()) {
 
  463             logger.log(Level.INFO, 
"Didn't find any Chrome cookies files."); 
 
  468         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  470         while (j < cookiesFiles.size()) {
 
  471             AbstractFile cookiesFile = cookiesFiles.get(j++);
 
  472             if ((cookiesFile.getSize() == 0) || (cookiesFile.getName().toLowerCase().contains(
"-slack"))) {
 
  475             String temps = RAImageIngestModule.getRATempPath(currentCase, browser, ingestJobId) + File.separator + cookiesFile.getName() + j + 
".db"; 
 
  477                 ContentUtils.writeToFile(cookiesFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  478             } 
catch (ReadContentInputStreamException ex) {
 
  479                 logger.log(Level.WARNING, String.format(
"Error reading Chrome cookie artifacts file '%s' (id=%d).",
 
  480                         cookiesFile.getName(), cookiesFile.getId()), ex); 
 
  481                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getCookie.errMsg.errAnalyzeFile",
 
  482                         this.getName(), cookiesFile.getName()));
 
  484             } 
catch (IOException ex) {
 
  485                 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Chrome cookie artifacts file '%s' (id=%d).",
 
  486                         temps, cookiesFile.getName(), cookiesFile.getId()), ex); 
 
  487                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getCookie.errMsg.errAnalyzeFile",
 
  488                         this.getName(), cookiesFile.getName()));
 
  491             File dbFile = 
new File(temps);
 
  492             if (context.dataSourceIngestIsCancelled()) {
 
  497             List<HashMap<String, Object>> tempList = this.dbConnect(temps, COOKIE_QUERY);
 
  498             logger.log(Level.INFO, 
"{0}- Now getting cookies from {1} with {2} artifacts identified.", 
new Object[]{getName(), temps, tempList.size()}); 
 
  499             for (HashMap<String, Object> result : tempList) {
 
  500                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  501                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  502                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  503                         ((result.get(
"host_key").toString() != null) ? result.get(
"host_key").toString() : 
""))); 
 
  504                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
 
  505                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  506                         (Long.valueOf(result.get(
"last_access_utc").toString()) / 1000000) - Long.valueOf(
"11644473600"))); 
 
  508                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
 
  509                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  510                         ((result.get(
"name").toString() != null) ? result.get(
"name").toString() : 
""))); 
 
  511                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
 
  512                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  513                         ((result.get(
"value").toString() != null) ? result.get(
"value").toString() : 
""))); 
 
  514                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  515                         RecentActivityExtracterModuleFactory.getModuleName(), browser));
 
  516                 String domain = result.get(
"host_key").toString(); 
 
  517                 domain = domain.replaceFirst(
"^\\.+(?!$)", 
"");
 
  518                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  519                         RecentActivityExtracterModuleFactory.getModuleName(), domain));
 
  522                     bbartifacts.add(createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_COOKIE, cookiesFile, bbattributes));
 
  523                 } 
catch (TskCoreException ex) {
 
  524                     logger.log(Level.SEVERE, String.format(
"Failed to create cookie artifact for file (%d)", cookiesFile.getId()), ex);
 
  531         if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
 
  532             postArtifacts(bbartifacts);
 
  542     private void getDownload(String browser, String browserLocation, 
long ingestJobId) {
 
  543         FileManager fileManager = currentCase.getServices().getFileManager();
 
  544         List<AbstractFile> downloadFiles;
 
  545         String historyFileName = HISTORY_FILE_NAME;
 
  546         if (browser.equals(UC_BROWSER_NAME)) {
 
  547             historyFileName = HISTORY_FILE_NAME + 
"%";
 
  550             downloadFiles = fileManager.findFiles(dataSource, historyFileName, browserLocation); 
 
  551         } 
catch (TskCoreException ex) {
 
  552             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getDownload.errMsg.errGettingFiles");
 
  553             logger.log(Level.SEVERE, msg, ex);
 
  554             this.addErrorMessage(this.getName() + 
": " + msg);
 
  558         if (downloadFiles.isEmpty()) {
 
  559             logger.log(Level.INFO, 
"Didn't find any Chrome download files."); 
 
  564         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  566         while (j < downloadFiles.size()) {
 
  567             AbstractFile downloadFile = downloadFiles.get(j++);
 
  568             if ((downloadFile.getSize() == 0) || (downloadFile.getName().toLowerCase().contains(
"-slack"))
 
  569                     || (downloadFile.getName().toLowerCase().contains(
"cache")) || (downloadFile.getName().toLowerCase().contains(
"index"))) {
 
  573             String temps = RAImageIngestModule.getRATempPath(currentCase, browser, ingestJobId) + File.separator + downloadFile.getName() + j + 
".db"; 
 
  575                 ContentUtils.writeToFile(downloadFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  576             } 
catch (ReadContentInputStreamException ex) {
 
  577                 logger.log(Level.WARNING, String.format(
"Error reading Chrome download artifacts file '%s' (id=%d).",
 
  578                         downloadFile.getName(), downloadFile.getId()), ex); 
 
  579                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getDownload.errMsg.errAnalyzeFiles1",
 
  580                         this.getName(), downloadFile.getName()));
 
  582             } 
catch (IOException ex) {
 
  583                 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Chrome download artifacts file '%s' (id=%d).",
 
  584                         temps, downloadFile.getName(), downloadFile.getId()), ex); 
 
  585                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getDownload.errMsg.errAnalyzeFiles1",
 
  586                         this.getName(), downloadFile.getName()));
 
  589             File dbFile = 
new File(temps);
 
  590             if (context.dataSourceIngestIsCancelled()) {
 
  595             List<HashMap<String, Object>> tempList;
 
  597             if (isChromePreVersion30(temps)) {
 
  598                 tempList = this.dbConnect(temps, DOWNLOAD_QUERY);
 
  600                 tempList = this.dbConnect(temps, DOWNLOAD_QUERY_V30);
 
  603             logger.log(Level.INFO, 
"{0}- Now getting downloads from {1} with {2} artifacts identified.", 
new Object[]{getName(), temps, tempList.size()}); 
 
  604             for (HashMap<String, Object> result : tempList) {
 
  605                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  606                 String fullPath = result.get(
"full_path").toString(); 
 
  607                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
 
  608                         RecentActivityExtracterModuleFactory.getModuleName(), fullPath));
 
  609                 long pathID = Util.findID(dataSource, fullPath);
 
  611                     bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
 
  612                             NbBundle.getMessage(
this.getClass(),
 
  613                                     "Chrome.parentModuleName"), pathID));
 
  615                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  616                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  617                         ((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
""))); 
 
  619                 Long time = (Long.valueOf(result.get(
"start_time").toString()) / 1000000) - Long.valueOf(
"11644473600"); 
 
  623                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
 
  624                         RecentActivityExtracterModuleFactory.getModuleName(), time));
 
  625                 String domain = NetworkUtils.extractDomain((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
""); 
 
  626                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  627                         RecentActivityExtracterModuleFactory.getModuleName(), domain));
 
  628                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  629                         RecentActivityExtracterModuleFactory.getModuleName(), browser));
 
  633                     BlackboardArtifact webDownloadArtifact = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadFile, bbattributes);
 
  634                     bbartifacts.add(webDownloadArtifact);
 
  635                     String normalizedFullPath = FilenameUtils.normalize(fullPath, 
true);
 
  636                     for (AbstractFile downloadedFile : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, FilenameUtils.getName(normalizedFullPath), FilenameUtils.getPath(normalizedFullPath))) {
 
  637                         bbartifacts.add(createAssociatedArtifact(downloadedFile, webDownloadArtifact));
 
  640                 } 
catch (TskCoreException ex) {
 
  641                     logger.log(Level.SEVERE, String.format(
"Error creating associated object artifact for file  '%s'", fullPath), ex); 
 
  648         if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
 
  649             postArtifacts(bbartifacts);
 
  659     private void getLogins(String browser, String browserLocation, 
long ingestJobId) {
 
  661         FileManager fileManager = currentCase.getServices().getFileManager();
 
  662         List<AbstractFile> loginDataFiles;
 
  663         String loginDataFileName = LOGIN_DATA_FILE_NAME;
 
  664         if (browser.equals(UC_BROWSER_NAME)) {
 
  665             loginDataFileName = LOGIN_DATA_FILE_NAME + 
"%";
 
  669             loginDataFiles = fileManager.findFiles(dataSource, loginDataFileName, browserLocation); 
 
  670         } 
catch (TskCoreException ex) {
 
  671             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getLogin.errMsg.errGettingFiles");
 
  672             logger.log(Level.SEVERE, msg, ex);
 
  673             this.addErrorMessage(this.getName() + 
": " + msg);
 
  677         if (loginDataFiles.isEmpty()) {
 
  678             logger.log(Level.INFO, 
"Didn't find any Chrome Login Data files."); 
 
  683         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  685         while (j < loginDataFiles.size()) {
 
  686             AbstractFile loginDataFile = loginDataFiles.get(j++);
 
  687             if ((loginDataFile.getSize() == 0) || (loginDataFile.getName().toLowerCase().contains(
"-slack"))) {
 
  690             String temps = RAImageIngestModule.getRATempPath(currentCase, browser, ingestJobId) + File.separator + loginDataFile.getName() + j + 
".db"; 
 
  692                 ContentUtils.writeToFile(loginDataFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  693             } 
catch (ReadContentInputStreamException ex) {
 
  694                 logger.log(Level.WARNING, String.format(
"Error reading Chrome login artifacts file '%s' (id=%d).",
 
  695                         loginDataFile.getName(), loginDataFile.getId()), ex); 
 
  696                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getLogin.errMsg.errAnalyzingFiles",
 
  697                         this.getName(), loginDataFile.getName()));
 
  699             } 
catch (IOException ex) {
 
  700                 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Chrome login artifacts file '%s' (id=%d).",
 
  701                         temps, loginDataFile.getName(), loginDataFile.getId()), ex); 
 
  702                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getLogin.errMsg.errAnalyzingFiles",
 
  703                         this.getName(), loginDataFile.getName()));
 
  706             File dbFile = 
new File(temps);
 
  707             if (context.dataSourceIngestIsCancelled()) {
 
  711             List<HashMap<String, Object>> tempList = this.dbConnect(temps, LOGIN_QUERY);
 
  712             logger.log(Level.INFO, 
"{0}- Now getting login information from {1} with {2} artifacts identified.", 
new Object[]{getName(), temps, tempList.size()}); 
 
  713             for (HashMap<String, Object> result : tempList) {
 
  714                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  716                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  717                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  718                         ((result.get(
"origin_url").toString() != null) ? result.get(
"origin_url").toString() : 
""))); 
 
  720                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
 
  721                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  722                         (Long.valueOf(result.get(
"date_created").toString()) / 1000000) - Long.valueOf(
"11644473600"))); 
 
  724                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED,
 
  725                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  726                         (NetworkUtils.extractDomain((result.get(
"origin_url").toString() != null) ? result.get(
"origin_url").toString() : 
"")))); 
 
  728                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
 
  729                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  730                         ((result.get(
"username_value").toString() != null) ? result.get(
"username_value").toString().replaceAll(
"'", 
"''") : 
""))); 
 
  732                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REALM,
 
  733                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  734                         ((result.get(
"signon_realm") != null && result.get(
"signon_realm").toString() != null) ? result.get(
"signon_realm").toString() : 
""))); 
 
  736                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  737                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  738                         result.containsKey(
"signon_realm") ? NetworkUtils.extractDomain(result.get(
"signon_realm").toString()) : 
"")); 
 
  740                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  741                         RecentActivityExtracterModuleFactory.getModuleName(), browser));
 
  744                     bbartifacts.add(createArtifactWithAttributes(ARTIFACT_TYPE.TSK_SERVICE_ACCOUNT, loginDataFile, bbattributes));
 
  745                 } 
catch (TskCoreException ex) {
 
  746                     logger.log(Level.SEVERE, String.format(
"Failed to create service account artifact for file (%d)", loginDataFile.getId()), ex);
 
  753         if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
 
  754             postArtifacts(bbartifacts);
 
  765     private void getAutofill(String browser, String browserLocation, 
long ingestJobId) {
 
  767         FileManager fileManager = currentCase.getServices().getFileManager();
 
  768         List<AbstractFile> webDataFiles;
 
  769         String webDataFileName = WEB_DATA_FILE_NAME;
 
  770         if (browser.equals(UC_BROWSER_NAME)) {
 
  771             webDataFileName = WEB_DATA_FILE_NAME + 
"%";
 
  775             webDataFiles = fileManager.findFiles(dataSource, webDataFileName, browserLocation); 
 
  776         } 
catch (TskCoreException ex) {
 
  777             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getAutofills.errMsg.errGettingFiles");
 
  778             logger.log(Level.SEVERE, msg, ex);
 
  779             this.addErrorMessage(this.getName() + 
": " + msg);
 
  783         if (webDataFiles.isEmpty()) {
 
  784             logger.log(Level.INFO, 
"Didn't find any Chrome Web Data files."); 
 
  789         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  791         while (j < webDataFiles.size()) {
 
  792             databaseEncrypted = 
false;
 
  793             AbstractFile webDataFile = webDataFiles.get(j++);
 
  794             if ((webDataFile.getSize() == 0) || (webDataFile.getName().toLowerCase().contains(
"-slack"))) {
 
  797             String tempFilePath = RAImageIngestModule.getRATempPath(currentCase, browser, ingestJobId) + File.separator + webDataFile.getName() + j + 
".db"; 
 
  799                 ContentUtils.writeToFile(webDataFile, 
new File(tempFilePath), context::dataSourceIngestIsCancelled);
 
  800             } 
catch (ReadContentInputStreamException ex) {
 
  801                 logger.log(Level.WARNING, String.format(
"Error reading Chrome Autofill artifacts file '%s' (id=%d).",
 
  802                         webDataFile.getName(), webDataFile.getId()), ex); 
 
  803                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getAutofill.errMsg.errAnalyzingFiles",
 
  804                         this.getName(), webDataFile.getName()));
 
  806             } 
catch (IOException ex) {
 
  807                 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Chrome Web data file '%s' (id=%d).",
 
  808                         tempFilePath, webDataFile.getName(), webDataFile.getId()), ex); 
 
  809                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getLogin.errMsg.errAnalyzingFiles",
 
  810                         this.getName(), webDataFile.getName()));
 
  813             File dbFile = 
new File(tempFilePath);
 
  814             if (context.dataSourceIngestIsCancelled()) {
 
  820             boolean isSchemaV8X = Util.checkColumn(
"date_created", 
"autofill", tempFilePath);
 
  823             bbartifacts.addAll(getFormAutofillArtifacts(webDataFile, tempFilePath, isSchemaV8X, browser));
 
  826                 getFormAddressArtifacts(webDataFile, tempFilePath, isSchemaV8X);
 
  827                 if (databaseEncrypted) {
 
  828                     String comment = String.format(
"%s Autofill Database Encryption Detected", browser);
 
  829                    Collection<BlackboardAttribute> bbattributes = Arrays.asList(
 
  830                            new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT, 
 
  831                                    RecentActivityExtracterModuleFactory.getModuleName(), comment));
 
  834                            webDataFile.newAnalysisResult(
 
  835                                    BlackboardArtifact.Type.TSK_ENCRYPTION_DETECTED, Score.SCORE_NOTABLE, 
 
  836                                    null, null, comment, bbattributes).getAnalysisResult()); 
 
  838             } 
catch (NoCurrentCaseException | TskCoreException | Blackboard.BlackboardException ex) {
 
  839                 logger.log(Level.SEVERE, String.format(
"Error adding artifacts to the case database " 
  840                         + 
"for chrome file %s [objId=%d]", webDataFile.getName(), webDataFile.getId()), ex);
 
  846         if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
 
  847             postArtifacts(bbartifacts);
 
  861     private Collection<BlackboardArtifact> getFormAutofillArtifacts(AbstractFile webDataFile, String dbFilePath, 
boolean isSchemaV8X, String browser) {
 
  863         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  866         String autoFillquery = (isSchemaV8X) ? AUTOFILL_QUERY_V8X
 
  869         List<HashMap<String, Object>> autofills = this.dbConnect(dbFilePath, autoFillquery);
 
  870         logger.log(Level.INFO, 
"{0}- Now getting Autofill information from {1} with {2} artifacts identified.", 
new Object[]{getName(), dbFilePath, autofills.size()}); 
 
  871         for (HashMap<String, Object> result : autofills) {
 
  872             Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  875             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
 
  876                     NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
  877                     ((result.get(
"name").toString() != null) ? result.get(
"name").toString() : 
""))); 
 
  879             fieldEncrypted = 
false;
 
  880             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
 
  881                     RecentActivityExtracterModuleFactory.getModuleName(),
 
  882                     processFields(result.get(
"value")))); 
 
  884             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
 
  885                     RecentActivityExtracterModuleFactory.getModuleName(),
 
  886                     (Integer.valueOf(result.get(
"count").toString())))); 
 
  888             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
 
  889                     RecentActivityExtracterModuleFactory.getModuleName(),
 
  890                     Long.valueOf(result.get(
"date_created").toString()))); 
 
  894                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
 
  895                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  896                         Long.valueOf(result.get(
"date_last_used").toString()))); 
 
  899             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  900                     RecentActivityExtracterModuleFactory.getModuleName(), browser));
 
  901             if (fieldEncrypted) {
 
  902                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT,
 
  903                         RecentActivityExtracterModuleFactory.getModuleName(), ENCRYPTED_FIELD_MESSAGE));
 
  908                 bbartifacts.add(createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_FORM_AUTOFILL, webDataFile, bbattributes));
 
  909             } 
catch (TskCoreException ex) {
 
  910                 logger.log(Level.SEVERE, String.format(
"Failed to create web form autopfill artifact for file (%d)", webDataFile.getId()), ex);
 
  929     private void getFormAddressArtifacts(AbstractFile webDataFile, String dbFilePath, 
boolean isSchemaV8X) 
throws NoCurrentCaseException,
 
  930             TskCoreException, Blackboard.BlackboardException {
 
  932         String webformAddressQuery = (isSchemaV8X) ? WEBFORM_ADDRESS_QUERY_V8X
 
  933                 : WEBFORM_ADDRESS_QUERY;
 
  936         WebBrowserArtifactsHelper helper = 
new WebBrowserArtifactsHelper(
 
  937                 Case.getCurrentCaseThrows().getSleuthkitCase(),
 
  938                 NbBundle.getMessage(this.getClass(), 
"Chrome.parentModuleName"),
 
  943         List<HashMap<String, Object>> addresses = this.dbConnect(dbFilePath, webformAddressQuery);
 
  944         logger.log(Level.INFO, 
"{0}- Now getting Web form addresses from {1} with {2} artifacts identified.", 
new Object[]{getName(), dbFilePath, addresses.size()}); 
 
  945         for (HashMap<String, Object> result : addresses) {
 
  947             fieldEncrypted = 
false;
 
  949             String first_name = processFields(result.get(
"first_name"));
 
  950             String middle_name = processFields(result.get(
"middle_name"));
 
  951             String last_name = processFields(result.get(
"last_name"));
 
  954             String email_Addr = processFields(result.get(
"email"));
 
  955             String phone_number = processFields(result.get(
"number"));
 
  958             String city = processFields(result.get(
"city"));
 
  959             String state = processFields(result.get(
"state"));
 
  960             String zipcode = processFields(result.get(
"zipcode"));
 
  961             String country_code = processFields(result.get(
"country_code"));
 
  964             String full_name = 
"";
 
  965             String street_address = 
"";
 
  966             long date_modified = 0;
 
  972                 full_name = processFields(result.get(
"full_name"));
 
  973                 street_address = processFields(result.get(
"street_address"));
 
  974                 date_modified = result.get(
"date_modified").toString() != null ? Long.valueOf(result.get(
"date_modified").toString()) : 0;
 
  975                 use_count = result.get(
"use_count").toString() != null ? Integer.valueOf(result.get(
"use_count").toString()) : 0;
 
  976                 use_date = result.get(
"use_date").toString() != null ? Long.valueOf(result.get(
"use_date").toString()) : 0;
 
  978                 String address_line_1 = processFields(result.get(
"address_line_1"));
 
  979                 String address_line_2 = processFields(result.get(
"address_line_2"));
 
  980                 street_address = String.join(
" ", address_line_1, address_line_2);
 
  984             if (full_name == null || full_name.isEmpty()) {
 
  985                 full_name = String.join(
" ", first_name, middle_name, last_name);
 
  988             String locationAddress = String.join(
", ", street_address, city, state, zipcode, country_code);
 
  990             List<BlackboardAttribute> otherAttributes = 
new ArrayList<>();
 
  991             if (date_modified > 0) {
 
  992                 otherAttributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED,
 
  993                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  995                 if (fieldEncrypted) {
 
  996                     otherAttributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT,
 
  997                             RecentActivityExtracterModuleFactory.getModuleName(), ENCRYPTED_FIELD_MESSAGE)); 
 
 1002             helper.addWebFormAddress(
 
 1003                     full_name, email_Addr, phone_number,
 
 1004                     locationAddress, 0, use_date,
 
 1005                     use_count, otherAttributes);
 
 1015     private String processFields(Object dataValue) {
 
 1017         if (dataValue instanceof byte[]) {
 
 1018             fieldEncrypted = 
true;
 
 1019             databaseEncrypted = 
true;
 
 1022         return dataValue.toString() != null ? dataValue.toString() : 
"";
 
 1026     private boolean isChromePreVersion30(String temps) {
 
 1027         String query = 
"PRAGMA table_info(downloads)"; 
 
 1028         List<HashMap<String, Object>> columns = this.dbConnect(temps, query);
 
 1029         for (HashMap<String, Object> col : columns) {
 
 1030             if (col.get(
"name").equals(
"url")) {