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 java.io.BufferedReader;
 
   33 import org.openide.util.NbBundle;
 
   35 import java.util.logging.Level;
 
   37 import java.io.FileNotFoundException;
 
   38 import java.io.FileReader;
 
   39 import java.io.IOException;
 
   40 import java.util.Collection;
 
   41 import java.util.List;
 
   43 import java.util.HashMap;
 
   44 import java.util.ArrayList;
 
   45 import java.util.Arrays;
 
   47 import org.apache.commons.io.FilenameUtils;
 
   48 import org.apache.commons.lang3.StringUtils;
 
   49 import org.openide.util.NbBundle.Messages;
 
   73 class Chromium 
extends Extract {
 
   75     private static final String HISTORY_QUERY = 
"SELECT urls.url, urls.title, urls.visit_count, urls.typed_count, "  
   76             + 
"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"; 
 
   77     private static final String COOKIE_QUERY = 
"SELECT name, value, host_key, expires_utc,last_access_utc, creation_utc FROM cookies"; 
 
   78     private static final String DOWNLOAD_QUERY = 
"SELECT full_path, url, start_time, received_bytes FROM downloads"; 
 
   79     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"; 
 
   80     private static final String LOGIN_QUERY = 
"SELECT origin_url, username_value, date_created, signon_realm from logins"; 
 
   81     private static final String AUTOFILL_QUERY = 
"SELECT name, value, count, date_created " 
   82             + 
" FROM autofill, autofill_dates " 
   83             + 
" WHERE autofill.pair_id = autofill_dates.pair_id"; 
 
   84     private static final String AUTOFILL_QUERY_V8X = 
"SELECT name, value, count, date_created, date_last_used from autofill"; 
 
   85     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 " 
   86             + 
" FROM autofill_profiles, autofill_profile_names, autofill_profile_emails, autofill_profile_phones" 
   87             + 
" WHERE autofill_profiles.guid = autofill_profile_names.guid AND autofill_profiles.guid = autofill_profile_emails.guid AND autofill_profiles.guid = autofill_profile_phones.guid";
 
   89     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" 
   90             + 
" FROM autofill_profiles, autofill_profile_names, autofill_profile_emails, autofill_profile_phones" 
   91             + 
" WHERE autofill_profiles.guid = autofill_profile_names.guid AND autofill_profiles.guid = autofill_profile_emails.guid AND autofill_profiles.guid = autofill_profile_phones.guid";
 
   92     private static final String FAVICON_QUERY = 
"SELECT page_url, last_updated, last_requested FROM icon_mapping, favicon_bitmaps " 
   93             + 
" WHERE icon_mapping.icon_id = favicon_bitmaps.icon_id";
 
   94     private static final String LOCALSTATE_FILE_NAME = 
"Local State";
 
   95     private static final String EXTENSIONS_FILE_NAME = 
"Secure Preferences";
 
   96     private static final String HISTORY_FILE_NAME = 
"History";
 
   97     private static final String BOOKMARK_FILE_NAME = 
"Bookmarks";
 
   98     private static final String COOKIE_FILE_NAME = 
"Cookies";
 
   99     private static final String LOGIN_DATA_FILE_NAME = 
"Login Data";
 
  100     private static final String WEB_DATA_FILE_NAME = 
"Web Data";
 
  101     private static final String FAVICON_DATA_FILE_NAME = 
"Favicons";
 
  102     private static final String UC_BROWSER_NAME = 
"UC Browser";
 
  103     private static final String OPERA_BROWSER_NAME = 
"Opera";
 
  104     private static final String ENCRYPTED_FIELD_MESSAGE = 
"The data was encrypted.";
 
  105     private static final String GOOGLE_PROFILE_NAME = 
"Profile";
 
  106     private static final String GOOGLE_PROFILE = 
"Google Chrome ";
 
  107     private static final String FAVICON_ARTIFACT_NAME = 
"TSK_FAVICON"; 
 
  108     private static final String LOCAL_STATE_ARTIFACT_NAME = 
"TSK_LOCAL_STATE"; 
 
  109     private static final String EXTENSIONS_ARTIFACT_NAME = 
"TSK_CHROME_EXTENSIONS"; 
 
  110     private static final String MALICIOUS_EXTENSION_FOUND = 
"Malicious Extension Found - ";
 
  112     private Boolean databaseEncrypted = 
false;
 
  113     private Boolean fieldEncrypted = 
false;
 
  115     private static final String MALICIOUS_CHROME_EXTENSION_LIST = 
"malicious_chrome_extensions.csv";
 
  116     private Map<String, String> maliciousChromeExtensions;
 
  118     private final Logger logger = Logger.getLogger(this.getClass().getName());
 
  119     private Content dataSource;
 
  120     private final IngestJobContext context;
 
  122     private Map<String, String> userProfiles;
 
  123     private Map<String, String> browserLocations;
 
  125     private static final Map<String, String> BROWSERS_MAP = ImmutableMap.<String, String>builder()
 
  126             .put(
"Microsoft Edge", 
"Microsoft/Edge/User Data")
 
  127             .put(
"Yandex", 
"YandexBrowser/User Data")
 
  128             .put(
"Opera", 
"Opera Software/Opera Stable")
 
  129             .put(
"SalamWeb", 
"SalamWeb/User Data")
 
  130             .put(
"UC Browser", 
"UCBrowser/User Data%")
 
  131             .put(
"Brave", 
"BraveSoftware/Brave-Browser/User Data")
 
  132             .put(
"Google Chrome", 
"Chrome/User Data")
 
  135     @Messages({
"# {0} - browserName",
 
  136         "Progress_Message_Chrome_History=Chrome History Browser {0}",
 
  137         "# {0} - browserName",
 
  138         "Progress_Message_Chrome_Bookmarks=Chrome Bookmarks Browser {0}",
 
  139         "# {0} - browserName",
 
  140         "Progress_Message_Chrome_Cookies=Chrome Cookies Browser {0}",
 
  141         "# {0} - browserName",
 
  142         "Progress_Message_Chrome_Downloads=Chrome Downloads Browser {0}",
 
  143         "Progress_Message_Chrome_Profiles=Chrome Profiles {0}",
 
  144         "Progress_Message_Chrome_Extensions=Chrome Extensions {0}",
 
  145         "Progress_Message_Chrome_Favicons=Chrome Downloads Favicons {0}",
 
  146         "Progress_Message_Chrome_FormHistory=Chrome Form History",
 
  147         "# {0} - browserName",
 
  148         "Progress_Message_Chrome_AutoFill=Chrome Auto Fill Browser {0}",
 
  149         "# {0} - browserName",
 
  150         "Progress_Message_Chrome_Logins=Chrome Logins Browser {0}",
 
  151         "Progress_Message_Chrome_Cache=Chrome Cache",})
 
  153     Chromium(IngestJobContext context) {
 
  154         super(NbBundle.getMessage(Chromium.class, 
"Chrome.moduleName"), context);
 
  155         this.context = context;
 
  159     public void process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
 
  160         this.dataSource = dataSource;
 
  162         long ingestJobId = context.getJobId();
 
  164         loadMaliciousChromeExetnsions();
 
  165         userProfiles = 
new HashMap<>();
 
  166         browserLocations = 
new HashMap<>();
 
  167         for (Map.Entry<String, String> browser : BROWSERS_MAP.entrySet()) {
 
  168             progressBar.progress(NbBundle.getMessage(
this.getClass(), 
"Progress_Message_Chrome_Profiles", browser.getKey()));
 
  169             getProfiles(browser.getKey(), browser.getValue(), ingestJobId);
 
  170             if (context.dataSourceIngestIsCancelled()) {
 
  174         for (Map.Entry<String, String> profile : userProfiles.entrySet()) {
 
  175             String browserLocation = profile.getKey(); 
 
  176             String browserName = browserLocations.get(browserLocation);
 
  177             String userName = profile.getValue();
 
  178             progressBar.progress(NbBundle.getMessage(
this.getClass(), 
"Progress_Message_Chrome_Extensions", browserName));
 
  179             this.getExtensions(browserName, browserLocation, userName, ingestJobId);
 
  180             if (context.dataSourceIngestIsCancelled()) {
 
  183             progressBar.progress(NbBundle.getMessage(
this.getClass(), 
"Progress_Message_Chrome_History", browserName));
 
  184             this.getHistory(browserName, browserLocation, userName, ingestJobId);
 
  185             if (context.dataSourceIngestIsCancelled()) {
 
  189             progressBar.progress(NbBundle.getMessage(
this.getClass(), 
"Progress_Message_Chrome_Bookmarks", browserName));
 
  190             this.getBookmark(browserName, browserLocation, userName, ingestJobId);
 
  191             if (context.dataSourceIngestIsCancelled()) {
 
  195             progressBar.progress(NbBundle.getMessage(
this.getClass(), 
"Progress_Message_Chrome_Cookies", browserName));
 
  196             this.getCookie(browserName, browserLocation, userName, ingestJobId);
 
  197             if (context.dataSourceIngestIsCancelled()) {
 
  201             progressBar.progress(NbBundle.getMessage(
this.getClass(), 
"Progress_Message_Chrome_Logins", browserName));
 
  202             this.getLogins(browserName, browserLocation, userName, ingestJobId);
 
  203             if (context.dataSourceIngestIsCancelled()) {
 
  207             progressBar.progress(NbBundle.getMessage(
this.getClass(), 
"Progress_Message_Chrome_AutoFill", browserName));
 
  208             this.getAutofill(browserName, browserLocation, userName, ingestJobId);
 
  209             if (context.dataSourceIngestIsCancelled()) {
 
  213             progressBar.progress(NbBundle.getMessage(
this.getClass(), 
"Progress_Message_Chrome_Downloads", browserName));
 
  214             this.getDownload(browserName, browserLocation, userName, ingestJobId);
 
  215             if (context.dataSourceIngestIsCancelled()) {
 
  219             progressBar.progress(NbBundle.getMessage(
this.getClass(), 
"Progress_Message_Chrome_Favicons", browserName));
 
  220             this.getFavicons(browserName, browserLocation, userName, ingestJobId);
 
  221             if (context.dataSourceIngestIsCancelled()) {
 
  226         progressBar.progress(Bundle.Progress_Message_Chrome_Cache());
 
  227         ChromeCacheExtractor chromeCacheExtractor = 
new ChromeCacheExtractor(dataSource, context, progressBar);
 
  228         chromeCacheExtractor.processCaches();
 
  238     private void getProfiles(String browser, String browserLocation, 
long ingestJobId) {
 
  239         FileManager fileManager = currentCase.getServices().getFileManager();
 
  240         String browserName = browser;
 
  241         List<AbstractFile> localStateFiles;
 
  242         String localStateName = LOCALSTATE_FILE_NAME;
 
  243         if (browserName.equals(UC_BROWSER_NAME)) {
 
  244             localStateName = LOCALSTATE_FILE_NAME + 
"%";
 
  247             localStateFiles = fileManager.findFiles(dataSource, localStateName, browserLocation); 
 
  248         } 
catch (TskCoreException ex) {
 
  249             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getLocalState.errMsg.errGettingFiles");
 
  250             logger.log(Level.SEVERE, msg, ex);
 
  251             this.addErrorMessage(this.getDisplayName() + 
": " + msg);
 
  256         List<AbstractFile> allocatedLocalStateFiles = 
new ArrayList<>();
 
  257         for (AbstractFile localStateFile : localStateFiles) {
 
  258             if (localStateFile.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC)) {
 
  259                 allocatedLocalStateFiles.add(localStateFile);
 
  264         if (allocatedLocalStateFiles.isEmpty()) {
 
  265             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getLocalState.errMsg.couldntFindAnyFiles");
 
  266             logger.log(Level.INFO, msg);
 
  271         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  273         while (j < allocatedLocalStateFiles.size()) {
 
  274             if (browser.contains(GOOGLE_PROFILE_NAME)) {
 
  275                 String parentPath = FilenameUtils.normalizeNoEndSeparator(allocatedLocalStateFiles.get(j).getParentPath());
 
  276                 browserName = GOOGLE_PROFILE + 
" " + FilenameUtils.getBaseName(parentPath);
 
  278             String temps = RAImageIngestModule.getRATempPath(currentCase, browserName, ingestJobId) + File.separator + allocatedLocalStateFiles.get(j).getName() + j; 
 
  279             final AbstractFile localStateFile = allocatedLocalStateFiles.get(j++);
 
  280             if ((localStateFile.getSize() == 0) || (localStateFile.getName().toLowerCase().contains(
"-slack"))
 
  281                     || (localStateFile.getName().toLowerCase().contains(
"cache")) || (localStateFile.getName().toLowerCase().contains(
"media"))
 
  282                     || (localStateFile.getName().toLowerCase().contains(
"index"))) {
 
  286                 ContentUtils.writeToFile(localStateFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  287             } 
catch (ReadContentInputStreamException ex) {
 
  288                 logger.log(Level.WARNING, String.format(
"Error reading Chrome web Local State artifacts file '%s' (id=%d).",
 
  289                         localStateFile.getName(), localStateFile.getId()), ex); 
 
  290                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getLocalState.errMsg.errAnalyzingFile",
 
  291                         this.getDisplayName(), localStateFile.getName()));
 
  293             } 
catch (IOException ex) {
 
  294                 logger.log(Level.SEVERE, String.format(
"Error writing temp file '%s' for Chrome Local State artifacts file '%s' (id=%d).",
 
  295                         temps, localStateFile.getName(), localStateFile.getId()), ex); 
 
  296                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getLocalState.errMsg.errAnalyzingFile",
 
  297                         this.getDisplayName(), localStateFile.getName()));
 
  301             if (context.dataSourceIngestIsCancelled()) {
 
  305             FileReader tempReader;
 
  307                 tempReader = 
new FileReader(temps);
 
  308             } 
catch (FileNotFoundException ex) {
 
  309                 logger.log(Level.WARNING, 
"Error while trying to read into the LocalState file.", ex); 
 
  313             JsonElement jsonElement;
 
  314             JsonObject jElement, jProfile, jInfoCache;
 
  317                 jsonElement = JsonParser.parseReader(tempReader);
 
  318                 jElement = jsonElement.getAsJsonObject();
 
  319                 if (jElement.has(
"profile")) {
 
  320                     jProfile = jElement.get(
"profile").getAsJsonObject(); 
 
  321                     jInfoCache = jProfile.get(
"info_cache").getAsJsonObject();
 
  323                     userProfiles.put(browserLocation, 
"Default");
 
  324                     browserLocations.put(browserLocation, browser);                    
 
  327             } 
catch (JsonIOException | JsonSyntaxException | IllegalStateException ex) {
 
  328                 logger.log(Level.WARNING, 
"Error parsing Json from LocalState.", ex); 
 
  329                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getlocalState.errMsg.errAnalyzingFile",
 
  330                         this.getDisplayName(), localStateFile.getName()));
 
  334             BlackboardArtifact.Type localStateArtifactType;
 
  337                 localStateArtifactType = createArtifactType(LOCAL_STATE_ARTIFACT_NAME, NbBundle.getMessage(
this.getClass(), 
"Chrome.getLocalState.displayName"));
 
  338             } 
catch (TskCoreException ex) {
 
  339                 logger.log(Level.SEVERE, String.format(
"Error creating artifact type for LocalState."), ex); 
 
  340                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getfavicon.errMsg.errCreateArtifact"));
 
  344             Set<String> profileNames = jInfoCache.keySet();
 
  345             for (String profileName : profileNames) {
 
  346                 JsonElement result = jInfoCache.get(profileName);
 
  347                 JsonObject profile = result.getAsJsonObject();
 
  348                 if (profile == null) {
 
  351                 JsonElement gaiaIdEl = profile.get(
"gaia_id"); 
 
  353                 if (gaiaIdEl != null) {
 
  354                     gaiaId = gaiaIdEl.getAsString();
 
  359                 JsonElement hostedDomainEl = profile.get(
"hosted_domain"); 
 
  360                 if (hostedDomainEl != null) {
 
  361                     hostedDomain = hostedDomainEl.getAsString();
 
  366                 JsonElement shortcutNameEl = profile.get(
"shortcut_name"); 
 
  367                 if (shortcutNameEl != null) {
 
  368                     shortcutName = shortcutNameEl.getAsString();
 
  373                 JsonElement nameEl = profile.get(
"name"); 
 
  374                 if (nameEl != null) {
 
  375                     name = nameEl.getAsString();
 
  380                 JsonElement userNameEl = profile.get(
"user_name"); 
 
  381                 if (userNameEl != null) {
 
  382                     userName = userNameEl.getAsString();
 
  387                 if (userName.contains(
"")) {
 
  388                     userProfiles.put(browserLocation + 
"/" + profileName, name);
 
  389                     browserLocations.put(browserLocation + 
"/" + profileName, browser);                    
 
  391                     userProfiles.put(browserLocation + 
"/" + profileName, userName);
 
  392                     browserLocations.put(browserLocation + 
"/" + profileName, browser);                    
 
  395                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  396                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
 
  397                         RecentActivityExtracterModuleFactory.getModuleName(), profileName));
 
  398                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_ID,
 
  399                         RecentActivityExtracterModuleFactory.getModuleName(), gaiaId));
 
  400                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  401                         RecentActivityExtracterModuleFactory.getModuleName(), hostedDomain));
 
  402                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SHORTCUT,
 
  403                         RecentActivityExtracterModuleFactory.getModuleName(), shortcutName));
 
  404                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
 
  405                         RecentActivityExtracterModuleFactory.getModuleName(), name));
 
  406                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
 
  407                         RecentActivityExtracterModuleFactory.getModuleName(), userName));
 
  408                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  409                         RecentActivityExtracterModuleFactory.getModuleName(), browserName));
 
  412                     bbartifacts.add(createArtifactWithAttributes(localStateArtifactType, localStateFile, bbattributes));
 
  413                 } 
catch (TskCoreException ex) {
 
  414                     logger.log(Level.SEVERE, String.format(
"Failed to create bookmark artifact for file (%d)", localStateFile.getId()), ex);
 
  419             if (!context.dataSourceIngestIsCancelled()) {
 
  420                 postArtifacts(bbartifacts);
 
  426         if (!userProfiles.containsKey(
"Default")) {
 
  427             userProfiles.put(browserLocation + 
"/" + 
"Default", 
"Default");
 
  428             browserLocations.put(browserLocation + 
"/" + 
"Default", browser);
 
  430         if (!userProfiles.containsKey(
"Guest Profile")) {
 
  431             userProfiles.put(browserLocation + 
"/" + 
"Guest Profile", 
"Guest");
 
  432             browserLocations.put(browserLocation + 
"/" + 
"Guest Profile", browser);
 
  434         if (!userProfiles.containsKey(
"System Profile")) {
 
  435             userProfiles.put(browserLocation + 
"/" + 
"System Profile", 
"System");
 
  436             browserLocations.put(browserLocation + 
"/" + 
"System Profile", browser);
 
  447     private void getExtensions(String browser, String browserLocation, String userName, 
long ingestJobId) {
 
  448         FileManager fileManager = currentCase.getServices().getFileManager();
 
  449         String browserName = browser;
 
  450         List<AbstractFile> extensionFiles;
 
  451         String extensionsName = EXTENSIONS_FILE_NAME;
 
  452         if (browserName.equals(UC_BROWSER_NAME)) {
 
  453             extensionsName = EXTENSIONS_FILE_NAME + 
"%";
 
  457             extensionFiles = fileManager.findFiles(dataSource, extensionsName, browserLocation); 
 
  458         } 
catch (TskCoreException ex) {
 
  459             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getExtensions.errMsg.errGettingFiles");
 
  460             logger.log(Level.SEVERE, msg, ex);
 
  461             this.addErrorMessage(this.getDisplayName() + 
": " + msg);
 
  466         List<AbstractFile> allocatedExtensionsFiles = 
new ArrayList<>();
 
  467         for (AbstractFile extensionFile : extensionFiles) {
 
  468             if (extensionFile.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC)) {
 
  469                 allocatedExtensionsFiles.add(extensionFile);
 
  474         if (allocatedExtensionsFiles.isEmpty()) {
 
  475             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getExtensions.errMsg.couldntFindAnyFiles");
 
  476             logger.log(Level.INFO, msg);
 
  481         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  483         while (j < allocatedExtensionsFiles.size()) {
 
  484             if (browser.contains(GOOGLE_PROFILE_NAME)) {
 
  485                 String parentPath = FilenameUtils.normalizeNoEndSeparator(allocatedExtensionsFiles.get(j).getParentPath());
 
  486                 browserName = GOOGLE_PROFILE + 
" " + FilenameUtils.getBaseName(parentPath);
 
  488             String temps = RAImageIngestModule.getRATempPath(currentCase, browserName, ingestJobId) + File.separator + allocatedExtensionsFiles.get(j).getName() + j; 
 
  489             final AbstractFile extensionFile = allocatedExtensionsFiles.get(j++);
 
  490             if ((extensionFile.getSize() == 0) || (extensionFile.getName().toLowerCase().contains(
"-slack"))
 
  491                     || (extensionFile.getName().toLowerCase().contains(
"cache")) || (extensionFile.getName().toLowerCase().contains(
"media"))
 
  492                     || (extensionFile.getName().toLowerCase().contains(
"index"))) {
 
  496                 ContentUtils.writeToFile(extensionFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  497             } 
catch (ReadContentInputStreamException ex) {
 
  498                 logger.log(Level.WARNING, String.format(
"Error reading Chrome web extension artifacts file '%s' (id=%d).",
 
  499                         extensionFile.getName(), extensionFile.getId()), ex); 
 
  500                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getExtensions.errMsg.errAnalyzingFile",
 
  501                         this.getDisplayName(), extensionFile.getName()));
 
  503             } 
catch (IOException ex) {
 
  504                 logger.log(Level.SEVERE, String.format(
"Error writing temp file '%s' for Chrome Extensions artifacts file '%s' (id=%d).",
 
  505                         temps, extensionFile.getName(), extensionFile.getId()), ex); 
 
  506                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getExtensions.errMsg.errAnalyzingFile",
 
  507                         this.getDisplayName(), extensionFile.getName()));
 
  511             if (context.dataSourceIngestIsCancelled()) {
 
  515             FileReader tempReader;
 
  517                 tempReader = 
new FileReader(temps);
 
  518             } 
catch (FileNotFoundException ex) {
 
  519                 logger.log(Level.WARNING, 
"Error while trying to read into the Secure Preferences file.", ex); 
 
  523             BlackboardArtifact.Type localStateArtifactType;
 
  526                 localStateArtifactType = createArtifactType(EXTENSIONS_ARTIFACT_NAME, NbBundle.getMessage(
this.getClass(), 
"Chrome.getExtensions.displayName"));
 
  527             } 
catch (TskCoreException ex) {
 
  528                 logger.log(Level.SEVERE, String.format(
"Error creating artifact type for Secure Preferences."), ex); 
 
  529                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getExtensions.errMsg.errCreateArtifact"));
 
  533             String profileName = FilenameUtils.getBaseName(StringUtils.chop(extensionFile.getParentPath()));
 
  535             JsonElement jsonElement;
 
  536             JsonObject jElement, jExtensions, jSettings;
 
  539                 jsonElement = JsonParser.parseReader(tempReader);
 
  540                 jElement = jsonElement.getAsJsonObject();
 
  541                 if (jElement.has(
"extensions")) {
 
  542                     logger.log(Level.WARNING, String.format(
"Processing Secure Preferences from %s", extensionFile.getParentPath()));
 
  543                     jExtensions = jElement.get(
"extensions").getAsJsonObject(); 
 
  544                     if (!browserName.equals(OPERA_BROWSER_NAME)) {
 
  545                         jSettings = jExtensions.get(
"settings").getAsJsonObject();
 
  547                         jSettings = jExtensions.get(
"opsettings").getAsJsonObject();
 
  552             } 
catch (JsonIOException | JsonSyntaxException | IllegalStateException ex) {
 
  553                 logger.log(Level.WARNING, 
"Error parsing Json from Secure Preferences.", ex); 
 
  554                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getExtensoins.errMsg.errAnalyzingFile",
 
  555                         this.getDisplayName(), extensionFile.getName()));
 
  559             Set<String> extensions = jSettings.keySet();
 
  560             for (String extension : extensions) {
 
  561                 JsonElement result = jSettings.get(extension);
 
  562                 JsonObject ext = result.getAsJsonObject();
 
  566                 JsonElement flagEl = ext.get(
"state"); 
 
  568                 if (flagEl != null) {
 
  569                     if (flagEl.getAsInt() == 1) {
 
  577                 String apiGrantedPermissions = 
"";
 
  578                 if (ext.has(
"active_permissions")) {
 
  579                     JsonObject permissions = ext.get(
"active_permissions").getAsJsonObject();
 
  580                     JsonArray apiPermissions = permissions.get(
"api").getAsJsonArray();
 
  581                     for (JsonElement apiPermission : apiPermissions) {
 
  582                         if (apiPermission.isJsonPrimitive()) {
 
  583                             String apigrantEl = apiPermission.getAsString();                   
 
  584                             if (apigrantEl != null) {
 
  585                                 apiGrantedPermissions = apiGrantedPermissions + 
", " + apigrantEl;
 
  587                                 apiGrantedPermissions =  apiGrantedPermissions + 
"";
 
  595                 if (ext.has(
"manifest")) {
 
  596                     JsonObject manifest = ext.get(
"manifest").getAsJsonObject();
 
  597                     JsonElement descriptionEl = manifest.get(
"description");
 
  598                     if (descriptionEl != null) {
 
  599                         description = descriptionEl.getAsString();
 
  603                     JsonElement versionEl = manifest.get(
"version");
 
  604                     if (versionEl != null) {
 
  605                         version = versionEl.getAsString();
 
  609                     JsonElement extNameEl = manifest.get(
"name");
 
  610                     if (extNameEl != null) {
 
  611                         extName = extNameEl.getAsString();
 
  620                 BlackboardArtifact art = null;
 
  621                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  622                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ID,
 
  623                         RecentActivityExtracterModuleFactory.getModuleName(), extension));
 
  624                 if (maliciousChromeExtensions.get(extension) != null) {
 
  625                     bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT,
 
  626                         RecentActivityExtracterModuleFactory.getModuleName(), 
 
  627                         MALICIOUS_EXTENSION_FOUND + maliciousChromeExtensions.getOrDefault(extension, 
"No Source Identified")));
 
  629                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
 
  630                         RecentActivityExtracterModuleFactory.getModuleName(), extName));
 
  631                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DESCRIPTION,
 
  632                         RecentActivityExtracterModuleFactory.getModuleName(), description));
 
  633                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VERSION,
 
  634                         RecentActivityExtracterModuleFactory.getModuleName(), version));
 
  635                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_FLAG,
 
  636                         RecentActivityExtracterModuleFactory.getModuleName(), flag));
 
  637                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PERMISSIONS,
 
  638                         RecentActivityExtracterModuleFactory.getModuleName(), apiGrantedPermissions.replaceFirst(
", ", 
"")));
 
  639                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
 
  640                         RecentActivityExtracterModuleFactory.getModuleName(), userName));
 
  641                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  642                         RecentActivityExtracterModuleFactory.getModuleName(), browserName));
 
  645                     art = createArtifactWithAttributes(localStateArtifactType, extensionFile, bbattributes);
 
  646                     bbartifacts.add(art);
 
  647                 } 
catch (TskCoreException ex) {
 
  648                     logger.log(Level.SEVERE, String.format(
"Failed to create Extension artifact for file (%d)", extensionFile.getId()), ex);
 
  652             if (!context.dataSourceIngestIsCancelled()) {
 
  653                 postArtifacts(bbartifacts);
 
  667     private void getHistory(String browser, String browserLocation, String userName, 
long ingestJobId) {
 
  668         FileManager fileManager = currentCase.getServices().getFileManager();
 
  669         String browserName = browser;
 
  670         List<AbstractFile> historyFiles;
 
  671         String historyFileName = HISTORY_FILE_NAME;
 
  672         if (browserName.equals(UC_BROWSER_NAME)) {
 
  673             historyFileName = HISTORY_FILE_NAME + 
"%";
 
  676             historyFiles = fileManager.findFiles(dataSource, historyFileName, browserLocation); 
 
  677         } 
catch (TskCoreException ex) {
 
  678             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getHistory.errMsg.errGettingFiles");
 
  679             logger.log(Level.SEVERE, msg, ex);
 
  680             this.addErrorMessage(this.getDisplayName() + 
": " + msg);
 
  685         List<AbstractFile> allocatedHistoryFiles = 
new ArrayList<>();
 
  686         for (AbstractFile historyFile : historyFiles) {
 
  687             if (historyFile.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC)) {
 
  688                 allocatedHistoryFiles.add(historyFile);
 
  693         if (allocatedHistoryFiles.isEmpty()) {
 
  694             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getHistory.errMsg.couldntFindAnyFiles");
 
  695             logger.log(Level.INFO, msg);
 
  700         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  702         while (j < allocatedHistoryFiles.size()) {
 
  703             if (browser.contains(GOOGLE_PROFILE_NAME)) {
 
  704                 String parentPath = FilenameUtils.normalizeNoEndSeparator(allocatedHistoryFiles.get(j).getParentPath());
 
  705                 browserName = GOOGLE_PROFILE + 
" " + FilenameUtils.getBaseName(parentPath);
 
  707             String temps = RAImageIngestModule.getRATempPath(currentCase, browserName, ingestJobId) + File.separator + allocatedHistoryFiles.get(j).getName() + j + 
".db"; 
 
  708             final AbstractFile historyFile = allocatedHistoryFiles.get(j++);
 
  709             if ((historyFile.getSize() == 0) || (historyFile.getName().toLowerCase().contains(
"-slack"))
 
  710                     || (historyFile.getName().toLowerCase().contains(
"cache")) || (historyFile.getName().toLowerCase().contains(
"media"))
 
  711                     || (historyFile.getName().toLowerCase().contains(
"index"))) {
 
  715                 ContentUtils.writeToFile(historyFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  716             } 
catch (ReadContentInputStreamException ex) {
 
  717                 logger.log(Level.WARNING, String.format(
"Error reading Chrome web history artifacts file '%s' (id=%d).",
 
  718                         historyFile.getName(), historyFile.getId()), ex); 
 
  719                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getHistory.errMsg.errAnalyzingFile",
 
  720                         this.getDisplayName(), historyFile.getName()));
 
  722             } 
catch (IOException ex) {
 
  723                 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Chrome web history artifacts file '%s' (id=%d).",
 
  724                         temps, historyFile.getName(), historyFile.getId()), ex); 
 
  725                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getHistory.errMsg.errAnalyzingFile",
 
  726                         this.getDisplayName(), historyFile.getName()));
 
  729             File dbFile = 
new File(temps);
 
  730             if (context.dataSourceIngestIsCancelled()) {
 
  734             List<HashMap<String, Object>> tempList;
 
  735             tempList = this.querySQLiteDb(temps, HISTORY_QUERY);
 
  736             logger.log(Level.INFO, 
"{0}- Now getting history from {1} with {2} artifacts identified.", 
new Object[]{getDisplayName(), temps, tempList.size()}); 
 
  737             for (HashMap<String, Object> result : tempList) {
 
  738                 String url = result.get(
"url") == null ? 
"" : result.get(
"url").toString();
 
  739                 String extractedDomain = NetworkUtils.extractDomain(url);
 
  742                     Collection<BlackboardAttribute> bbattributes = createHistoryAttributes(
 
  743                         StringUtils.defaultString(url), 
 
  744                         (Long.valueOf(result.get(
"last_visit_time").toString()) / 1000000) - Long.valueOf(
"11644473600"),
 
  745                         result.get(
"from_visit") == null ? 
"" : result.get(
"from_visit").toString(),
 
  746                         result.get(
"title") == null ? 
"" : result.get(
"title").toString(),
 
  751                     bbartifacts.add(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_WEB_HISTORY, historyFile, bbattributes));
 
  752                 } 
catch (TskCoreException ex) {
 
  753                     logger.log(Level.SEVERE, String.format(
"Failed to create history artifact for file (%d)", historyFile.getId()), ex);
 
  759         if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
 
  760             postArtifacts(bbartifacts);
 
  771     private void getBookmark(String browser, String browserLocation, String userName, 
long ingestJobId) {
 
  772         FileManager fileManager = currentCase.getServices().getFileManager();
 
  773         List<AbstractFile> bookmarkFiles;
 
  774         String browserName = browser;
 
  775         String bookmarkFileName = BOOKMARK_FILE_NAME;
 
  776         if (browserName.equals(UC_BROWSER_NAME)) {
 
  777             bookmarkFileName = BOOKMARK_FILE_NAME + 
"%";
 
  780             bookmarkFiles = fileManager.findFiles(dataSource, bookmarkFileName, browserLocation); 
 
  781         } 
catch (TskCoreException ex) {
 
  782             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getBookmark.errMsg.errGettingFiles");
 
  783             logger.log(Level.SEVERE, msg, ex);
 
  784             this.addErrorMessage(this.getDisplayName() + 
": " + msg);
 
  788         if (bookmarkFiles.isEmpty()) {
 
  789             logger.log(Level.INFO, 
"Didn't find any Chrome bookmark files."); 
 
  794         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  796         while (j < bookmarkFiles.size()) {
 
  797             if (browser.contains(GOOGLE_PROFILE_NAME)) {
 
  798                 String parentPath = FilenameUtils.normalizeNoEndSeparator(bookmarkFiles.get(j).getParentPath());
 
  799                 browserName = GOOGLE_PROFILE + 
" " + FilenameUtils.getBaseName(parentPath);
 
  802             AbstractFile bookmarkFile = bookmarkFiles.get(j++);
 
  803             if ((bookmarkFile.getSize() == 0) || (bookmarkFile.getName().toLowerCase().contains(
"-slack"))
 
  804                     || (bookmarkFile.getName().toLowerCase().contains(
"extras")) || (bookmarkFile.getName().toLowerCase().contains(
"log"))
 
  805                     || (bookmarkFile.getName().toLowerCase().contains(
"backup")) || (bookmarkFile.getName().toLowerCase().contains(
"visualized"))
 
  806                     || (bookmarkFile.getName().toLowerCase().contains(
"bak")) || (bookmarkFile.getParentPath().toLowerCase().contains(
"backup"))) {
 
  809             String temps = RAImageIngestModule.getRATempPath(currentCase, browserName, ingestJobId) + File.separator + bookmarkFile.getName() + j + 
".db"; 
 
  811                 ContentUtils.writeToFile(bookmarkFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  812             } 
catch (ReadContentInputStreamException ex) {
 
  813                 logger.log(Level.WARNING, String.format(
"Error reading Chrome bookmark artifacts file '%s' (id=%d).",
 
  814                         bookmarkFile.getName(), bookmarkFile.getId()), ex); 
 
  815                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getBookmark.errMsg.errAnalyzingFile",
 
  816                         this.getDisplayName(), bookmarkFile.getName()));
 
  818             } 
catch (IOException ex) {
 
  819                 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Chrome bookmark artifacts file '%s' (id=%d).",
 
  820                         temps, bookmarkFile.getName(), bookmarkFile.getId()), ex); 
 
  821                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getBookmark.errMsg.errAnalyzingFile",
 
  822                         this.getDisplayName(), bookmarkFile.getName()));
 
  826             logger.log(Level.INFO, 
"{0}- Now getting Bookmarks from {1}", 
new Object[]{getDisplayName(), temps}); 
 
  827             File dbFile = 
new File(temps);
 
  828             if (context.dataSourceIngestIsCancelled()) {
 
  833             FileReader tempReader;
 
  835                 tempReader = 
new FileReader(temps);
 
  836             } 
catch (FileNotFoundException ex) {
 
  837                 logger.log(Level.WARNING, 
"Error while trying to read into the Bookmarks for Chrome.", ex); 
 
  841             JsonElement jsonElement;
 
  842             JsonObject jElement, jRoot;
 
  845                 jsonElement = JsonParser.parseReader(tempReader);
 
  846                 jElement = jsonElement.getAsJsonObject();
 
  847                 jRoot = jElement.get(
"roots").getAsJsonObject(); 
 
  848                 Set<String> bookmarkKeys = jRoot.keySet();
 
  849             } 
catch (JsonIOException | JsonSyntaxException | IllegalStateException ex) {
 
  850                 logger.log(Level.WARNING, 
"Error parsing Json from Chrome Bookmark.", ex); 
 
  851                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getBookmark.errMsg.errAnalyzingFile3",
 
  852                         this.getDisplayName(), bookmarkFile.getName()));
 
  856             Set<String> bookmarkKeys = jRoot.keySet();
 
  857             for (String bookmarkKey : bookmarkKeys) {
 
  858                 JsonObject jBookmark = jRoot.get(bookmarkKey).getAsJsonObject(); 
 
  859                 if (jBookmark.has(
"children")) {
 
  860                     JsonArray jBookmarkArray = jBookmark.getAsJsonArray(
"children"); 
 
  861                     for (JsonElement result : jBookmarkArray) {
 
  862                         JsonObject address = result.getAsJsonObject();
 
  863                         if (address == null) {
 
  866                         JsonElement urlEl = address.get(
"url"); 
 
  869                             url = urlEl.getAsString();
 
  874                         JsonElement nameEl = address.get(
"name"); 
 
  875                         if (nameEl != null) {
 
  876                             name = nameEl.getAsString();
 
  881                         JsonElement dateEl = address.get(
"date_added"); 
 
  882                         if (dateEl != null) {
 
  883                             date = dateEl.getAsLong();
 
  885                             date = Long.valueOf(0);
 
  887                         String domain = NetworkUtils.extractDomain(url);
 
  888                         Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  890                         bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  891                                 RecentActivityExtracterModuleFactory.getModuleName(), url));
 
  892                         bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
 
  893                                 RecentActivityExtracterModuleFactory.getModuleName(), name));
 
  894                         bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
 
  895                                 RecentActivityExtracterModuleFactory.getModuleName(), (date / 1000000) - Long.valueOf(
"11644473600")));
 
  896                         bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  897                                 RecentActivityExtracterModuleFactory.getModuleName(), browserName));
 
  898                         bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  899                                 RecentActivityExtracterModuleFactory.getModuleName(), domain));
 
  900                         bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
 
  901                                 RecentActivityExtracterModuleFactory.getModuleName(), userName));
 
  902                         bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT,
 
  903                                 RecentActivityExtracterModuleFactory.getModuleName(), bookmarkKey));
 
  907                             bbartifacts.add(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_WEB_BOOKMARK, bookmarkFile, bbattributes));
 
  908                         } 
catch (TskCoreException ex) {
 
  909                             logger.log(Level.SEVERE, String.format(
"Failed to create bookmark artifact for file (%d)", bookmarkFile.getId()), ex);
 
  916             if (!context.dataSourceIngestIsCancelled()) {
 
  917                 postArtifacts(bbartifacts);
 
  931     private void getCookie(String browser, String browserLocation, String userName, 
long ingestJobId) {
 
  933         FileManager fileManager = currentCase.getServices().getFileManager();
 
  934         List<AbstractFile> cookiesFiles;
 
  935         String browserName = browser;
 
  936         String cookieFileName = COOKIE_FILE_NAME;
 
  937         if (browserName.equals(UC_BROWSER_NAME)) {
 
  940             cookieFileName = 
"%" + COOKIE_FILE_NAME + 
"%";
 
  943             cookiesFiles = fileManager.findFiles(dataSource, cookieFileName, browserLocation); 
 
  944         } 
catch (TskCoreException ex) {
 
  945             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getCookie.errMsg.errGettingFiles");
 
  946             logger.log(Level.SEVERE, msg, ex);
 
  947             this.addErrorMessage(this.getDisplayName() + 
": " + msg);
 
  951         if (cookiesFiles.isEmpty()) {
 
  952             logger.log(Level.INFO, 
"Didn't find any Chrome cookies files."); 
 
  957         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  959         while (j < cookiesFiles.size()) {
 
  960             if (browser.contains(GOOGLE_PROFILE_NAME)) {
 
  961                 String parentPath = FilenameUtils.normalizeNoEndSeparator(cookiesFiles.get(j).getParentPath());
 
  962                 browserName = GOOGLE_PROFILE + FilenameUtils.getBaseName(parentPath);
 
  965             AbstractFile cookiesFile = cookiesFiles.get(j++);
 
  966             if ((cookiesFile.getSize() == 0) || (cookiesFile.getName().toLowerCase().contains(
"-slack"))) {
 
  969             String temps = RAImageIngestModule.getRATempPath(currentCase, browserName, ingestJobId) + File.separator + cookiesFile.getName() + j + 
".db"; 
 
  971                 ContentUtils.writeToFile(cookiesFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  972             } 
catch (ReadContentInputStreamException ex) {
 
  973                 logger.log(Level.WARNING, String.format(
"Error reading Chrome cookie artifacts file '%s' (id=%d).",
 
  974                         cookiesFile.getName(), cookiesFile.getId()), ex); 
 
  975                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getCookie.errMsg.errAnalyzeFile",
 
  976                         this.getDisplayName(), cookiesFile.getName()));
 
  978             } 
catch (IOException ex) {
 
  979                 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Chrome cookie artifacts file '%s' (id=%d).",
 
  980                         temps, cookiesFile.getName(), cookiesFile.getId()), ex); 
 
  981                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getCookie.errMsg.errAnalyzeFile",
 
  982                         this.getDisplayName(), cookiesFile.getName()));
 
  985             File dbFile = 
new File(temps);
 
  986             if (context.dataSourceIngestIsCancelled()) {
 
  991             List<HashMap<String, Object>> tempList = this.querySQLiteDb(temps, COOKIE_QUERY);
 
  992             logger.log(Level.INFO, 
"{0}- Now getting cookies from {1} with {2} artifacts identified.", 
new Object[]{getDisplayName(), temps, tempList.size()}); 
 
  993             for (HashMap<String, Object> result : tempList) {
 
  994                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  995                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  996                         RecentActivityExtracterModuleFactory.getModuleName(),
 
  997                         ((result.get(
"host_key").toString() != null) ? result.get(
"host_key").toString() : 
""))); 
 
  998                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
 
  999                         RecentActivityExtracterModuleFactory.getModuleName(),
 
 1000                         (Long.valueOf(result.get(
"last_access_utc").toString()) / 1000000) - Long.valueOf(
"11644473600"))); 
 
 1002                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
 
 1003                         RecentActivityExtracterModuleFactory.getModuleName(),
 
 1004                         ((result.get(
"name").toString() != null) ? result.get(
"name").toString() : 
""))); 
 
 1005                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
 
 1006                         RecentActivityExtracterModuleFactory.getModuleName(),
 
 1007                         ((result.get(
"value").toString() != null) ? result.get(
"value").toString() : 
""))); 
 
 1008                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
 1009                         RecentActivityExtracterModuleFactory.getModuleName(), browserName));
 
 1010                 String domain = result.get(
"host_key").toString(); 
 
 1011                 domain = domain.replaceFirst(
"^\\.+(?!$)", 
"");
 
 1012                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
 1013                         RecentActivityExtracterModuleFactory.getModuleName(), domain));
 
 1014                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
 
 1015                         RecentActivityExtracterModuleFactory.getModuleName(), userName));
 
 1018                     bbartifacts.add(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_WEB_COOKIE, cookiesFile, bbattributes));
 
 1019                 } 
