Autopsy  4.17.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
Chromium.java
Go to the documentation of this file.
1 /*
2  *
3  * Autopsy Forensic Browser
4  *
5  * Copyright 2012-2020 Basis Technology Corp.
6  *
7  * Copyright 2012 42six Solutions.
8  *
9  * Project Contact/Architect: carrier <at> sleuthkit <dot> org
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  * http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23 package org.sleuthkit.autopsy.recentactivity;
24 
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;
35 import java.util.*;
36 import java.io.File;
37 import java.io.FileNotFoundException;
38 import java.io.FileReader;
39 import java.io.IOException;
40 import org.apache.commons.io.FilenameUtils;
41 import org.openide.util.NbBundle.Messages;
49 import org.sleuthkit.datamodel.AbstractFile;
50 import org.sleuthkit.datamodel.Blackboard;
51 import org.sleuthkit.datamodel.BlackboardArtifact;
52 import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
53 import org.sleuthkit.datamodel.BlackboardAttribute;
54 import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
55 import org.sleuthkit.datamodel.Content;
56 import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
57 import org.sleuthkit.datamodel.TskCoreException;
58 import org.sleuthkit.datamodel.TskData;
59 import org.sleuthkit.datamodel.blackboardutils.WebBrowserArtifactsHelper;
60 
64 class Chromium extends Extract {
65 
66  private static final String HISTORY_QUERY = "SELECT urls.url, urls.title, urls.visit_count, urls.typed_count, " //NON-NLS
67  + "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"; //NON-NLS
68  private static final String COOKIE_QUERY = "SELECT name, value, host_key, expires_utc,last_access_utc, creation_utc FROM cookies"; //NON-NLS
69  private static final String DOWNLOAD_QUERY = "SELECT full_path, url, start_time, received_bytes FROM downloads"; //NON-NLS
70  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"; //NON-NLS
71  private static final String LOGIN_QUERY = "SELECT origin_url, username_value, date_created, signon_realm from logins"; //NON-NLS
72  private static final String AUTOFILL_QUERY = "SELECT name, value, count, date_created "
73  + " FROM autofill, autofill_dates "
74  + " WHERE autofill.pair_id = autofill_dates.pair_id"; //NON-NLS
75  private static final String AUTOFILL_QUERY_V8X = "SELECT name, value, count, date_created, date_last_used from autofill"; //NON-NLS
76  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 "
77  + " FROM autofill_profiles, autofill_profile_names, autofill_profile_emails, autofill_profile_phones"
78  + " WHERE autofill_profiles.guid = autofill_profile_names.guid AND autofill_profiles.guid = autofill_profile_emails.guid AND autofill_profiles.guid = autofill_profile_phones.guid";
79 
80  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"
81  + " FROM autofill_profiles, autofill_profile_names, autofill_profile_emails, autofill_profile_phones"
82  + " WHERE autofill_profiles.guid = autofill_profile_names.guid AND autofill_profiles.guid = autofill_profile_emails.guid AND autofill_profiles.guid = autofill_profile_phones.guid";
83  private static final String HISTORY_FILE_NAME = "History";
84  private static final String BOOKMARK_FILE_NAME = "Bookmarks";
85  private static final String COOKIE_FILE_NAME = "Cookies";
86  private static final String LOGIN_DATA_FILE_NAME = "Login Data";
87  private static final String WEB_DATA_FILE_NAME = "Web Data";
88  private static final String UC_BROWSER_NAME = "UC Browser";
89 
90  private final Logger logger = Logger.getLogger(this.getClass().getName());
91  private Content dataSource;
92  private IngestJobContext context;
93 
94  private static final Map<String, String> BROWSERS_MAP = ImmutableMap.<String, String>builder()
95  .put("Microsoft Edge", "Microsoft/Edge/User Data/Default")
96  .put("Yandex", "YandexBrowser/User Data/Default")
97  .put("Opera", "Opera Software/Opera Stable")
98  .put("SalamWeb", "SalamWeb/User Data/Default")
99  .put("UC Browser", "UCBrowser/User Data%/Default")
100  .put("Brave", "BraveSoftware/Brave-Browser/User Data/Default")
101  .put("Google Chrome", "Chrome/User Data/Default")
102  .build();
103 
104  @Messages({"# {0} - browserName",
105  "Progress_Message_Chrome_History=Chrome History Browser {0}",
106  "# {0} - browserName",
107  "Progress_Message_Chrome_Bookmarks=Chrome Bookmarks Browser {0}",
108  "# {0} - browserName",
109  "Progress_Message_Chrome_Cookies=Chrome Cookies Browser {0}",
110  "# {0} - browserName",
111  "Progress_Message_Chrome_Downloads=Chrome Downloads Browser {0}",
112  "Progress_Message_Chrome_FormHistory=Chrome Form History",
113  "# {0} - browserName",
114  "Progress_Message_Chrome_AutoFill=Chrome Auto Fill Browser {0}",
115  "# {0} - browserName",
116  "Progress_Message_Chrome_Logins=Chrome Logins Browser {0}",
117  "Progress_Message_Chrome_Cache=Chrome Cache",})
118 
119  Chromium() {
120  moduleName = NbBundle.getMessage(Chromium.class, "Chrome.moduleName");
121  }
122 
123  @Override
124  public void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
125  this.dataSource = dataSource;
126  this.context = context;
127  dataFound = false;
128 
129  for (Map.Entry<String, String> browser : BROWSERS_MAP.entrySet()) {
130  String browserName = browser.getKey();
131  String browserLocation = browser.getValue();
132  progressBar.progress(NbBundle.getMessage(this.getClass(), "Progress_Message_Chrome_History", browserName));
133  this.getHistory(browser.getKey(), browser.getValue());
134  if (context.dataSourceIngestIsCancelled()) {
135  return;
136  }
137 
138  progressBar.progress(NbBundle.getMessage(this.getClass(), "Progress_Message_Chrome_Bookmarks", browserName));
139  this.getBookmark(browser.getKey(), browser.getValue());
140  if (context.dataSourceIngestIsCancelled()) {
141  return;
142  }
143 
144  progressBar.progress(NbBundle.getMessage(this.getClass(), "Progress_Message_Chrome_Cookies", browserName));
145  this.getCookie(browser.getKey(), browser.getValue());
146  if (context.dataSourceIngestIsCancelled()) {
147  return;
148  }
149 
150  progressBar.progress(NbBundle.getMessage(this.getClass(), "Progress_Message_Chrome_Logins", browserName));
151  this.getLogins(browser.getKey(), browser.getValue());
152  if (context.dataSourceIngestIsCancelled()) {
153  return;
154  }
155 
156  progressBar.progress(NbBundle.getMessage(this.getClass(), "Progress_Message_Chrome_AutoFill", browserName));
157  this.getAutofill(browser.getKey(), browser.getValue());
158  if (context.dataSourceIngestIsCancelled()) {
159  return;
160  }
161 
162  progressBar.progress(NbBundle.getMessage(this.getClass(), "Progress_Message_Chrome_Downloads", browserName));
163  this.getDownload(browser.getKey(), browser.getValue());
164  if (context.dataSourceIngestIsCancelled()) {
165  return;
166  }
167  }
168 
169  progressBar.progress(Bundle.Progress_Message_Chrome_Cache());
170  ChromeCacheExtractor chromeCacheExtractor = new ChromeCacheExtractor(dataSource, context, progressBar);
171  chromeCacheExtractor.processCaches();
172 
173  }
174 
178  private void getHistory(String browser, String browserLocation) {
179  FileManager fileManager = currentCase.getServices().getFileManager();
180  List<AbstractFile> historyFiles;
181  String historyFileName = HISTORY_FILE_NAME;
182  if (browser.equals(UC_BROWSER_NAME)) {
183  historyFileName = HISTORY_FILE_NAME + "%";
184  }
185  try {
186  historyFiles = fileManager.findFiles(dataSource, historyFileName, browserLocation); //NON-NLS
187  } catch (TskCoreException ex) {
188  String msg = NbBundle.getMessage(this.getClass(), "Chrome.getHistory.errMsg.errGettingFiles");
189  logger.log(Level.SEVERE, msg, ex);
190  this.addErrorMessage(this.getName() + ": " + msg);
191  return;
192  }
193 
194  // get only the allocated ones, for now
195  List<AbstractFile> allocatedHistoryFiles = new ArrayList<>();
196  for (AbstractFile historyFile : historyFiles) {
197  if (historyFile.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC)) {
198  allocatedHistoryFiles.add(historyFile);
199  }
200  }
201 
202  // log a message if we don't have any allocated history files
203  if (allocatedHistoryFiles.isEmpty()) {
204  String msg = NbBundle.getMessage(this.getClass(), "Chrome.getHistory.errMsg.couldntFindAnyFiles");
205  logger.log(Level.INFO, msg);
206  return;
207  }
208 
209  dataFound = true;
210  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
211  int j = 0;
212  while (j < allocatedHistoryFiles.size()) {
213  String temps = RAImageIngestModule.getRATempPath(currentCase, browser) + File.separator + allocatedHistoryFiles.get(j).getName() + j + ".db"; //NON-NLS
214  final AbstractFile historyFile = allocatedHistoryFiles.get(j++);
215  if ((historyFile.getSize() == 0) || (historyFile.getName().toLowerCase().contains("-slack"))
216  || (historyFile.getName().toLowerCase().contains("cache")) || (historyFile.getName().toLowerCase().contains("media"))
217  || (historyFile.getName().toLowerCase().contains("index"))) {
218  continue;
219  }
220  try {
221  ContentUtils.writeToFile(historyFile, new File(temps), context::dataSourceIngestIsCancelled);
222  } catch (ReadContentInputStreamException ex) {
223  logger.log(Level.WARNING, String.format("Error reading Chrome web history artifacts file '%s' (id=%d).",
224  historyFile.getName(), historyFile.getId()), ex); //NON-NLS
225  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Chrome.getHistory.errMsg.errAnalyzingFile",
226  this.getName(), historyFile.getName()));
227  continue;
228  } catch (IOException ex) {
229  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Chrome web history artifacts file '%s' (id=%d).",
230  temps, historyFile.getName(), historyFile.getId()), ex); //NON-NLS
231  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Chrome.getHistory.errMsg.errAnalyzingFile",
232  this.getName(), historyFile.getName()));
233  continue;
234  }
235  File dbFile = new File(temps);
236  if (context.dataSourceIngestIsCancelled()) {
237  dbFile.delete();
238  break;
239  }
240  List<HashMap<String, Object>> tempList;
241  tempList = this.dbConnect(temps, HISTORY_QUERY);
242  logger.log(Level.INFO, "{0}- Now getting history from {1} with {2}artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
243  for (HashMap<String, Object> result : tempList) {
244  Collection<BlackboardAttribute> bbattributes = new ArrayList<BlackboardAttribute>();
245  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
246  RecentActivityExtracterModuleFactory.getModuleName(),
247  ((result.get("url").toString() != null) ? result.get("url").toString() : ""))); //NON-NLS
248  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
249  RecentActivityExtracterModuleFactory.getModuleName(),
250  (Long.valueOf(result.get("last_visit_time").toString()) / 1000000) - Long.valueOf("11644473600"))); //NON-NLS
251  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER,
252  RecentActivityExtracterModuleFactory.getModuleName(),
253  ((result.get("from_visit").toString() != null) ? result.get("from_visit").toString() : ""))); //NON-NLS
254  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
255  RecentActivityExtracterModuleFactory.getModuleName(),
256  ((result.get("title").toString() != null) ? result.get("title").toString() : ""))); //NON-NLS
257  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
258  RecentActivityExtracterModuleFactory.getModuleName(), browser));
259  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
260  RecentActivityExtracterModuleFactory.getModuleName(),
261  (NetworkUtils.extractDomain((result.get("url").toString() != null) ? result.get("url").toString() : "")))); //NON-NLS
262 
263  BlackboardArtifact bbart = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_HISTORY, historyFile, bbattributes);
264  if (bbart != null) {
265  bbartifacts.add(bbart);
266  }
267  }
268  dbFile.delete();
269  }
270 
271  if (!bbartifacts.isEmpty()) {
272  postArtifacts(bbartifacts);
273  }
274  }
275 
279  private void getBookmark(String browser, String browserLocation) {
280  FileManager fileManager = currentCase.getServices().getFileManager();
281  List<AbstractFile> bookmarkFiles;
282  String bookmarkFileName = BOOKMARK_FILE_NAME;
283  if (browser.equals(UC_BROWSER_NAME)) {
284  bookmarkFileName = BOOKMARK_FILE_NAME + "%";
285  }
286  try {
287  bookmarkFiles = fileManager.findFiles(dataSource, bookmarkFileName, browserLocation); //NON-NLS
288  } catch (TskCoreException ex) {
289  String msg = NbBundle.getMessage(this.getClass(), "Chrome.getBookmark.errMsg.errGettingFiles");
290  logger.log(Level.SEVERE, msg, ex);
291  this.addErrorMessage(this.getName() + ": " + msg);
292  return;
293  }
294 
295  if (bookmarkFiles.isEmpty()) {
296  logger.log(Level.INFO, "Didn't find any Chrome bookmark files."); //NON-NLS
297  return;
298  }
299 
300  dataFound = true;
301  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
302  int j = 0;
303 
304  while (j < bookmarkFiles.size()) {
305  AbstractFile bookmarkFile = bookmarkFiles.get(j++);
306  if ((bookmarkFile.getSize() == 0) || (bookmarkFile.getName().toLowerCase().contains("-slack"))
307  || (bookmarkFile.getName().toLowerCase().contains("extras")) || (bookmarkFile.getName().toLowerCase().contains("log"))
308  || (bookmarkFile.getName().toLowerCase().contains("backup")) || (bookmarkFile.getName().toLowerCase().contains("visualized"))
309  || (bookmarkFile.getName().toLowerCase().contains("bak")) || (bookmarkFile.getParentPath().toLowerCase().contains("backup"))) {
310  continue;
311  }
312  String temps = RAImageIngestModule.getRATempPath(currentCase, browser) + File.separator + bookmarkFile.getName() + j + ".db"; //NON-NLS
313  try {
314  ContentUtils.writeToFile(bookmarkFile, new File(temps), context::dataSourceIngestIsCancelled);
315  } catch (ReadContentInputStreamException ex) {
316  logger.log(Level.WARNING, String.format("Error reading Chrome bookmark artifacts file '%s' (id=%d).",
317  bookmarkFile.getName(), bookmarkFile.getId()), ex); //NON-NLS
318  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Chrome.getBookmark.errMsg.errAnalyzingFile",
319  this.getName(), bookmarkFile.getName()));
320  continue;
321  } catch (IOException ex) {
322  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Chrome bookmark artifacts file '%s' (id=%d).",
323  temps, bookmarkFile.getName(), bookmarkFile.getId()), ex); //NON-NLS
324  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Chrome.getBookmark.errMsg.errAnalyzingFile",
325  this.getName(), bookmarkFile.getName()));
326  continue;
327  }
328 
329  logger.log(Level.INFO, "{0}- Now getting Bookmarks from {1}", new Object[]{moduleName, temps}); //NON-NLS
330  File dbFile = new File(temps);
331  if (context.dataSourceIngestIsCancelled()) {
332  dbFile.delete();
333  break;
334  }
335 
336  FileReader tempReader;
337  try {
338  tempReader = new FileReader(temps);
339  } catch (FileNotFoundException ex) {
340  logger.log(Level.WARNING, "Error while trying to read into the Bookmarks for Chrome.", ex); //NON-NLS
341  continue;
342  }
343 
344  final JsonParser parser = new JsonParser();
345  JsonElement jsonElement;
346  JsonObject jElement, jRoot, jBookmark;
347  JsonArray jBookmarkArray;
348 
349  try {
350  jsonElement = parser.parse(tempReader);
351  jElement = jsonElement.getAsJsonObject();
352  jRoot = jElement.get("roots").getAsJsonObject(); //NON-NLS
353  jBookmark = jRoot.get("bookmark_bar").getAsJsonObject(); //NON-NLS
354  jBookmarkArray = jBookmark.getAsJsonArray("children"); //NON-NLS
355  } catch (JsonIOException | JsonSyntaxException | IllegalStateException ex) {
356  logger.log(Level.WARNING, "Error parsing Json from Chrome Bookmark.", ex); //NON-NLS
357  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Chrome.getBookmark.errMsg.errAnalyzingFile3",
358  this.getName(), bookmarkFile.getName()));
359  continue;
360  }
361 
362  for (JsonElement result : jBookmarkArray) {
363  JsonObject address = result.getAsJsonObject();
364  if (address == null) {
365  continue;
366  }
367  JsonElement urlEl = address.get("url"); //NON-NLS
368  String url;
369  if (urlEl != null) {
370  url = urlEl.getAsString();
371  } else {
372  url = "";
373  }
374  String name;
375  JsonElement nameEl = address.get("name"); //NON-NLS
376  if (nameEl != null) {
377  name = nameEl.getAsString();
378  } else {
379  name = "";
380  }
381  Long date;
382  JsonElement dateEl = address.get("date_added"); //NON-NLS
383  if (dateEl != null) {
384  date = dateEl.getAsLong();
385  } else {
386  date = Long.valueOf(0);
387  }
388  String domain = NetworkUtils.extractDomain(url);
389  try {
390  BlackboardArtifact bbart = bookmarkFile.newArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK);
391  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
392  //TODO Revisit usage of deprecated constructor as per TSK-583
393  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
394  RecentActivityExtracterModuleFactory.getModuleName(), url));
395  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
396  RecentActivityExtracterModuleFactory.getModuleName(), name));
397  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
398  RecentActivityExtracterModuleFactory.getModuleName(), (date / 1000000) - Long.valueOf("11644473600")));
399  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
400  RecentActivityExtracterModuleFactory.getModuleName(), browser));
401  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
402  RecentActivityExtracterModuleFactory.getModuleName(), domain));
403  bbart.addAttributes(bbattributes);
404 
405  bbartifacts.add(bbart);
406  } catch (TskCoreException ex) {
407  logger.log(Level.SEVERE, "Error while trying to insert Chrome bookmark artifact{0}", ex); //NON-NLS
408  this.addErrorMessage(
409  NbBundle.getMessage(this.getClass(), "Chrome.getBookmark.errMsg.errAnalyzingFile4",
410  this.getName(), bookmarkFile.getName()));
411  }
412  }
413  postArtifacts(bbartifacts);
414  bbartifacts.clear();
415  dbFile.delete();
416  }
417  }
418 
422  private void getCookie(String browser, String browserLocation) {
423 
424  FileManager fileManager = currentCase.getServices().getFileManager();
425  List<AbstractFile> cookiesFiles;
426  String cookieFileName = COOKIE_FILE_NAME;
427  if (browser.equals(UC_BROWSER_NAME)) {
428  // Wildcard on front and back of Cookies are there for Cookie files that start with something else
429  // ie: UC browser has "Extension Cookies.9" as well as Cookies.9
430  cookieFileName = "%" + COOKIE_FILE_NAME + "%";
431  }
432  try {
433  cookiesFiles = fileManager.findFiles(dataSource, cookieFileName, browserLocation); //NON-NLS
434  } catch (TskCoreException ex) {
435  String msg = NbBundle.getMessage(this.getClass(), "Chrome.getCookie.errMsg.errGettingFiles");
436  logger.log(Level.SEVERE, msg, ex);
437  this.addErrorMessage(this.getName() + ": " + msg);
438  return;
439  }
440 
441  if (cookiesFiles.isEmpty()) {
442  logger.log(Level.INFO, "Didn't find any Chrome cookies files."); //NON-NLS
443  return;
444  }
445 
446  dataFound = true;
447  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
448  int j = 0;
449  while (j < cookiesFiles.size()) {
450  AbstractFile cookiesFile = cookiesFiles.get(j++);
451  if ((cookiesFile.getSize() == 0) || (cookiesFile.getName().toLowerCase().contains("-slack"))) {
452  continue;
453  }
454  String temps = RAImageIngestModule.getRATempPath(currentCase, browser) + File.separator + cookiesFile.getName() + j + ".db"; //NON-NLS
455  try {
456  ContentUtils.writeToFile(cookiesFile, new File(temps), context::dataSourceIngestIsCancelled);
457  } catch (ReadContentInputStreamException ex) {
458  logger.log(Level.WARNING, String.format("Error reading Chrome cookie artifacts file '%s' (id=%d).",
459  cookiesFile.getName(), cookiesFile.getId()), ex); //NON-NLS
460  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Chrome.getCookie.errMsg.errAnalyzeFile",
461  this.getName(), cookiesFile.getName()));
462  continue;
463  } catch (IOException ex) {
464  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Chrome cookie artifacts file '%s' (id=%d).",
465  temps, cookiesFile.getName(), cookiesFile.getId()), ex); //NON-NLS
466  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Chrome.getCookie.errMsg.errAnalyzeFile",
467  this.getName(), cookiesFile.getName()));
468  continue;
469  }
470  File dbFile = new File(temps);
471  if (context.dataSourceIngestIsCancelled()) {
472  dbFile.delete();
473  break;
474  }
475 
476  List<HashMap<String, Object>> tempList = this.dbConnect(temps, COOKIE_QUERY);
477  logger.log(Level.INFO, "{0}- Now getting cookies from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
478  for (HashMap<String, Object> result : tempList) {
479  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
480  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
481  RecentActivityExtracterModuleFactory.getModuleName(),
482  ((result.get("host_key").toString() != null) ? result.get("host_key").toString() : ""))); //NON-NLS
483  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME,
484  RecentActivityExtracterModuleFactory.getModuleName(),
485  (Long.valueOf(result.get("last_access_utc").toString()) / 1000000) - Long.valueOf("11644473600"))); //NON-NLS
486 
487  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
488  RecentActivityExtracterModuleFactory.getModuleName(),
489  ((result.get("name").toString() != null) ? result.get("name").toString() : ""))); //NON-NLS
490  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
491  RecentActivityExtracterModuleFactory.getModuleName(),
492  ((result.get("value").toString() != null) ? result.get("value").toString() : ""))); //NON-NLS
493  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
494  RecentActivityExtracterModuleFactory.getModuleName(), browser));
495  String domain = result.get("host_key").toString(); //NON-NLS
496  domain = domain.replaceFirst("^\\.+(?!$)", "");
497  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
498  RecentActivityExtracterModuleFactory.getModuleName(), domain));
499 
500  BlackboardArtifact bbart = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_COOKIE, cookiesFile, bbattributes);
501  if (bbart != null) {
502  bbartifacts.add(bbart);
503  }
504  }
505 
506  dbFile.delete();
507  }
508 
509  if (!bbartifacts.isEmpty()) {
510  postArtifacts(bbartifacts);
511  }
512  }
513 
517  private void getDownload(String browser, String browserLocation) {
518  FileManager fileManager = currentCase.getServices().getFileManager();
519  List<AbstractFile> downloadFiles;
520  String historyFileName = HISTORY_FILE_NAME;
521  if (browser.equals(UC_BROWSER_NAME)) {
522  historyFileName = HISTORY_FILE_NAME + "%";
523  }
524  try {
525  downloadFiles = fileManager.findFiles(dataSource, historyFileName, browserLocation); //NON-NLS
526  } catch (TskCoreException ex) {
527  String msg = NbBundle.getMessage(this.getClass(), "Chrome.getDownload.errMsg.errGettingFiles");
528  logger.log(Level.SEVERE, msg, ex);
529  this.addErrorMessage(this.getName() + ": " + msg);
530  return;
531  }
532 
533  if (downloadFiles.isEmpty()) {
534  logger.log(Level.INFO, "Didn't find any Chrome download files."); //NON-NLS
535  return;
536  }
537 
538  dataFound = true;
539  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
540  int j = 0;
541  while (j < downloadFiles.size()) {
542  AbstractFile downloadFile = downloadFiles.get(j++);
543  if ((downloadFile.getSize() == 0) || (downloadFile.getName().toLowerCase().contains("-slack"))
544  || (downloadFile.getName().toLowerCase().contains("cache")) || (downloadFile.getName().toLowerCase().contains("index"))) {
545  continue;
546  }
547 
548  String temps = RAImageIngestModule.getRATempPath(currentCase, browser) + File.separator + downloadFile.getName() + j + ".db"; //NON-NLS
549  try {
550  ContentUtils.writeToFile(downloadFile, new File(temps), context::dataSourceIngestIsCancelled);
551  } catch (ReadContentInputStreamException ex) {
552  logger.log(Level.WARNING, String.format("Error reading Chrome download artifacts file '%s' (id=%d).",
553  downloadFile.getName(), downloadFile.getId()), ex); //NON-NLS
554  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Chrome.getDownload.errMsg.errAnalyzeFiles1",
555  this.getName(), downloadFile.getName()));
556  continue;
557  } catch (IOException ex) {
558  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Chrome download artifacts file '%s' (id=%d).",
559  temps, downloadFile.getName(), downloadFile.getId()), ex); //NON-NLS
560  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Chrome.getDownload.errMsg.errAnalyzeFiles1",
561  this.getName(), downloadFile.getName()));
562  continue;
563  }
564  File dbFile = new File(temps);
565  if (context.dataSourceIngestIsCancelled()) {
566  dbFile.delete();
567  break;
568  }
569 
570  List<HashMap<String, Object>> tempList;
571 
572  if (isChromePreVersion30(temps)) {
573  tempList = this.dbConnect(temps, DOWNLOAD_QUERY);
574  } else {
575  tempList = this.dbConnect(temps, DOWNLOAD_QUERY_V30);
576  }
577 
578  logger.log(Level.INFO, "{0}- Now getting downloads from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
579  for (HashMap<String, Object> result : tempList) {
580  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
581  String fullPath = result.get("full_path").toString(); //NON-NLS
582  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
583  RecentActivityExtracterModuleFactory.getModuleName(), fullPath));
584  long pathID = Util.findID(dataSource, fullPath);
585  if (pathID != -1) {
586  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
587  NbBundle.getMessage(this.getClass(),
588  "Chrome.parentModuleName"), pathID));
589  }
590  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
591  RecentActivityExtracterModuleFactory.getModuleName(),
592  ((result.get("url").toString() != null) ? result.get("url").toString() : ""))); //NON-NLS
593  //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "Recent Activity", ((result.get("url").toString() != null) ? EscapeUtil.decodeURL(result.get("url").toString()) : "")));
594  Long time = (Long.valueOf(result.get("start_time").toString()) / 1000000) - Long.valueOf("11644473600"); //NON-NLS
595 
596  //TODO Revisit usage of deprecated constructor as per TSK-583
597  //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "Recent Activity", "Last Visited", time));
598  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
599  RecentActivityExtracterModuleFactory.getModuleName(), time));
600  String domain = NetworkUtils.extractDomain((result.get("url").toString() != null) ? result.get("url").toString() : ""); //NON-NLS
601  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
602  RecentActivityExtracterModuleFactory.getModuleName(), domain));
603  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
604  RecentActivityExtracterModuleFactory.getModuleName(), browser));
605 
606  BlackboardArtifact webDownloadArtifact = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadFile, bbattributes);
607  if (webDownloadArtifact != null) {
608  bbartifacts.add(webDownloadArtifact);
609 
610  // find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact.
611  try {
612  String normalizedFullPath = FilenameUtils.normalize(fullPath, true);
613  for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(normalizedFullPath), FilenameUtils.getPath(normalizedFullPath))) {
614  BlackboardArtifact associatedObjectArtifact = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
615  associatedObjectArtifact.addAttribute(
616  new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
617  RecentActivityExtracterModuleFactory.getModuleName(), webDownloadArtifact.getArtifactID()));
618 
619  bbartifacts.add(associatedObjectArtifact);
620  break;
621  }
622  } catch (TskCoreException ex) {
623  logger.log(Level.SEVERE, String.format("Error creating associated object artifact for file '%s'", fullPath), ex); //NON-NLS
624  }
625  }
626  }
627 
628  dbFile.delete();
629  }
630 
631  if (!bbartifacts.isEmpty()) {
632  postArtifacts(bbartifacts);
633  }
634  }
635 
639  private void getLogins(String browser, String browserLocation) {
640 
641  FileManager fileManager = currentCase.getServices().getFileManager();
642  List<AbstractFile> loginDataFiles;
643  String loginDataFileName = LOGIN_DATA_FILE_NAME;
644  if (browser.equals(UC_BROWSER_NAME)) {
645  loginDataFileName = LOGIN_DATA_FILE_NAME + "%";
646  }
647 
648  try {
649  loginDataFiles = fileManager.findFiles(dataSource, loginDataFileName, browserLocation); //NON-NLS
650  } catch (TskCoreException ex) {
651  String msg = NbBundle.getMessage(this.getClass(), "Chrome.getLogin.errMsg.errGettingFiles");
652  logger.log(Level.SEVERE, msg, ex);
653  this.addErrorMessage(this.getName() + ": " + msg);
654  return;
655  }
656 
657  if (loginDataFiles.isEmpty()) {
658  logger.log(Level.INFO, "Didn't find any Chrome Login Data files."); //NON-NLS
659  return;
660  }
661 
662  dataFound = true;
663  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
664  int j = 0;
665  while (j < loginDataFiles.size()) {
666  AbstractFile loginDataFile = loginDataFiles.get(j++);
667  if ((loginDataFile.getSize() == 0) || (loginDataFile.getName().toLowerCase().contains("-slack"))) {
668  continue;
669  }
670  String temps = RAImageIngestModule.getRATempPath(currentCase, browser) + File.separator + loginDataFile.getName() + j + ".db"; //NON-NLS
671  try {
672  ContentUtils.writeToFile(loginDataFile, new File(temps), context::dataSourceIngestIsCancelled);
673  } catch (ReadContentInputStreamException ex) {
674  logger.log(Level.WARNING, String.format("Error reading Chrome login artifacts file '%s' (id=%d).",
675  loginDataFile.getName(), loginDataFile.getId()), ex); //NON-NLS
676  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Chrome.getLogin.errMsg.errAnalyzingFiles",
677  this.getName(), loginDataFile.getName()));
678  continue;
679  } catch (IOException ex) {
680  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Chrome login artifacts file '%s' (id=%d).",
681  temps, loginDataFile.getName(), loginDataFile.getId()), ex); //NON-NLS
682  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Chrome.getLogin.errMsg.errAnalyzingFiles",
683  this.getName(), loginDataFile.getName()));
684  continue;
685  }
686  File dbFile = new File(temps);
687  if (context.dataSourceIngestIsCancelled()) {
688  dbFile.delete();
689  break;
690  }
691  List<HashMap<String, Object>> tempList = this.dbConnect(temps, LOGIN_QUERY);
692  logger.log(Level.INFO, "{0}- Now getting login information from {1} with {2}artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
693  for (HashMap<String, Object> result : tempList) {
694  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
695 
696  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
697  RecentActivityExtracterModuleFactory.getModuleName(),
698  ((result.get("origin_url").toString() != null) ? result.get("origin_url").toString() : ""))); //NON-NLS
699 
700  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
701  RecentActivityExtracterModuleFactory.getModuleName(),
702  (Long.valueOf(result.get("date_created").toString()) / 1000000) - Long.valueOf("11644473600"))); //NON-NLS
703 
704  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED,
705  RecentActivityExtracterModuleFactory.getModuleName(),
706  (NetworkUtils.extractDomain((result.get("origin_url").toString() != null) ? result.get("origin_url").toString() : "")))); //NON-NLS
707 
708  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
709  RecentActivityExtracterModuleFactory.getModuleName(),
710  ((result.get("username_value").toString() != null) ? result.get("username_value").toString().replaceAll("'", "''") : ""))); //NON-NLS
711 
712  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REALM,
713  RecentActivityExtracterModuleFactory.getModuleName(),
714  ((result.get("signon_realm") != null && result.get("signon_realm").toString() != null) ? result.get("signon_realm").toString() : ""))); //NON-NLS
715 
716  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
717  RecentActivityExtracterModuleFactory.getModuleName(),
718  result.containsKey("signon_realm") ? NetworkUtils.extractDomain(result.get("signon_realm").toString()) : "")); //NON-NLS
719 
720  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
721  RecentActivityExtracterModuleFactory.getModuleName(), browser));
722 
723  BlackboardArtifact bbart = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_SERVICE_ACCOUNT, loginDataFile, bbattributes);
724  if (bbart != null) {
725  bbartifacts.add(bbart);
726  }
727  }
728 
729  dbFile.delete();
730  }
731 
732  if (!bbartifacts.isEmpty()) {
733  postArtifacts(bbartifacts);
734  }
735  }
736 
741  private void getAutofill(String browser, String browserLocation) {
742 
743  FileManager fileManager = currentCase.getServices().getFileManager();
744  List<AbstractFile> webDataFiles;
745  String webDataFileName = WEB_DATA_FILE_NAME;
746  if (browser.equals(UC_BROWSER_NAME)) {
747  webDataFileName = WEB_DATA_FILE_NAME + "%";
748  }
749 
750  try {
751  webDataFiles = fileManager.findFiles(dataSource, webDataFileName, browserLocation); //NON-NLS
752  } catch (TskCoreException ex) {
753  String msg = NbBundle.getMessage(this.getClass(), "Chrome.getAutofills.errMsg.errGettingFiles");
754  logger.log(Level.SEVERE, msg, ex);
755  this.addErrorMessage(this.getName() + ": " + msg);
756  return;
757  }
758 
759  if (webDataFiles.isEmpty()) {
760  logger.log(Level.INFO, "Didn't find any Chrome Web Data files."); //NON-NLS
761  return;
762  }
763 
764  dataFound = true;
765  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
766  int j = 0;
767  while (j < webDataFiles.size()) {
768  AbstractFile webDataFile = webDataFiles.get(j++);
769  if ((webDataFile.getSize() == 0) || (webDataFile.getName().toLowerCase().contains("-slack"))) {
770  continue;
771  }
772  String tempFilePath = RAImageIngestModule.getRATempPath(currentCase, browser) + File.separator + webDataFile.getName() + j + ".db"; //NON-NLS
773  try {
774  ContentUtils.writeToFile(webDataFile, new File(tempFilePath), context::dataSourceIngestIsCancelled);
775  } catch (ReadContentInputStreamException ex) {
776  logger.log(Level.WARNING, String.format("Error reading Chrome Autofill artifacts file '%s' (id=%d).",
777  webDataFile.getName(), webDataFile.getId()), ex); //NON-NLS
778  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Chrome.getAutofill.errMsg.errAnalyzingFiles",
779  this.getName(), webDataFile.getName()));
780  continue;
781  } catch (IOException ex) {
782  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Chrome Web data file '%s' (id=%d).",
783  tempFilePath, webDataFile.getName(), webDataFile.getId()), ex); //NON-NLS
784  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Chrome.getLogin.errMsg.errAnalyzingFiles",
785  this.getName(), webDataFile.getName()));
786  continue;
787  }
788  File dbFile = new File(tempFilePath);
789  if (context.dataSourceIngestIsCancelled()) {
790  dbFile.delete();
791  break;
792  }
793 
794  // The DB schema is little different in schema version 8x vs older versions
795  boolean isSchemaV8X = Util.checkColumn("date_created", "autofill", tempFilePath);
796 
797  // get form autofill artifacts
798  bbartifacts.addAll(getFormAutofillArtifacts(webDataFile, tempFilePath, isSchemaV8X, browser));
799  try {
800  // get form address atifacts
801  getFormAddressArtifacts(webDataFile, tempFilePath, isSchemaV8X);
802  } catch (NoCurrentCaseException | TskCoreException | Blackboard.BlackboardException ex) {
803  logger.log(Level.SEVERE, String.format("Error adding artifacts to the case database "
804  + "for chrome file %s [objId=%d]", webDataFile.getName(), webDataFile.getId()), ex);
805  }
806 
807  dbFile.delete();
808  }
809 
810  if (!bbartifacts.isEmpty()) {
811  postArtifacts(bbartifacts);
812  }
813  }
814 
825  private Collection<BlackboardArtifact> getFormAutofillArtifacts(AbstractFile webDataFile, String dbFilePath, boolean isSchemaV8X, String browser) {
826 
827  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
828 
829  // The DB Schema is little different in version 8x vs older versions
830  String autoFillquery = (isSchemaV8X) ? AUTOFILL_QUERY_V8X
831  : AUTOFILL_QUERY;
832 
833  List<HashMap<String, Object>> autofills = this.dbConnect(dbFilePath, autoFillquery);
834  logger.log(Level.INFO, "{0}- Now getting Autofill information from {1} with {2}artifacts identified.", new Object[]{moduleName, dbFilePath, autofills.size()}); //NON-NLS
835  for (HashMap<String, Object> result : autofills) {
836  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
837 
838  // extract all common attributes
839  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
840  NbBundle.getMessage(this.getClass(), "Chrome.parentModuleName"),
841  ((result.get("name").toString() != null) ? result.get("name").toString() : ""))); //NON-NLS
842 
843  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
844  RecentActivityExtracterModuleFactory.getModuleName(),
845  ((result.get("value").toString() != null) ? result.get("value").toString() : ""))); //NON-NLS
846 
847  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
848  RecentActivityExtracterModuleFactory.getModuleName(),
849  (Integer.valueOf(result.get("count").toString())))); //NON-NLS
850 
851  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
852  RecentActivityExtracterModuleFactory.getModuleName(),
853  Long.valueOf(result.get("date_created").toString()))); //NON-NLS
854 
855  // get schema version specific attributes
856  if (isSchemaV8X) {
857  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
858  RecentActivityExtracterModuleFactory.getModuleName(),
859  Long.valueOf(result.get("date_last_used").toString()))); //NON-NLS
860  }
861 
862  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
863  RecentActivityExtracterModuleFactory.getModuleName(), browser));
864 
865  // Add an artifact
866  BlackboardArtifact bbart = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_FORM_AUTOFILL, webDataFile, bbattributes);
867  if (bbart != null) {
868  bbartifacts.add(bbart);
869  }
870  }
871 
872  // return all extracted artifacts
873  return bbartifacts;
874  }
875 
887  private void getFormAddressArtifacts(AbstractFile webDataFile, String dbFilePath, boolean isSchemaV8X) throws NoCurrentCaseException,
888  TskCoreException, Blackboard.BlackboardException {
889 
890  String webformAddressQuery = (isSchemaV8X) ? WEBFORM_ADDRESS_QUERY_V8X
891  : WEBFORM_ADDRESS_QUERY;
892 
893  // Helper to create web form address artifacts.
894  WebBrowserArtifactsHelper helper = new WebBrowserArtifactsHelper(
895  Case.getCurrentCaseThrows().getSleuthkitCase(),
896  NbBundle.getMessage(this.getClass(), "Chrome.parentModuleName"),
897  webDataFile
898  );
899 
900  // Get Web form addresses
901  List<HashMap<String, Object>> addresses = this.dbConnect(dbFilePath, webformAddressQuery);
902  logger.log(Level.INFO, "{0}- Now getting Web form addresses from {1} with {2}artifacts identified.", new Object[]{moduleName, dbFilePath, addresses.size()}); //NON-NLS
903  for (HashMap<String, Object> result : addresses) {
904 
905  // get name fields
906  String first_name = result.get("first_name").toString() != null ? result.get("first_name").toString() : "";
907  String middle_name = result.get("middle_name").toString() != null ? result.get("middle_name").toString() : "";
908  String last_name = result.get("last_name").toString() != null ? result.get("last_name").toString() : "";
909 
910  // get email and phone
911  String email_Addr = result.get("email").toString() != null ? result.get("email").toString() : "";
912  String phone_number = result.get("number").toString() != null ? result.get("number").toString() : "";
913 
914  // Get the address fields
915  String city = result.get("city").toString() != null ? result.get("city").toString() : "";
916  String state = result.get("state").toString() != null ? result.get("state").toString() : "";
917  String zipcode = result.get("zipcode").toString() != null ? result.get("zipcode").toString() : "";
918  String country_code = result.get("country_code").toString() != null ? result.get("country_code").toString() : "";
919 
920  // schema version specific fields
921  String full_name = "";
922  String street_address = "";
923  long date_modified = 0;
924  int use_count = 0;
925  long use_date = 0;
926 
927  if (isSchemaV8X) {
928  full_name = result.get("full_name").toString() != null ? result.get("full_name").toString() : "";
929  street_address = result.get("street_address").toString() != null ? result.get("street_address").toString() : "";
930  date_modified = result.get("date_modified").toString() != null ? Long.valueOf(result.get("date_modified").toString()) : 0;
931  use_count = result.get("use_count").toString() != null ? Integer.valueOf(result.get("use_count").toString()) : 0;
932  use_date = result.get("use_date").toString() != null ? Long.valueOf(result.get("use_date").toString()) : 0;
933  } else {
934  String address_line_1 = result.get("address_line_1").toString() != null ? result.get("street_address").toString() : "";
935  String address_line_2 = result.get("address_line_2").toString() != null ? result.get("address_line_2").toString() : "";
936  street_address = String.join(" ", address_line_1, address_line_2);
937  }
938 
939  // Create atrributes from extracted fields
940  if (full_name == null || full_name.isEmpty()) {
941  full_name = String.join(" ", first_name, middle_name, last_name);
942  }
943 
944  String locationAddress = String.join(", ", street_address, city, state, zipcode, country_code);
945 
946  List<BlackboardAttribute> otherAttributes = new ArrayList<>();
947  if (date_modified > 0) {
948  otherAttributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED,
949  RecentActivityExtracterModuleFactory.getModuleName(),
950  date_modified)); //NON-NLS
951  }
952 
953  helper.addWebFormAddress(
954  full_name, email_Addr, phone_number,
955  locationAddress, 0, use_date,
956  use_count, otherAttributes);
957  }
958  }
959 
960  private boolean isChromePreVersion30(String temps) {
961  String query = "PRAGMA table_info(downloads)"; //NON-NLS
962  List<HashMap<String, Object>> columns = this.dbConnect(temps, query);
963  for (HashMap<String, Object> col : columns) {
964  if (col.get("name").equals("url")) { //NON-NLS
965  return true;
966  }
967  }
968 
969  return false;
970  }
971 }

Copyright © 2012-2021 Basis Technology. Generated on: Tue Jan 19 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.