Autopsy  4.10.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
Firefox.java
Go to the documentation of this file.
1  /*
2  *
3  * Autopsy Forensic Browser
4  *
5  * Copyright 2012-2019 Basis Technology Corp.
6  *
7  * Copyright 2012 42six Solutions.
8  * Contact: aebadirad <at> 42six <dot> com
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.gson.JsonArray;
26 import com.google.gson.JsonElement;
27 import com.google.gson.JsonIOException;
28 import com.google.gson.JsonObject;
29 import com.google.gson.JsonParser;
30 import com.google.gson.JsonSyntaxException;
31 import java.io.File;
32 import java.io.FileNotFoundException;
33 import java.io.FileReader;
34 import java.io.IOException;
35 import java.io.UnsupportedEncodingException;
36 import java.net.URLDecoder;
37 import java.util.ArrayList;
38 import java.util.Arrays;
39 import java.util.Collection;
40 import java.util.HashMap;
41 import java.util.HashSet;
42 import java.util.List;
43 import java.util.Set;
44 import java.util.logging.Level;
45 import org.apache.commons.io.FilenameUtils;
46 
47 import org.openide.util.NbBundle;
48 import org.openide.util.NbBundle.Messages;
59 import org.sleuthkit.datamodel.AbstractFile;
60 import org.sleuthkit.datamodel.Account;
61 import org.sleuthkit.datamodel.BlackboardArtifact;
62 import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
63 import org.sleuthkit.datamodel.BlackboardAttribute;
64 import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
65 import org.sleuthkit.datamodel.Content;
66 import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
67 import org.sleuthkit.datamodel.TskCoreException;
68 
69 @Messages({
70  "Progress_Message_Firefox_History=Firefox History",
71  "Progress_Message_Firefox_Bookmarks=Firefox Bookmarks",
72  "Progress_Message_Firefox_Cookies=Firefox Cookies",
73  "Progress_Message_Firefox_Downloads=Firefox Downloads",
74  "Progress_Message_Firefox_FormHistory=Firefox Form History",
75  "Progress_Message_Firefox_AutoFill=Firefox Auto Fill"
76 })
77 
81 class Firefox extends Extract {
82 
83  private static final Logger logger = Logger.getLogger(Firefox.class.getName());
84  private static final String PLACE_URL_PREFIX = "place:";
85  private static final String HISTORY_QUERY = "SELECT moz_historyvisits.id, url, title, visit_count,(visit_date/1000000) AS visit_date,from_visit,"
86  + "(SELECT url FROM moz_historyvisits history, moz_places places where history.id = moz_historyvisits.from_visit and history.place_id = places.id ) as ref "
87  + "FROM moz_places, moz_historyvisits "
88  + "WHERE moz_places.id = moz_historyvisits.place_id "
89  + "AND hidden = 0"; //NON-NLS
90  private static final String COOKIE_QUERY = "SELECT name,value,host,expiry,(lastAccessed/1000000) AS lastAccessed,(creationTime/1000000) AS creationTime FROM moz_cookies"; //NON-NLS
91  private static final String COOKIE_QUERY_V3 = "SELECT name,value,host,expiry,(lastAccessed/1000000) AS lastAccessed FROM moz_cookies"; //NON-NLS
92  private static final String BOOKMARK_QUERY = "SELECT fk, moz_bookmarks.title, url, (moz_bookmarks.dateAdded/1000000) AS dateAdded FROM moz_bookmarks INNER JOIN moz_places ON moz_bookmarks.fk=moz_places.id"; //NON-NLS
93  private static final String DOWNLOAD_QUERY = "SELECT target, source,(startTime/1000000) AS startTime, maxBytes FROM moz_downloads"; //NON-NLS
94  private static final String DOWNLOAD_QUERY_V24 = "SELECT url, content AS target, (lastModified/1000000) AS lastModified "
95  + " FROM moz_places, moz_annos, moz_anno_attributes "
96  + " WHERE moz_places.id = moz_annos.place_id"
97  + " AND moz_annos.anno_attribute_id = moz_anno_attributes.id"
98  + " AND moz_anno_attributes.name='downloads/destinationFileURI'"; //NON-NLS
99  private static final String FORMHISTORY_QUERY = "SELECT fieldname, value FROM moz_formhistory";
100  private static final String FORMHISTORY_QUERY_V64 = "SELECT fieldname, value, timesUsed, firstUsed, lastUsed FROM moz_formhistory";
101  private final IngestServices services = IngestServices.getInstance();
102  private Content dataSource;
103  private IngestJobContext context;
104 
105  Firefox() {
106  moduleName = NbBundle.getMessage(Firefox.class, "Firefox.moduleName");
107  }
108 
109  @Override
110  public void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
111  this.dataSource = dataSource;
112  this.context = context;
113  dataFound = false;
114 
115  progressBar.progress(Bundle.Progress_Message_Firefox_History());
116  this.getHistory();
117 
118  progressBar.progress(Bundle.Progress_Message_Firefox_Bookmarks());
119  this.getBookmark();
120 
121  progressBar.progress(Bundle.Progress_Message_Firefox_Downloads());
122  this.getDownload();
123 
124  progressBar.progress(Bundle.Progress_Message_Firefox_Cookies());
125  this.getCookie();
126 
127  progressBar.progress(Bundle.Progress_Message_Firefox_FormHistory());
128  this.getFormsHistory();
129 
130  progressBar.progress(Bundle.Progress_Message_Firefox_AutoFill());
131  this.getAutofillProfiles();
132  }
133 
134  private void getHistory() {
135  FileManager fileManager = currentCase.getServices().getFileManager();
136  List<AbstractFile> historyFiles;
137  try {
138  historyFiles = fileManager.findFiles(dataSource, "places.sqlite", "Firefox"); //NON-NLS
139  } catch (TskCoreException ex) {
140  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.errFetchingFiles");
141  logger.log(Level.WARNING, msg);
142  this.addErrorMessage(this.getName() + ": " + msg);
143  return;
144  }
145 
146  if (historyFiles.isEmpty()) {
147  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.noFilesFound");
148  logger.log(Level.INFO, msg);
149  return;
150  }
151 
152  dataFound = true;
153  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
154  int j = 0;
155  for (AbstractFile historyFile : historyFiles) {
156  if (historyFile.getSize() == 0) {
157  continue;
158  }
159 
160  String fileName = historyFile.getName();
161  String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
162  try {
163  ContentUtils.writeToFile(historyFile, new File(temps), context::dataSourceIngestIsCancelled);
164  } catch (ReadContentInputStreamException ex) {
165  logger.log(Level.WARNING, String.format("Error reading Firefox web history artifacts file '%s' (id=%d).",
166  fileName, historyFile.getId()), ex); //NON-NLS
167  this.addErrorMessage(
168  NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
169  fileName));
170  continue;
171  } catch (IOException ex) {
172  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Firefox web history artifacts file '%s' (id=%d).",
173  temps, fileName, historyFile.getId()), ex); //NON-NLS
174  this.addErrorMessage(
175  NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
176  fileName));
177  continue;
178  }
179  File dbFile = new File(temps);
180  if (context.dataSourceIngestIsCancelled()) {
181  dbFile.delete();
182  break;
183  }
184  List<HashMap<String, Object>> tempList = this.dbConnect(temps, HISTORY_QUERY);
185  logger.log(Level.INFO, "{0} - Now getting history from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
186  for (HashMap<String, Object> result : tempList) {
187  String url = result.get("url").toString();
188 
189  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
190  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
191  RecentActivityExtracterModuleFactory.getModuleName(),
192  ((url != null) ? url : ""))); //NON-NLS
193  //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("url").toString() != null) ? EscapeUtil.decodeURL(result.get("url").toString()) : "")));
194  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
195  RecentActivityExtracterModuleFactory.getModuleName(),
196  (Long.valueOf(result.get("visit_date").toString())))); //NON-NLS
197  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER,
198  RecentActivityExtracterModuleFactory.getModuleName(),
199  ((result.get("ref").toString() != null) ? result.get("ref").toString() : ""))); //NON-NLS
200  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
201  RecentActivityExtracterModuleFactory.getModuleName(),
202  ((result.get("title").toString() != null) ? result.get("title").toString() : ""))); //NON-NLS
203  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
204  RecentActivityExtracterModuleFactory.getModuleName(),
205  NbBundle.getMessage(this.getClass(), "Firefox.moduleName")));
206  String domain = extractDomain(url);
207  if (domain != null && domain.isEmpty() == false) {
208  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
209  RecentActivityExtracterModuleFactory.getModuleName(), domain)); //NON-NLS
210 
211  }
212  BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY, historyFile, bbattributes);
213  if (bbart != null) {
214  bbartifacts.add(bbart);
215  }
216  }
217  ++j;
218  dbFile.delete();
219  }
220 
221  services.fireModuleDataEvent(new ModuleDataEvent(
222  NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
223  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, bbartifacts));
224  }
225 
229  private void getBookmark() {
230 
231  FileManager fileManager = currentCase.getServices().getFileManager();
232  List<AbstractFile> bookmarkFiles;
233  try {
234  bookmarkFiles = fileManager.findFiles(dataSource, "places.sqlite", "Firefox"); //NON-NLS
235  } catch (TskCoreException ex) {
236  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getBookmark.errMsg.errFetchFiles");
237  logger.log(Level.WARNING, msg);
238  this.addErrorMessage(this.getName() + ": " + msg);
239  return;
240  }
241 
242  if (bookmarkFiles.isEmpty()) {
243  logger.log(Level.INFO, "Didn't find any firefox bookmark files."); //NON-NLS
244  return;
245  }
246 
247  dataFound = true;
248  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
249  int j = 0;
250  for (AbstractFile bookmarkFile : bookmarkFiles) {
251  if (bookmarkFile.getSize() == 0) {
252  continue;
253  }
254  String fileName = bookmarkFile.getName();
255  String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
256  try {
257  ContentUtils.writeToFile(bookmarkFile, new File(temps), context::dataSourceIngestIsCancelled);
258  } catch (ReadContentInputStreamException ex) {
259  logger.log(Level.WARNING, String.format("Error reading Firefox bookmark artifacts file '%s' (id=%d).",
260  fileName, bookmarkFile.getId()), ex); //NON-NLS
261  this.addErrorMessage(
262  NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
263  fileName));
264  continue;
265  } catch (IOException ex) {
266  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Firefox bookmark artifacts file '%s' (id=%d).",
267  temps, fileName, bookmarkFile.getId()), ex); //NON-NLS
268  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getBookmark.errMsg.errAnalyzeFile",
269  this.getName(), fileName));
270  continue;
271  }
272  File dbFile = new File(temps);
273  if (context.dataSourceIngestIsCancelled()) {
274  dbFile.delete();
275  break;
276  }
277  List<HashMap<String, Object>> tempList = this.dbConnect(temps, BOOKMARK_QUERY);
278  logger.log(Level.INFO, "{0} - Now getting bookmarks from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
279  for (HashMap<String, Object> result : tempList) {
280  String url = result.get("url").toString();
281 
282  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
283  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
284  RecentActivityExtracterModuleFactory.getModuleName(),
285  ((url != null) ? url : ""))); //NON-NLS
286  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
287  RecentActivityExtracterModuleFactory.getModuleName(),
288  ((result.get("title").toString() != null) ? result.get("title").toString() : ""))); //NON-NLS
289  if (Long.valueOf(result.get("dateAdded").toString()) > 0) { //NON-NLS
290  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
291  RecentActivityExtracterModuleFactory.getModuleName(),
292  (Long.valueOf(result.get("dateAdded").toString())))); //NON-NLS
293  }
294  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
295  RecentActivityExtracterModuleFactory.getModuleName(),
296  NbBundle.getMessage(this.getClass(), "Firefox.moduleName")));
297  String domain = extractDomain(url);
298  if (domain != null && domain.isEmpty() == false) {
299  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
300  RecentActivityExtracterModuleFactory.getModuleName(), domain)); //NON-NLS
301  }
302 
303  BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK, bookmarkFile, bbattributes);
304  if (bbart != null) {
305  bbartifacts.add(bbart);
306  }
307  }
308  ++j;
309  dbFile.delete();
310  }
311 
312  services.fireModuleDataEvent(new ModuleDataEvent(
313  NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
314  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK, bbartifacts));
315  }
316 
320  private void getCookie() {
321  FileManager fileManager = currentCase.getServices().getFileManager();
322  List<AbstractFile> cookiesFiles;
323  try {
324  cookiesFiles = fileManager.findFiles(dataSource, "cookies.sqlite", "Firefox"); //NON-NLS
325  } catch (TskCoreException ex) {
326  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getCookie.errMsg.errFetchFile");
327  logger.log(Level.WARNING, msg);
328  this.addErrorMessage(this.getName() + ": " + msg);
329  return;
330  }
331 
332  if (cookiesFiles.isEmpty()) {
333  logger.log(Level.INFO, "Didn't find any Firefox cookie files."); //NON-NLS
334  return;
335  }
336 
337  dataFound = true;
338  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
339  int j = 0;
340  for (AbstractFile cookiesFile : cookiesFiles) {
341  if (cookiesFile.getSize() == 0) {
342  continue;
343  }
344  String fileName = cookiesFile.getName();
345  String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
346  try {
347  ContentUtils.writeToFile(cookiesFile, new File(temps), context::dataSourceIngestIsCancelled);
348  } catch (ReadContentInputStreamException ex) {
349  logger.log(Level.WARNING, String.format("Error reading Firefox cookie artifacts file '%s' (id=%d).",
350  fileName, cookiesFile.getId()), ex); //NON-NLS
351  this.addErrorMessage(
352  NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
353  fileName));
354  continue;
355  } catch (IOException ex) {
356  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Firefox cookie artifacts file '%s' (id=%d).",
357  temps, fileName, cookiesFile.getId()), ex); //NON-NLS
358  this.addErrorMessage(
359  NbBundle.getMessage(this.getClass(), "Firefox.getCookie.errMsg.errAnalyzeFile", this.getName(),
360  fileName));
361  continue;
362  }
363  File dbFile = new File(temps);
364  if (context.dataSourceIngestIsCancelled()) {
365  dbFile.delete();
366  break;
367  }
368  boolean checkColumn = Util.checkColumn("creationTime", "moz_cookies", temps); //NON-NLS
369  String query;
370  if (checkColumn) {
371  query = COOKIE_QUERY;
372  } else {
373  query = COOKIE_QUERY_V3;
374  }
375 
376  List<HashMap<String, Object>> tempList = this.dbConnect(temps, query);
377  logger.log(Level.INFO, "{0} - Now getting cookies from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
378  for (HashMap<String, Object> result : tempList) {
379  String host = result.get("host").toString();
380 
381  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
382  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
383  RecentActivityExtracterModuleFactory.getModuleName(),
384  ((host != null) ? host : ""))); //NON-NLS
385  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME,
386  RecentActivityExtracterModuleFactory.getModuleName(),
387  (Long.valueOf(result.get("lastAccessed").toString())))); //NON-NLS
388  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
389  RecentActivityExtracterModuleFactory.getModuleName(),
390  ((result.get("name").toString() != null) ? result.get("name").toString() : ""))); //NON-NLS
391  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
392  RecentActivityExtracterModuleFactory.getModuleName(),
393  ((result.get("value").toString() != null) ? result.get("value").toString() : ""))); //NON-NLS
394  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
395  RecentActivityExtracterModuleFactory.getModuleName(),
396  NbBundle.getMessage(this.getClass(), "Firefox.moduleName")));
397 
398  if (checkColumn == true) {
399  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
400  RecentActivityExtracterModuleFactory.getModuleName(),
401  (Long.valueOf(result.get("creationTime").toString())))); //NON-NLS
402  }
403  String domain = extractDomain(host);
404  if (domain != null && domain.isEmpty() == false) {
405  domain = domain.replaceFirst("^\\.+(?!$)", "");
406  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
407  RecentActivityExtracterModuleFactory.getModuleName(), domain));
408  }
409 
410  BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_COOKIE, cookiesFile, bbattributes);
411  if (bbart != null) {
412  bbartifacts.add(bbart);
413  }
414  }
415  ++j;
416  dbFile.delete();
417  }
418 
419  services.fireModuleDataEvent(new ModuleDataEvent(
420  NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
421  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE, bbartifacts));
422  }
423 
427  private void getDownload() {
428  getDownloadPreVersion24();
429  getDownloadVersion24();
430  }
431 
437  private void getDownloadPreVersion24() {
438 
439  FileManager fileManager = currentCase.getServices().getFileManager();
440  List<AbstractFile> downloadsFiles;
441  try {
442  downloadsFiles = fileManager.findFiles(dataSource, "downloads.sqlite", "Firefox"); //NON-NLS
443  } catch (TskCoreException ex) {
444  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getDlPre24.errMsg.errFetchFiles");
445  logger.log(Level.WARNING, msg);
446  this.addErrorMessage(this.getName() + ": " + msg);
447  return;
448  }
449 
450  if (downloadsFiles.isEmpty()) {
451  logger.log(Level.INFO, "Didn't find any pre-version-24.0 Firefox download files."); //NON-NLS
452  return;
453  }
454 
455  dataFound = true;
456  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
457  int j = 0;
458  for (AbstractFile downloadsFile : downloadsFiles) {
459  if (downloadsFile.getSize() == 0) {
460  continue;
461  }
462  String fileName = downloadsFile.getName();
463  String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
464  int errors = 0;
465  try {
466  ContentUtils.writeToFile(downloadsFile, new File(temps), context::dataSourceIngestIsCancelled);
467  } catch (ReadContentInputStreamException ex) {
468  logger.log(Level.WARNING, String.format("Error reading Firefox download artifacts file '%s' (id=%d).",
469  fileName, downloadsFile.getId()), ex); //NON-NLS
470  this.addErrorMessage(
471  NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
472  fileName));
473  continue;
474  } catch (IOException ex) {
475  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Firefox download artifacts file '%s' (id=%d).",
476  temps, fileName, downloadsFile.getId()), ex); //NON-NLS
477  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getDlPre24.errMsg.errAnalyzeFiles",
478  this.getName(), fileName));
479  continue;
480  }
481  File dbFile = new File(temps);
482  if (context.dataSourceIngestIsCancelled()) {
483  dbFile.delete();
484  break;
485  }
486 
487  List<HashMap<String, Object>> tempList = this.dbConnect(temps, DOWNLOAD_QUERY);
488  logger.log(Level.INFO, "{0}- Now getting downloads from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
489  for (HashMap<String, Object> result : tempList) {
490  String source = result.get("source").toString();
491 
492  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
493 
494  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
495  RecentActivityExtracterModuleFactory.getModuleName(),
496  source)); //NON-NLS
497  //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("source").toString() != null) ? EscapeUtil.decodeURL(result.get("source").toString()) : "")));
498  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
499  RecentActivityExtracterModuleFactory.getModuleName(),
500  (Long.valueOf(result.get("startTime").toString())))); //NON-NLS
501 
502  String target = result.get("target").toString(); //NON-NLS
503  String downloadedFilePath = "";
504  if (target != null) {
505  try {
506  downloadedFilePath = URLDecoder.decode(target.replaceAll("file:///", ""), "UTF-8"); //NON-NLS
507  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
508  RecentActivityExtracterModuleFactory.getModuleName(),
509  downloadedFilePath));
510  long pathID = Util.findID(dataSource, downloadedFilePath);
511  if (pathID != -1) {
512  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
513  RecentActivityExtracterModuleFactory.getModuleName(),
514  pathID));
515  }
516  } catch (UnsupportedEncodingException ex) {
517  logger.log(Level.SEVERE, "Error decoding Firefox download URL in " + temps, ex); //NON-NLS
518  errors++;
519  }
520  }
521 
522  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
523  RecentActivityExtracterModuleFactory.getModuleName(),
524  NbBundle.getMessage(this.getClass(), "Firefox.moduleName")));
525  String domain = extractDomain(source);
526  if (domain != null && domain.isEmpty() == false) {
527  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
528  RecentActivityExtracterModuleFactory.getModuleName(),
529  domain)); //NON-NLS
530  }
531 
532  BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
533  if (bbart != null) {
534  bbartifacts.add(bbart);
535  }
536 
537  // find the downloaded file and create a TSK_DOWNLOAD_SOURCE for it.
538  try {
539  for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) {
540  BlackboardArtifact downloadSourceArt = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE);
541  downloadSourceArt.addAttributes(createDownloadSourceAttributes(source));
542  bbartifacts.add(downloadSourceArt);
543  break;
544  }
545  } catch (TskCoreException ex) {
546  logger.log(Level.SEVERE, String.format("Error creating download source artifact for file '%s'",
547  downloadedFilePath), ex); //NON-NLS
548  }
549  }
550  if (errors > 0) {
551  this.addErrorMessage(
552  NbBundle.getMessage(this.getClass(), "Firefox.getDlPre24.errMsg.errParsingArtifacts",
553  this.getName(), errors));
554  }
555  j++;
556  dbFile.delete();
557  break;
558  }
559 
560  services.fireModuleDataEvent(new ModuleDataEvent(
561  NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
562  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, bbartifacts));
563  }
564 
570  private void getDownloadVersion24() {
571  FileManager fileManager = currentCase.getServices().getFileManager();
572  List<AbstractFile> downloadsFiles;
573  try {
574  downloadsFiles = fileManager.findFiles(dataSource, "places.sqlite", "Firefox"); //NON-NLS
575  } catch (TskCoreException ex) {
576  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getDlV24.errMsg.errFetchFiles");
577  logger.log(Level.WARNING, msg);
578  this.addErrorMessage(this.getName() + ": " + msg);
579  return;
580  }
581 
582  if (downloadsFiles.isEmpty()) {
583  logger.log(Level.INFO, "Didn't find any version-24.0 Firefox download files."); //NON-NLS
584  return;
585  }
586 
587  dataFound = true;
588  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
589  int j = 0;
590  for (AbstractFile downloadsFile : downloadsFiles) {
591  if (downloadsFile.getSize() == 0) {
592  continue;
593  }
594  String fileName = downloadsFile.getName();
595  String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + "-downloads" + j + ".db"; //NON-NLS
596  int errors = 0;
597  try {
598  ContentUtils.writeToFile(downloadsFile, new File(temps), context::dataSourceIngestIsCancelled);
599  } catch (ReadContentInputStreamException ex) {
600  logger.log(Level.WARNING, String.format("Error reading Firefox download artifacts file '%s' (id=%d).",
601  fileName, downloadsFile.getId()), ex); //NON-NLS
602  this.addErrorMessage(
603  NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
604  fileName));
605  continue;
606  } catch (IOException ex) {
607  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Firefox download artifacts file '%s' (id=%d).",
608  temps, fileName, downloadsFile.getId()), ex); //NON-NLS
609  this.addErrorMessage(
610  NbBundle.getMessage(this.getClass(), "Firefox.getDlV24.errMsg.errAnalyzeFile", this.getName(),
611  fileName));
612  continue;
613  }
614  File dbFile = new File(temps);
615  if (context.dataSourceIngestIsCancelled()) {
616  dbFile.delete();
617  break;
618  }
619 
620  List<HashMap<String, Object>> tempList = this.dbConnect(temps, DOWNLOAD_QUERY_V24);
621 
622  logger.log(Level.INFO, "{0} - Now getting downloads from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
623  for (HashMap<String, Object> result : tempList) {
624  String url = result.get("url").toString();
625 
626  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
627 
628  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
629  RecentActivityExtracterModuleFactory.getModuleName(),
630  url)); //NON-NLS
631  //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("source").toString() != null) ? EscapeUtil.decodeURL(result.get("source").toString()) : "")));
632  //TODO Revisit usage of deprecated constructor as per TSK-583
633  //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "RecentActivity", "Last Visited", (Long.valueOf(result.get("startTime").toString()))));
634 
635  String target = result.get("target").toString(); //NON-NLS
636  String downloadedFilePath = "";
637  if (target != null) {
638  try {
639  downloadedFilePath = URLDecoder.decode(target.replaceAll("file:///", ""), "UTF-8"); //NON-NLS
640  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
641  RecentActivityExtracterModuleFactory.getModuleName(),
642  downloadedFilePath));
643  long pathID = Util.findID(dataSource, downloadedFilePath);
644  if (pathID != -1) {
645  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
646  RecentActivityExtracterModuleFactory.getModuleName(),
647  pathID));
648  }
649  } catch (UnsupportedEncodingException ex) {
650  logger.log(Level.SEVERE, "Error decoding Firefox download URL in " + temps, ex); //NON-NLS
651  errors++;
652  }
653  }
654  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
655  RecentActivityExtracterModuleFactory.getModuleName(),
656  Long.valueOf(result.get("lastModified").toString()))); //NON-NLS
657  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
658  RecentActivityExtracterModuleFactory.getModuleName(),
659  NbBundle.getMessage(this.getClass(), "Firefox.moduleName")));
660  String domain = extractDomain(url);
661  if (domain != null && domain.isEmpty() == false) {
662  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
663  RecentActivityExtracterModuleFactory.getModuleName(), domain)); //NON-NLS
664  }
665 
666  BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
667  if (bbart != null) {
668  bbartifacts.add(bbart);
669  }
670 
671  // find the downloaded file and create a TSK_DOWNLOAD_SOURCE for it.
672  try {
673  for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) {
674  BlackboardArtifact downloadSourceArt = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE);
675  downloadSourceArt.addAttributes(createDownloadSourceAttributes(url));
676  bbartifacts.add(downloadSourceArt);
677  break;
678  }
679  } catch (TskCoreException ex) {
680  logger.log(Level.SEVERE, String.format("Error creating download source artifact for file '%s'",
681  downloadedFilePath), ex); //NON-NLS
682  }
683  }
684  if (errors > 0) {
685  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getDlV24.errMsg.errParsingArtifacts",
686  this.getName(), errors));
687  }
688  j++;
689  dbFile.delete();
690  break;
691  }
692 
693  services.fireModuleDataEvent(new ModuleDataEvent(
694  NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
695  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, bbartifacts));
696  }
697 
702  private void getFormsHistory() {
703  FileManager fileManager = currentCase.getServices().getFileManager();
704  List<AbstractFile> formHistoryFiles;
705 
706  // Some fields are just noisy and can me excluded
707  Set<String> excludedFieldNames = new HashSet<>(Arrays.asList(
708  "it", // some kind of timestamp
709  "ts" // some kind of timestamp
710  ));
711 
712  try {
713  formHistoryFiles = fileManager.findFiles(dataSource, "formhistory.sqlite", "Firefox"); //NON-NLS
714  } catch (TskCoreException ex) {
715  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.errFetchingFiles");
716  logger.log(Level.WARNING, msg);
717  this.addErrorMessage(this.getName() + ": " + msg);
718  return;
719  }
720 
721  if (formHistoryFiles.isEmpty()) {
722  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.noFilesFound");
723  logger.log(Level.INFO, msg);
724  return;
725  }
726 
727  dataFound = true;
728  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
729  int j = 0;
730  for (AbstractFile formHistoryFile : formHistoryFiles) {
731  if (formHistoryFile.getSize() == 0) {
732  continue;
733  }
734 
735  String fileName = formHistoryFile.getName();
736  String tempFilePath = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
737  try {
738  ContentUtils.writeToFile(formHistoryFile, new File(tempFilePath), context::dataSourceIngestIsCancelled);
739  } catch (ReadContentInputStreamException ex) {
740  logger.log(Level.WARNING, String.format("Error reading Firefox web history artifacts file '%s' (id=%d).",
741  fileName, formHistoryFile.getId()), ex); //NON-NLS
742  this.addErrorMessage(
743  NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.errAnalyzeFile", this.getName(),
744  fileName));
745  continue;
746  } catch (IOException ex) {
747  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Firefox web history artifacts file '%s' (id=%d).",
748  tempFilePath, fileName, formHistoryFile.getId()), ex); //NON-NLS
749  this.addErrorMessage(
750  NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.errAnalyzeFile", this.getName(),
751  fileName));
752  continue;
753  }
754  File dbFile = new File(tempFilePath);
755  if (context.dataSourceIngestIsCancelled()) {
756  dbFile.delete();
757  break;
758  }
759 
760  // The table schema is a little different in newer version of Firefox
761  boolean isFirefoxV64 = Util.checkColumn("timesUsed", "moz_formhistory", tempFilePath);
762  String formHistoryQuery = (isFirefoxV64) ? FORMHISTORY_QUERY_V64 : FORMHISTORY_QUERY;
763 
764  List<HashMap<String, Object>> tempList = this.dbConnect(tempFilePath, formHistoryQuery);
765  logger.log(Level.INFO, "{0} - Now getting history from {1} with {2} artifacts identified.", new Object[]{moduleName, tempFilePath, tempList.size()}); //NON-NLS
766  for (HashMap<String, Object> result : tempList) {
767  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
768 
769  String fieldName = ((result.get("fieldname").toString() != null) ? result.get("fieldname").toString() : "");
770  // filter out unuseful values
771  if (excludedFieldNames.contains(fieldName.toLowerCase())) {
772  continue;
773  }
774 
775  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
776  RecentActivityExtracterModuleFactory.getModuleName(),
777  fieldName)); //NON-NLS
778 
779  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
780  RecentActivityExtracterModuleFactory.getModuleName(),
781  ((result.get("value").toString() != null) ? result.get("value").toString() : ""))); //NON-NLS
782 
783  // Newer versions of firefox have additional columns
784  if (isFirefoxV64) {
785  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
786  RecentActivityExtracterModuleFactory.getModuleName(),
787  (Long.valueOf(result.get("firstUsed").toString()) / 1000000))); //NON-NLS
788 
789  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
790  RecentActivityExtracterModuleFactory.getModuleName(),
791  (Long.valueOf(result.get("lastUsed").toString()) / 1000000))); //NON-NLS
792 
793  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
794  RecentActivityExtracterModuleFactory.getModuleName(),
795  (Integer.valueOf(result.get("timesUsed").toString())))); //NON-NLS
796 
797  }
798  // Add artifact
799  BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_FORM_AUTOFILL, formHistoryFile, bbattributes);
800  if (bbart != null) {
801  this.indexArtifact(bbart);
802  bbartifacts.add(bbart);
803  }
804  }
805  ++j;
806  dbFile.delete();
807  }
808 
809  services.fireModuleDataEvent(new ModuleDataEvent(
810  NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
811  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_FORM_AUTOFILL, bbartifacts));
812  }
813 
814 
820  private void getAutofillProfiles() {
821  FileManager fileManager = currentCase.getServices().getFileManager();
822  List<AbstractFile> autofillProfilesFiles;
823  try {
824  autofillProfilesFiles = fileManager.findFiles(dataSource, "autofill-profiles.json", "Firefox"); //NON-NLS
825  } catch (TskCoreException ex) {
826  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errGettingFiles");
827  logger.log(Level.SEVERE, msg, ex);
828  this.addErrorMessage(this.getName() + ": " + msg);
829  return;
830  }
831 
832  if (autofillProfilesFiles.isEmpty()) {
833  logger.log(Level.INFO, "Didn't find any Firefox Autofill Profiles files."); //NON-NLS
834  return;
835  }
836 
837  dataFound = true;
838  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
839  int j = 0;
840 
841  while (j < autofillProfilesFiles.size()) {
842  AbstractFile profileFile = autofillProfilesFiles.get(j++);
843  if (profileFile.getSize() == 0) {
844  continue;
845  }
846  String temps = RAImageIngestModule.getRATempPath(currentCase, "Firefox") + File.separator + profileFile.getName() + j + ".json"; //NON-NLS
847  try {
848  ContentUtils.writeToFile(profileFile, new File(temps), context::dataSourceIngestIsCancelled);
849  } catch (ReadContentInputStreamException ex) {
850  logger.log(Level.WARNING, String.format("Error reading Firefox Autofill profiles artifacts file '%s' (id=%d).",
851  profileFile.getName(), profileFile.getId()), ex); //NON-NLS
852  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile",
853  this.getName(), profileFile.getName()));
854  continue;
855  } catch (IOException ex) {
856  logger.log(Level.SEVERE, String.format("Error writing temp file '%s' for Firefox Autofill profiles file '%s' (id=%d).",
857  temps, profileFile.getName(), profileFile.getId()), ex); //NON-NLS
858  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile",
859  this.getName(), profileFile.getName()));
860  continue;
861  }
862 
863  logger.log(Level.INFO, "{0}- Now getting Bookmarks from {1}", new Object[]{moduleName, temps}); //NON-NLS
864  File dbFile = new File(temps);
865  if (context.dataSourceIngestIsCancelled()) {
866  dbFile.delete();
867  break;
868  }
869 
870  FileReader tempReader;
871  try {
872  tempReader = new FileReader(temps);
873  } catch (FileNotFoundException ex) {
874  logger.log(Level.SEVERE, "Error while trying to read the Autofill profiles json file for Firefox.", ex); //NON-NLS
875  this.addErrorMessage(
876  NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzeFile", this.getName(),
877  profileFile.getName()));
878  continue;
879  }
880 
881  final JsonParser parser = new JsonParser();
882 
883  JsonObject jsonRootObject;
884  JsonArray jAddressesArray;
885 
886  try {
887  jsonRootObject = parser.parse(tempReader).getAsJsonObject();
888  jAddressesArray = jsonRootObject.getAsJsonArray("addresses"); //NON-NLS
889  } catch (JsonIOException | JsonSyntaxException | IllegalStateException ex) {
890  logger.log(Level.WARNING, "Error parsing Json for Firefox Autofill profiles.", ex); //NON-NLS
891  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile3",
892  this.getName(), profileFile.getName()));
893  continue;
894  }
895 
896  for (JsonElement result : jAddressesArray) {
897  JsonObject address = result.getAsJsonObject();
898  if (address == null) {
899  continue;
900  }
901 
902  JsonElement nameEl = address.get("name"); //NON-NLS
903  String name = (nameEl != null) ? nameEl.getAsString() : "";
904 
905  JsonElement emailEl = address.get("email"); //NON-NLS
906  String email = (emailEl != null) ? emailEl.getAsString() : "";
907 
908  JsonElement telEl = address.get("tel"); //NON-NLS
909  String tel = (telEl != null) ? telEl.getAsString() : "";
910  JsonElement telCountryCodeEl = address.get("tel-country-code"); //NON-NLS
911  String telCountryCode = (telCountryCodeEl != null) ? telCountryCodeEl.getAsString() : "";
912  JsonElement telNationalEl = address.get("tel-national"); //NON-NLS
913  String telNational = (telNationalEl != null) ? telNationalEl.getAsString() : "";
914 
915  String phoneNumber = makeTelNumber(tel, telCountryCode, telNational);
916 
917  JsonElement createdEl = address.get("timeCreated"); //NON-NLS
918  Long datetimeCreated = (createdEl != null) ? createdEl.getAsLong()/1000 : Long.valueOf(0);
919  JsonElement lastusedEl = address.get("timeLastUsed"); //NON-NLS
920  Long datetimeLastUsed = (lastusedEl != null) ? lastusedEl.getAsLong()/1000 : Long.valueOf(0);
921  JsonElement timesUsedEl = address.get("timesUsed"); //NON-NLS
922  Integer timesUsed = (timesUsedEl != null) ? timesUsedEl.getAsShort() : Integer.valueOf(0);
923 
924  JsonElement addressLine1El = address.get("address-line1"); //NON-NLS
925  String addressLine1 = (addressLine1El != null) ? addressLine1El.getAsString() : "";
926  JsonElement addressLine2El = address.get("address-line2"); //NON-NLS
927  String addressLine2 = (addressLine2El != null) ? addressLine2El.getAsString() : "";
928  JsonElement addressLine3El = address.get("address-line3"); //NON-NLS
929  String addressLine3 = (addressLine3El != null) ? addressLine3El.getAsString() : "";
930 
931  JsonElement postalCodeEl = address.get("postal-code"); //NON-NLS
932  String postalCode = (postalCodeEl != null) ? postalCodeEl.getAsString() : "";
933  JsonElement countryEl = address.get("country"); //NON-NLS
934  String country = (countryEl != null) ? countryEl.getAsString() : "";
935 
936  String mailingAddress = makeFullAddress(addressLine1, addressLine2, addressLine3, postalCode, country );
937 
938  try {
939  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
940  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME_PERSON,
941  RecentActivityExtracterModuleFactory.getModuleName(),
942  name)); //NON-NLS
943 
944  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL,
945  RecentActivityExtracterModuleFactory.getModuleName(),
946  email)); //NON-NLS
947 
948  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER,
949  RecentActivityExtracterModuleFactory.getModuleName(),
950  phoneNumber)); //NON-NLS
951 
952  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LOCATION,
953  RecentActivityExtracterModuleFactory.getModuleName(),
954  mailingAddress)); //NON-NLS
955 
956  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
957  RecentActivityExtracterModuleFactory.getModuleName(),
958  datetimeCreated)); //NON-NLS
959 
960  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
961  RecentActivityExtracterModuleFactory.getModuleName(),
962  datetimeLastUsed)); //NON-NLS
963 
964  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
965  RecentActivityExtracterModuleFactory.getModuleName(),
966  timesUsed)); //NON-NLS
967 
968  BlackboardArtifact bbart = profileFile.newArtifact(ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS);
969 
970  // index the artifact for keyword search
971  if (bbart != null) {
972  bbart.addAttributes(bbattributes);
973  this.indexArtifact(bbart);
974  bbartifacts.add(bbart);
975  }
976 
977  // If an email address is found, create an account instance for it
978  if (email != null && !email.isEmpty()) {
979  try {
980  Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.EMAIL, email, NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), profileFile);
981  } catch (NoCurrentCaseException | TskCoreException ex) {
982  logger.log(Level.SEVERE, String.format("Error creating email account instance for '%s' from Firefox profiles file '%s' .",
983  email, profileFile.getName()), ex); //NON-NLS
984  }
985  }
986 
987  // If a phone number is found, create an account instance for it
988  if (phoneNumber != null && !phoneNumber.isEmpty()) {
989  try {
990  Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.PHONE, phoneNumber, NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), profileFile);
991  } catch (NoCurrentCaseException | TskCoreException ex) {
992  logger.log(Level.SEVERE, String.format("Error creating phone number account instance for '%s' from Chrome profiles file '%s' .",
993  phoneNumber, profileFile.getName()), ex); //NON-NLS
994  }
995  }
996 
997  } catch (TskCoreException ex) {
998  logger.log(Level.SEVERE, "Error while trying to insert Firefox Autofill profile artifact{0}", ex); //NON-NLS
999  this.addErrorMessage(
1000  NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile4",
1001  this.getName(), profileFile.getName()));
1002  }
1003  }
1004  dbFile.delete();
1005  }
1006 
1007  IngestServices.getInstance().fireModuleDataEvent(new ModuleDataEvent(
1008  NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
1009  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS, bbartifacts));
1010  }
1011 
1020  private String extractDomain(String url) {
1021  if (url == null || url.isEmpty()) {
1022  return url;
1023  }
1024 
1025  if (url.toLowerCase().startsWith(PLACE_URL_PREFIX)) {
1026  /*
1027  * Ignore URLs that begin with the matched text.
1028  */
1029  return null;
1030  }
1031 
1032  return NetworkUtils.extractDomain(url);
1033  }
1034 
1035 
1045  private String makeTelNumber(String tel, String telCountryCode, String telNational) {
1046 
1047  if (tel != null && !tel.isEmpty()) {
1048  return tel;
1049  }
1050 
1051  if ((telCountryCode != null && !telCountryCode.isEmpty()) &&
1052  (telNational != null && !telNational.isEmpty())) {
1053  return telCountryCode + telNational;
1054  }
1055 
1056  return "";
1057  }
1058 
1070  private String makeFullAddress(String addressLine1, String addressLine2, String addressLine3, String postalCode, String country ) {
1071  String fullAddress = "";
1072  fullAddress = appendAddressField(fullAddress, addressLine1 );
1073  fullAddress = appendAddressField(fullAddress, addressLine2 );
1074  fullAddress = appendAddressField(fullAddress, addressLine3 );
1075  fullAddress = appendAddressField(fullAddress, postalCode );
1076  fullAddress = appendAddressField(fullAddress, country );
1077 
1078  return fullAddress;
1079  }
1080 
1089  private String appendAddressField(String address, String addressfield) {
1090 
1091  String updatedAddress = address;
1092  if (addressfield != null && !addressfield.isEmpty()) {
1093  if (!updatedAddress.isEmpty()) {
1094  updatedAddress += ", ";
1095  }
1096  updatedAddress += addressfield;
1097  }
1098 
1099  return updatedAddress;
1100  }
1101 
1102 }

Copyright © 2012-2018 Basis Technology. Generated on: Fri Mar 22 2019
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.