catch (TskCoreException ex) {
 
 1020                     logger.log(Level.SEVERE, String.format(
"Failed to create cookie artifact for file (%d)", cookiesFile.getId()), ex);
 
 1027         if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
 
 1028             postArtifacts(bbartifacts);
 
 1039     private void getDownload(String browser, String browserLocation, String userName, 
long ingestJobId) {
 
 1040         FileManager fileManager = currentCase.getServices().getFileManager();
 
 1041         List<AbstractFile> downloadFiles;
 
 1042         String browserName = browser;
 
 1043         String historyFileName = HISTORY_FILE_NAME;
 
 1044         if (browserName.equals(UC_BROWSER_NAME)) {
 
 1045             historyFileName = HISTORY_FILE_NAME + 
"%";
 
 1048             downloadFiles = fileManager.findFiles(dataSource, historyFileName, browserLocation); 
 
 1049         } 
catch (TskCoreException ex) {
 
 1050             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getDownload.errMsg.errGettingFiles");
 
 1051             logger.log(Level.SEVERE, msg, ex);
 
 1052             this.addErrorMessage(this.getDisplayName() + 
": " + msg);
 
 1056         if (downloadFiles.isEmpty()) {
 
 1057             logger.log(Level.INFO, 
"Didn't find any Chrome download files."); 
 
 1062         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
 1064         while (j < downloadFiles.size()) {
 
 1065             if (browser.contains(GOOGLE_PROFILE_NAME)) {
 
 1066                 String parentPath = FilenameUtils.normalizeNoEndSeparator(downloadFiles.get(j).getParentPath());
 
 1067                 browserName = GOOGLE_PROFILE + FilenameUtils.getBaseName(parentPath);
 
 1070             AbstractFile downloadFile = downloadFiles.get(j++);
 
 1071             if ((downloadFile.getSize() == 0) || (downloadFile.getName().toLowerCase().contains(
"-slack"))
 
 1072                     || (downloadFile.getName().toLowerCase().contains(
"cache")) || (downloadFile.getName().toLowerCase().contains(
"index"))) {
 
 1076             String temps = RAImageIngestModule.getRATempPath(currentCase, browserName, ingestJobId) + File.separator + downloadFile.getName() + j + 
".db"; 
 
 1078                 ContentUtils.writeToFile(downloadFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
 1079             } 
catch (ReadContentInputStreamException ex) {
 
 1080                 logger.log(Level.WARNING, String.format(
"Error reading Chrome download artifacts file '%s' (id=%d).",
 
 1081                         downloadFile.getName(), downloadFile.getId()), ex); 
 
 1082                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getDownload.errMsg.errAnalyzeFiles1",
 
 1083                         this.getDisplayName(), downloadFile.getName()));
 
 1085             } 
catch (IOException ex) {
 
 1086                 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Chrome download artifacts file '%s' (id=%d).",
 
 1087                         temps, downloadFile.getName(), downloadFile.getId()), ex); 
 
 1088                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getDownload.errMsg.errAnalyzeFiles1",
 
 1089                         this.getDisplayName(), downloadFile.getName()));
 
 1092             File dbFile = 
new File(temps);
 
 1093             if (context.dataSourceIngestIsCancelled()) {
 
 1098             List<HashMap<String, Object>> tempList;
 
 1100             if (isChromePreVersion30(temps)) {
 
 1101                 tempList = this.querySQLiteDb(temps, DOWNLOAD_QUERY);
 
 1103                 tempList = this.querySQLiteDb(temps, DOWNLOAD_QUERY_V30);
 
 1106             logger.log(Level.INFO, 
"{0}- Now getting downloads from {1} with {2} artifacts identified.", 
new Object[]{getDisplayName(), temps, tempList.size()}); 
 
 1107             for (HashMap<String, Object> result : tempList) {
 
 1108                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
 1109                 String fullPath = result.get(
"full_path").toString(); 
 
 1110                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
 
 1111                         RecentActivityExtracterModuleFactory.getModuleName(), fullPath));
 
 1112                 long pathID = Util.findID(dataSource, fullPath);
 
 1114                     bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
 
 1115                             NbBundle.getMessage(
this.getClass(),
 
 1116                                     "Chrome.parentModuleName"), pathID));
 
 1118                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
 1119                         RecentActivityExtracterModuleFactory.getModuleName(),
 
 1120                         ((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
""))); 
 
 1122                 Long time = (Long.valueOf(result.get(
"start_time").toString()) / 1000000) - Long.valueOf(
"11644473600"); 
 
 1126                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
 
 1127                         RecentActivityExtracterModuleFactory.getModuleName(), time));
 
 1128                 String domain = NetworkUtils.extractDomain((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
""); 
 
 1129                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
 1130                         RecentActivityExtracterModuleFactory.getModuleName(), domain));
 
 1131                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
 
 1132                         RecentActivityExtracterModuleFactory.getModuleName(), userName));
 
 1133                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
 1134                         RecentActivityExtracterModuleFactory.getModuleName(), browserName));
 
 1138                     BlackboardArtifact webDownloadArtifact = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_WEB_DOWNLOAD, downloadFile, bbattributes);
 
 1139                     bbartifacts.add(webDownloadArtifact);
 
 1140                     String normalizedFullPath = FilenameUtils.normalize(fullPath, 
true);
 
 1141                     for (AbstractFile downloadedFile : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, FilenameUtils.getName(normalizedFullPath), FilenameUtils.getPath(normalizedFullPath))) {
 
 1142                         bbartifacts.add(createAssociatedArtifact(downloadedFile, webDownloadArtifact));
 
 1145                 } 
catch (TskCoreException ex) {
 
 1146                     logger.log(Level.SEVERE, String.format(
"Error creating associated object artifact for file  '%s'", fullPath), ex); 
 
 1153         if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
 
 1154             postArtifacts(bbartifacts);
 
 1165     private void getFavicons(String browser, String browserLocation, String userName, 
long ingestJobId) {
 
 1166         FileManager fileManager = currentCase.getServices().getFileManager();
 
 1167         List<AbstractFile> faviconFiles;
 
 1168         String browserName = browser;
 
 1170             faviconFiles = fileManager.findFiles(dataSource, FAVICON_DATA_FILE_NAME, browserLocation); 
 
 1171         } 
catch (TskCoreException ex) {
 
 1172             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getFavicon.errMsg.errGettingFiles");
 
 1173             logger.log(Level.SEVERE, msg, ex);
 
 1174             this.addErrorMessage(this.getDisplayName() + 
": " + msg);
 
 1178         if (faviconFiles.isEmpty()) {
 
 1179             logger.log(Level.INFO, 
"Didn't find any Chrome favicon files."); 
 
 1184         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
 1186         while (j < faviconFiles.size()) {
 
 1187             if (browser.contains(GOOGLE_PROFILE_NAME)) {
 
 1188                 String parentPath = FilenameUtils.normalizeNoEndSeparator(faviconFiles.get(j).getParentPath());
 
 1189                 browserName = GOOGLE_PROFILE + FilenameUtils.getBaseName(parentPath);
 
 1191             AbstractFile faviconFile = faviconFiles.get(j++);
 
 1192             if ((faviconFile.getSize() == 0) || (faviconFile.getName().toLowerCase().contains(
"-slack"))
 
 1193                     || (faviconFile.getName().toLowerCase().contains(
"cache")) || (faviconFile.getName().toLowerCase().contains(
"index"))) {
 
 1197             String temps = RAImageIngestModule.getRATempPath(currentCase, browserName, ingestJobId) + File.separator + faviconFile.getName() + j + 
".db"; 
 
 1199                 ContentUtils.writeToFile(faviconFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
 1200             } 
catch (ReadContentInputStreamException ex) {
 
 1201                 logger.log(Level.WARNING, String.format(
"Error reading Chrome favicons artifacts file '%s' (id=%d).",
 
 1202                         faviconFile.getName(), faviconFile.getId()), ex); 
 
 1203                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getFavicon.errMsg.errAnalyzeFiles1",
 
 1204                         this.getDisplayName(), faviconFile.getName()));
 
 1206             } 
catch (IOException ex) {
 
 1207                 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Chrome favicon artifacts file '%s' (id=%d).",
 
 1208                         temps, faviconFile.getName(), faviconFile.getId()), ex); 
 
 1209                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getfavicon.errMsg.errAnalyzeFiles1",
 
 1210                         this.getDisplayName(), faviconFile.getName()));
 
 1213             File dbFile = 
new File(temps);
 
 1214             if (context.dataSourceIngestIsCancelled()) {
 
 1219             BlackboardArtifact.Type faviconArtifactType;
 
 1222                 faviconArtifactType = createArtifactType(FAVICON_ARTIFACT_NAME, NbBundle.getMessage(
this.getClass(), 
"Chrome.getFavicon.displayName"));
 
 1223             } 
catch (TskCoreException ex) {
 
 1224                 logger.log(Level.SEVERE, String.format(
"Error creating artifact type for Chrome favicon."), ex); 
 
 1225                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getfavicon.errMsg.errCreateArtifact"));
 
 1230             List<HashMap<String, Object>> tempList;
 
 1232             tempList = this.querySQLiteDb(temps, FAVICON_QUERY);
 
 1234             logger.log(Level.INFO, 
"{0}- Now getting favicons from {1} with {2} artifacts identified.", 
new Object[]{getDisplayName(), temps, tempList.size()}); 
 
 1235             for (HashMap<String, Object> result : tempList) {
 
 1236                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
 1237                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
 1238                         RecentActivityExtracterModuleFactory.getModuleName(),
 
 1239                         ((result.get(
"page_url").toString() != null) ? result.get(
"page_url").toString() : 
""))); 
 
 1240                 Long updatedTime = (Long.valueOf(result.get(
"last_updated").toString()) / 1000000) - Long.valueOf(
"11644473600"); 
 
 1241                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED,
 
 1242                         RecentActivityExtracterModuleFactory.getModuleName(), updatedTime));
 
 1243                 Long requestedTime = (Long.valueOf(result.get(
"last_requested").toString()) / 1000000) - Long.valueOf(
"11644473600"); 
 
 1244                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
 
 1245                         RecentActivityExtracterModuleFactory.getModuleName(), requestedTime));
 
 1246                 String domain = NetworkUtils.extractDomain((result.get(
"page_url").toString() != null) ? result.get(
"page_url").toString() : 
""); 
 
 1247                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
 1248                         RecentActivityExtracterModuleFactory.getModuleName(), domain));
 
 1249                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
 
 1250                         RecentActivityExtracterModuleFactory.getModuleName(), userName));
 
 1251                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
 1252                         RecentActivityExtracterModuleFactory.getModuleName(), browserName));
 
 1255                     bbartifacts.add(createArtifactWithAttributes(faviconArtifactType, faviconFile, bbattributes));
 
 1256                 } 
catch (TskCoreException ex) {
 
 1257                     logger.log(Level.SEVERE, String.format(
"Failed to create cookie artifact for file (%d)", faviconFile.getId()), ex);
 
 1265         if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
 
 1266             postArtifacts(bbartifacts);
 
 1277     private void getLogins(String browser, String browserLocation, String userName, 
long ingestJobId) {
 
 1279         FileManager fileManager = currentCase.getServices().getFileManager();
 
 1280         List<AbstractFile> loginDataFiles;
 
 1281         String browserName = browser;
 
 1282         String loginDataFileName = LOGIN_DATA_FILE_NAME;
 
 1283         if (browserName.equals(UC_BROWSER_NAME)) {
 
 1284             loginDataFileName = LOGIN_DATA_FILE_NAME + 
"%";
 
 1288             loginDataFiles = fileManager.findFiles(dataSource, loginDataFileName, browserLocation); 
 
 1289         } 
catch (TskCoreException ex) {
 
 1290             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getLogin.errMsg.errGettingFiles");
 
 1291             logger.log(Level.SEVERE, msg, ex);
 
 1292             this.addErrorMessage(this.getDisplayName() + 
": " + msg);
 
 1296         if (loginDataFiles.isEmpty()) {
 
 1297             logger.log(Level.INFO, 
"Didn't find any Chrome Login Data files."); 
 
 1302         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
 1304         while (j < loginDataFiles.size()) {
 
 1305             if (browser.contains(GOOGLE_PROFILE_NAME)) {
 
 1306                 String parentPath = FilenameUtils.normalizeNoEndSeparator(loginDataFiles.get(j).getParentPath());
 
 1307                 browserName = GOOGLE_PROFILE + FilenameUtils.getBaseName(parentPath);
 
 1309             AbstractFile loginDataFile = loginDataFiles.get(j++);
 
 1310             if ((loginDataFile.getSize() == 0) || (loginDataFile.getName().toLowerCase().contains(
"-slack"))) {
 
 1313             String temps = RAImageIngestModule.getRATempPath(currentCase, browserName, ingestJobId) + File.separator + loginDataFile.getName() + j + 
".db"; 
 
 1315                 ContentUtils.writeToFile(loginDataFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
 1316             } 
catch (ReadContentInputStreamException ex) {
 
 1317                 logger.log(Level.WARNING, String.format(
"Error reading Chrome login artifacts file '%s' (id=%d).",
 
 1318                         loginDataFile.getName(), loginDataFile.getId()), ex); 
 
 1319                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getLogin.errMsg.errAnalyzingFiles",
 
 1320                         this.getDisplayName(), loginDataFile.getName()));
 
 1322             } 
catch (IOException ex) {
 
 1323                 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Chrome login artifacts file '%s' (id=%d).",
 
 1324                         temps, loginDataFile.getName(), loginDataFile.getId()), ex); 
 
 1325                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getLogin.errMsg.errAnalyzingFiles",
 
 1326                         this.getDisplayName(), loginDataFile.getName()));
 
 1329             File dbFile = 
new File(temps);
 
 1330             if (context.dataSourceIngestIsCancelled()) {
 
 1334             List<HashMap<String, Object>> tempList = this.querySQLiteDb(temps, LOGIN_QUERY);
 
 1335             logger.log(Level.INFO, 
"{0}- Now getting login information from {1} with {2} artifacts identified.", 
new Object[]{getDisplayName(), temps, tempList.size()}); 
 
 1336             for (HashMap<String, Object> result : tempList) {
 
 1337                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
 1339                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
 1340                         RecentActivityExtracterModuleFactory.getModuleName(),
 
 1341                         ((result.get(
"origin_url").toString() != null) ? result.get(
"origin_url").toString() : 
""))); 
 
 1343                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
 
 1344                         RecentActivityExtracterModuleFactory.getModuleName(),
 
 1345                         (Long.valueOf(result.get(
"date_created").toString()) / 1000000) - Long.valueOf(
"11644473600"))); 
 
 1347                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED,
 
 1348                         RecentActivityExtracterModuleFactory.getModuleName(),
 
 1349                         (NetworkUtils.extractDomain((result.get(
"origin_url").toString() != null) ? result.get(
"origin_url").toString() : 
"")))); 
 
 1351                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
 
 1352                         RecentActivityExtracterModuleFactory.getModuleName(),
 
 1353                         ((result.get(
"username_value").toString() != null) ? result.get(
"username_value").toString().replaceAll(
"'", 
"''") : 
""))); 
 
 1355                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REALM,
 
 1356                         RecentActivityExtracterModuleFactory.getModuleName(),
 
 1357                         ((result.get(
"signon_realm") != null && result.get(
"signon_realm").toString() != null) ? result.get(
"signon_realm").toString() : 
""))); 
 
 1359                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
 1360                         RecentActivityExtracterModuleFactory.getModuleName(),
 
 1361                         result.containsKey(
"signon_realm") ? NetworkUtils.extractDomain(result.get(
"signon_realm").toString()) : 
"")); 
 
 1363                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
 1364                         RecentActivityExtracterModuleFactory.getModuleName(), browserName));
 
 1366                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
 
 1367                         RecentActivityExtracterModuleFactory.getModuleName(), userName));
 
 1370                     bbartifacts.add(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_SERVICE_ACCOUNT, loginDataFile, bbattributes));
 
 1371                 } 
catch (TskCoreException ex) {
 
 1372                     logger.log(Level.SEVERE, String.format(
"Failed to create service account artifact for file (%d)", loginDataFile.getId()), ex);
 
 1379         if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
 
 1380             postArtifacts(bbartifacts);
 
 1392     private void getAutofill(String browser, String browserLocation, String userName, 
long ingestJobId) {
 
 1394         FileManager fileManager = currentCase.getServices().getFileManager();
 
 1395         List<AbstractFile> webDataFiles;
 
 1396         String browserName = browser;
 
 1397         String webDataFileName = WEB_DATA_FILE_NAME;
 
 1398         if (browserName.equals(UC_BROWSER_NAME)) {
 
 1399             webDataFileName = WEB_DATA_FILE_NAME + 
"%";
 
 1403             webDataFiles = fileManager.findFiles(dataSource, webDataFileName, browserLocation); 
 
 1404         } 
catch (TskCoreException ex) {
 
 1405             String msg = NbBundle.getMessage(this.getClass(), 
"Chrome.getAutofills.errMsg.errGettingFiles");
 
 1406             logger.log(Level.SEVERE, msg, ex);
 
 1407             this.addErrorMessage(this.getDisplayName() + 
": " + msg);
 
 1411         if (webDataFiles.isEmpty()) {
 
 1412             logger.log(Level.INFO, 
"Didn't find any Chrome Web Data files."); 
 
 1417         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
 1419         while (j < webDataFiles.size()) {
 
 1420             if (browser.contains(GOOGLE_PROFILE_NAME)) {
 
 1421                 String parentPath = FilenameUtils.normalizeNoEndSeparator(webDataFiles.get(j).getParentPath());
 
 1422                 browserName = GOOGLE_PROFILE + FilenameUtils.getBaseName(parentPath);
 
 1424             databaseEncrypted = 
false;
 
 1425             AbstractFile webDataFile = webDataFiles.get(j++);
 
 1426             if ((webDataFile.getSize() == 0) || (webDataFile.getName().toLowerCase().contains(
"-slack"))) {
 
 1429             String tempFilePath = RAImageIngestModule.getRATempPath(currentCase, browserName, ingestJobId) + File.separator + webDataFile.getName() + j + 
".db"; 
 
 1431                 ContentUtils.writeToFile(webDataFile, 
new File(tempFilePath), context::dataSourceIngestIsCancelled);
 
 1432             } 
catch (ReadContentInputStreamException ex) {
 
 1433                 logger.log(Level.WARNING, String.format(
"Error reading Chrome Autofill artifacts file '%s' (id=%d).",
 
 1434                         webDataFile.getName(), webDataFile.getId()), ex); 
 
 1435                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getAutofill.errMsg.errAnalyzingFiles",
 
 1436                         this.getDisplayName(), webDataFile.getName()));
 
 1438             } 
catch (IOException ex) {
 
 1439                 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Chrome Web data file '%s' (id=%d).",
 
 1440                         tempFilePath, webDataFile.getName(), webDataFile.getId()), ex); 
 
 1441                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Chrome.getLogin.errMsg.errAnalyzingFiles",
 
 1442                         this.getDisplayName(), webDataFile.getName()));
 
 1445             File dbFile = 
new File(tempFilePath);
 
 1446             if (context.dataSourceIngestIsCancelled()) {
 
 1452             boolean isSchemaV8X = Util.checkColumn(
"date_created", 
"autofill", tempFilePath);
 
 1455             bbartifacts.addAll(getFormAutofillArtifacts(webDataFile, tempFilePath, isSchemaV8X, userName, browserName));
 
 1458                 getFormAddressArtifacts(webDataFile, tempFilePath, isSchemaV8X);
 
 1459                 if (databaseEncrypted) {
 
 1460                     String comment = String.format(
"%s Autofill Database Encryption Detected", browserName);
 
 1461                     Collection<BlackboardAttribute> bbattributes = Arrays.asList(
 
 1462                             new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT,
 
 1463                                     RecentActivityExtracterModuleFactory.getModuleName(), comment));
 
 1466                             webDataFile.newAnalysisResult(
 
 1467                                     BlackboardArtifact.Type.TSK_ENCRYPTION_DETECTED, Score.SCORE_NOTABLE,
 
 1468                                     null, null, comment, bbattributes).getAnalysisResult());
 
 1470             } 
catch (NoCurrentCaseException | TskCoreException | Blackboard.BlackboardException ex) {
 
 1471                 logger.log(Level.SEVERE, String.format(
"Error adding artifacts to the case database " 
 1472                         + 
"for chrome file %s [objId=%d]", webDataFile.getName(), webDataFile.getId()), ex);
 
 1478         if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
 
 1479             postArtifacts(bbartifacts);
 
 1493     private Collection<BlackboardArtifact> getFormAutofillArtifacts(AbstractFile webDataFile, String dbFilePath, 
boolean isSchemaV8X, String userName, String browser) {
 
 1495         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
 1498         String autoFillquery = (isSchemaV8X) ? AUTOFILL_QUERY_V8X
 
 1501         List<HashMap<String, Object>> autofills = this.querySQLiteDb(dbFilePath, autoFillquery);
 
 1502         logger.log(Level.INFO, 
"{0}- Now getting Autofill information from {1} with {2} artifacts identified.", 
new Object[]{getDisplayName(), dbFilePath, autofills.size()}); 
 
 1503         for (HashMap<String, Object> result : autofills) {
 
 1504             Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
 1507             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
 
 1508                     NbBundle.getMessage(
this.getClass(), 
"Chrome.parentModuleName"),
 
 1509                     ((result.get(
"name").toString() != null) ? result.get(
"name").toString() : 
""))); 
 
 1511             fieldEncrypted = 
false;
 
 1512             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
 
 1513                     RecentActivityExtracterModuleFactory.getModuleName(),
 
 1514                     processFields(result.get(
"value")))); 
 
 1516             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
 
 1517                     RecentActivityExtracterModuleFactory.getModuleName(),
 
 1518                     (Integer.valueOf(result.get(
"count").toString())))); 
 
 1520             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
 
 1521                     RecentActivityExtracterModuleFactory.getModuleName(),
 
 1522                     Long.valueOf(result.get(
"date_created").toString()))); 
 
 1526                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
 
 1527                         RecentActivityExtracterModuleFactory.getModuleName(),
 
 1528                         Long.valueOf(result.get(
"date_last_used").toString()))); 
 
 1531             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
 
 1532                     RecentActivityExtracterModuleFactory.getModuleName(), userName));
 
 1533             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
 1534                     RecentActivityExtracterModuleFactory.getModuleName(), browser));
 
 1535             if (fieldEncrypted) {
 
 1536                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT,
 
 1537                         RecentActivityExtracterModuleFactory.getModuleName(), ENCRYPTED_FIELD_MESSAGE));
 
 1542                 bbartifacts.add(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_WEB_FORM_AUTOFILL, webDataFile, bbattributes));
 
 1543             } 
catch (TskCoreException ex) {
 
 1544                 logger.log(Level.SEVERE, String.format(
"Failed to create web form autopfill artifact for file (%d)", webDataFile.getId()), ex);
 
 1563     private void getFormAddressArtifacts(AbstractFile webDataFile, String dbFilePath, 
boolean isSchemaV8X) 
throws NoCurrentCaseException,
 
 1564             TskCoreException, Blackboard.BlackboardException {
 
 1566         String webformAddressQuery = (isSchemaV8X) ? WEBFORM_ADDRESS_QUERY_V8X
 
 1567                 : WEBFORM_ADDRESS_QUERY;
 
 1570         WebBrowserArtifactsHelper helper = 
new WebBrowserArtifactsHelper(
 
 1571                 Case.getCurrentCaseThrows().getSleuthkitCase(),
 
 1572                 NbBundle.getMessage(this.getClass(), 
"Chrome.parentModuleName"),
 
 1573                 webDataFile, context.getJobId()
 
 1577         List<HashMap<String, Object>> addresses = this.querySQLiteDb(dbFilePath, webformAddressQuery);
 
 1578         logger.log(Level.INFO, 
"{0}- Now getting Web form addresses from {1} with {2} artifacts identified.", 
new Object[]{getDisplayName(), dbFilePath, addresses.size()}); 
 
 1579         for (HashMap<String, Object> result : addresses) {
 
 1581             fieldEncrypted = 
false;
 
 1583             String first_name = processFields(result.get(
"first_name"));
 
 1584             String middle_name = processFields(result.get(
"middle_name"));
 
 1585             String last_name = processFields(result.get(
"last_name"));
 
 1588             String email_Addr = processFields(result.get(
"email"));
 
 1589             String phone_number = processFields(result.get(
"number"));
 
 1592             String city = processFields(result.get(
"city"));
 
 1593             String state = processFields(result.get(
"state"));
 
 1594             String zipcode = processFields(result.get(
"zipcode"));
 
 1595             String country_code = processFields(result.get(
"country_code"));
 
 1598             String full_name = 
"";
 
 1599             String street_address = 
"";
 
 1600             long date_modified = 0;
 
 1606                 full_name = processFields(result.get(
"full_name"));
 
 1607                 street_address = processFields(result.get(
"street_address"));
 
 1608                 date_modified = result.get(
"date_modified").toString() != null ? Long.valueOf(result.get(
"date_modified").toString()) : 0;
 
 1609                 use_count = result.get(
"use_count").toString() != null ? Integer.valueOf(result.get(
"use_count").toString()) : 0;
 
 1610                 use_date = result.get(
"use_date").toString() != null ? Long.valueOf(result.get(
"use_date").toString()) : 0;
 
 1612                 String address_line_1 = processFields(result.get(
"address_line_1"));
 
 1613                 String address_line_2 = processFields(result.get(
"address_line_2"));
 
 1614                 street_address = String.join(
" ", address_line_1, address_line_2);
 
 1618             if (full_name == null || full_name.isEmpty()) {
 
 1619                 full_name = String.join(
" ", first_name, middle_name, last_name);
 
 1622             String locationAddress = String.join(
", ", street_address, city, state, zipcode, country_code);
 
 1624             List<BlackboardAttribute> otherAttributes = 
new ArrayList<>();
 
 1625             if (date_modified > 0) {
 
 1626                 otherAttributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED,
 
 1627                         RecentActivityExtracterModuleFactory.getModuleName(),
 
 1629                 if (fieldEncrypted) {
 
 1630                     otherAttributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT,
 
 1631                             RecentActivityExtracterModuleFactory.getModuleName(), ENCRYPTED_FIELD_MESSAGE)); 
 
 1636             helper.addWebFormAddress(
 
 1637                     full_name, email_Addr, phone_number,
 
 1638                     locationAddress, 0, use_date,
 
 1639                     use_count, otherAttributes);
 
 1652     private String processFields(Object dataValue) {
 
 1654         if (dataValue instanceof byte[]) {
 
 1655             fieldEncrypted = 
true;
 
 1656             databaseEncrypted = 
true;
 
 1659         return dataValue.toString() != null ? dataValue.toString() : 
"";
 
 1663     private boolean isChromePreVersion30(String temps) {
 
 1664         String query = 
"PRAGMA table_info(downloads)"; 
 
 1665         List<HashMap<String, Object>> columns = this.querySQLiteDb(temps, query);
 
 1666         for (HashMap<String, Object> col : columns) {
 
 1667             if (col.get(
"name").equals(
"url")) { 
 
 1676         "ExtractFavicon_Display_Name=Favicon" 
 1684     private BlackboardArtifact.Type createArtifactType(String artifactName, String displayName) 
throws TskCoreException {
 
 1685         BlackboardArtifact.Type faviconArtifactType;
 
 1687             faviconArtifactType = tskCase.getBlackboard().getOrAddArtifactType(artifactName, displayName); 
 
 1688         } 
catch (Blackboard.BlackboardException ex) {
 
 1689             throw new TskCoreException(String.format(
"An exception was thrown while defining artifact type %s", artifactName), ex);
 
 1691         return faviconArtifactType;
 
 1697     private void loadMaliciousChromeExetnsions() {
 
 1698         maliciousChromeExtensions = 
new HashMap<>();
 
 1701             String malChromeExtenList = PlatformUtil.getUserConfigDirectory() + File.separator + MALICIOUS_CHROME_EXTENSION_LIST;
 
 1702             BufferedReader csvReader = 
new BufferedReader(
new FileReader(malChromeExtenList));
 
 1704             while ((row = csvReader.readLine()) != null) {
 
 1705                 if (!row.startsWith(
"#", 0)) {
 
 1706                     String[] data = row.split(
",");
 
 1707                     maliciousChromeExtensions.put(data[0], data[1]);
 
 1710         } 
catch (IOException ex) {
 
 1711             logger.log(Level.SEVERE, String.format(
"Failed to load Malicious Chrome Extension List file (%s)", MALICIOUS_CHROME_EXTENSION_LIST), ex);
 
 1720     private void configExtractor() throws IOException {
 
 1721         PlatformUtil.extractResourceToUserConfigDir(Chromium.class,
 
 1722                 MALICIOUS_CHROME_EXTENSION_LIST, 
true);