Autopsy  4.11.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 
157  if (context.dataSourceIngestIsCancelled()) {
158  return;
159  }
160 
161  if (historyFile.getSize() == 0) {
162  continue;
163  }
164 
165  String fileName = historyFile.getName();
166  String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
167  try {
168  ContentUtils.writeToFile(historyFile, new File(temps), context::dataSourceIngestIsCancelled);
169  } catch (ReadContentInputStreamException ex) {
170  logger.log(Level.WARNING, String.format("Error reading Firefox web history artifacts file '%s' (id=%d).",
171  fileName, historyFile.getId()), ex); //NON-NLS
172  this.addErrorMessage(
173  NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
174  fileName));
175  continue;
176  } catch (IOException ex) {
177  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Firefox web history artifacts file '%s' (id=%d).",
178  temps, fileName, historyFile.getId()), ex); //NON-NLS
179  this.addErrorMessage(
180  NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
181  fileName));
182  continue;
183  }
184  File dbFile = new File(temps);
185  if (context.dataSourceIngestIsCancelled()) {
186  dbFile.delete();
187  break;
188  }
189  List<HashMap<String, Object>> tempList = this.dbConnect(temps, HISTORY_QUERY);
190  logger.log(Level.INFO, "{0} - Now getting history from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
191  for (HashMap<String, Object> result : tempList) {
192 
193  if (context.dataSourceIngestIsCancelled()) {
194  return;
195  }
196 
197  String url = result.get("url").toString();
198 
199  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
200  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
201  RecentActivityExtracterModuleFactory.getModuleName(),
202  ((url != null) ? url : ""))); //NON-NLS
203  //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("url").toString() != null) ? EscapeUtil.decodeURL(result.get("url").toString()) : "")));
204  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
205  RecentActivityExtracterModuleFactory.getModuleName(),
206  (Long.valueOf(result.get("visit_date").toString())))); //NON-NLS
207  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER,
208  RecentActivityExtracterModuleFactory.getModuleName(),
209  ((result.get("ref").toString() != null) ? result.get("ref").toString() : ""))); //NON-NLS
210  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
211  RecentActivityExtracterModuleFactory.getModuleName(),
212  ((result.get("title").toString() != null) ? result.get("title").toString() : ""))); //NON-NLS
213  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
214  RecentActivityExtracterModuleFactory.getModuleName(),
215  NbBundle.getMessage(this.getClass(), "Firefox.moduleName")));
216  String domain = extractDomain(url);
217  if (domain != null && domain.isEmpty() == false) {
218  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
219  RecentActivityExtracterModuleFactory.getModuleName(), domain)); //NON-NLS
220 
221  }
222  BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY, historyFile, bbattributes);
223  if (bbart != null) {
224  bbartifacts.add(bbart);
225  }
226  }
227  ++j;
228  dbFile.delete();
229  }
230 
231  services.fireModuleDataEvent(new ModuleDataEvent(
232  NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
233  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, bbartifacts));
234  }
235 
239  private void getBookmark() {
240 
241  FileManager fileManager = currentCase.getServices().getFileManager();
242  List<AbstractFile> bookmarkFiles;
243  try {
244  bookmarkFiles = fileManager.findFiles(dataSource, "places.sqlite", "Firefox"); //NON-NLS
245  } catch (TskCoreException ex) {
246  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getBookmark.errMsg.errFetchFiles");
247  logger.log(Level.WARNING, msg);
248  this.addErrorMessage(this.getName() + ": " + msg);
249  return;
250  }
251 
252  if (bookmarkFiles.isEmpty()) {
253  logger.log(Level.INFO, "Didn't find any firefox bookmark files."); //NON-NLS
254  return;
255  }
256 
257  dataFound = true;
258  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
259  int j = 0;
260  for (AbstractFile bookmarkFile : bookmarkFiles) {
261  if (bookmarkFile.getSize() == 0) {
262  continue;
263  }
264  String fileName = bookmarkFile.getName();
265  String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
266  try {
267  ContentUtils.writeToFile(bookmarkFile, new File(temps), context::dataSourceIngestIsCancelled);
268  } catch (ReadContentInputStreamException ex) {
269  logger.log(Level.WARNING, String.format("Error reading Firefox bookmark artifacts file '%s' (id=%d).",
270  fileName, bookmarkFile.getId()), ex); //NON-NLS
271  this.addErrorMessage(
272  NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
273  fileName));
274  continue;
275  } catch (IOException ex) {
276  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Firefox bookmark artifacts file '%s' (id=%d).",
277  temps, fileName, bookmarkFile.getId()), ex); //NON-NLS
278  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getBookmark.errMsg.errAnalyzeFile",
279  this.getName(), fileName));
280  continue;
281  }
282  File dbFile = new File(temps);
283  if (context.dataSourceIngestIsCancelled()) {
284  dbFile.delete();
285  break;
286  }
287  List<HashMap<String, Object>> tempList = this.dbConnect(temps, BOOKMARK_QUERY);
288  logger.log(Level.INFO, "{0} - Now getting bookmarks from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
289  for (HashMap<String, Object> result : tempList) {
290 
291  if (context.dataSourceIngestIsCancelled()) {
292  break;
293  }
294 
295  String url = result.get("url").toString();
296 
297  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
298  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
299  RecentActivityExtracterModuleFactory.getModuleName(),
300  ((url != null) ? url : ""))); //NON-NLS
301  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
302  RecentActivityExtracterModuleFactory.getModuleName(),
303  ((result.get("title").toString() != null) ? result.get("title").toString() : ""))); //NON-NLS
304  if (Long.valueOf(result.get("dateAdded").toString()) > 0) { //NON-NLS
305  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
306  RecentActivityExtracterModuleFactory.getModuleName(),
307  (Long.valueOf(result.get("dateAdded").toString())))); //NON-NLS
308  }
309  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
310  RecentActivityExtracterModuleFactory.getModuleName(),
311  NbBundle.getMessage(this.getClass(), "Firefox.moduleName")));
312  String domain = extractDomain(url);
313  if (domain != null && domain.isEmpty() == false) {
314  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
315  RecentActivityExtracterModuleFactory.getModuleName(), domain)); //NON-NLS
316  }
317 
318  BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK, bookmarkFile, bbattributes);
319  if (bbart != null) {
320  bbartifacts.add(bbart);
321  }
322  }
323  ++j;
324  dbFile.delete();
325  }
326 
327  services.fireModuleDataEvent(new ModuleDataEvent(
328  NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
329  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK, bbartifacts));
330  }
331 
335  private void getCookie() {
336  FileManager fileManager = currentCase.getServices().getFileManager();
337  List<AbstractFile> cookiesFiles;
338  try {
339  cookiesFiles = fileManager.findFiles(dataSource, "cookies.sqlite", "Firefox"); //NON-NLS
340  } catch (TskCoreException ex) {
341  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getCookie.errMsg.errFetchFile");
342  logger.log(Level.WARNING, msg);
343  this.addErrorMessage(this.getName() + ": " + msg);
344  return;
345  }
346 
347  if (cookiesFiles.isEmpty()) {
348  logger.log(Level.INFO, "Didn't find any Firefox cookie files."); //NON-NLS
349  return;
350  }
351 
352  dataFound = true;
353  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
354  int j = 0;
355  for (AbstractFile cookiesFile : cookiesFiles) {
356  if (cookiesFile.getSize() == 0) {
357  continue;
358  }
359  String fileName = cookiesFile.getName();
360  String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
361  try {
362  ContentUtils.writeToFile(cookiesFile, new File(temps), context::dataSourceIngestIsCancelled);
363  } catch (ReadContentInputStreamException ex) {
364  logger.log(Level.WARNING, String.format("Error reading Firefox cookie artifacts file '%s' (id=%d).",
365  fileName, cookiesFile.getId()), ex); //NON-NLS
366  this.addErrorMessage(
367  NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
368  fileName));
369  continue;
370  } catch (IOException ex) {
371  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Firefox cookie artifacts file '%s' (id=%d).",
372  temps, fileName, cookiesFile.getId()), ex); //NON-NLS
373  this.addErrorMessage(
374  NbBundle.getMessage(this.getClass(), "Firefox.getCookie.errMsg.errAnalyzeFile", this.getName(),
375  fileName));
376  continue;
377  }
378  File dbFile = new File(temps);
379  if (context.dataSourceIngestIsCancelled()) {
380  dbFile.delete();
381  break;
382  }
383  boolean checkColumn = Util.checkColumn("creationTime", "moz_cookies", temps); //NON-NLS
384  String query;
385  if (checkColumn) {
386  query = COOKIE_QUERY;
387  } else {
388  query = COOKIE_QUERY_V3;
389  }
390 
391  List<HashMap<String, Object>> tempList = this.dbConnect(temps, query);
392  logger.log(Level.INFO, "{0} - Now getting cookies from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
393  for (HashMap<String, Object> result : tempList) {
394 
395  if (context.dataSourceIngestIsCancelled()) {
396  break;
397  }
398 
399  String host = result.get("host").toString();
400 
401  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
402  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
403  RecentActivityExtracterModuleFactory.getModuleName(),
404  ((host != null) ? host : ""))); //NON-NLS
405  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME,
406  RecentActivityExtracterModuleFactory.getModuleName(),
407  (Long.valueOf(result.get("lastAccessed").toString())))); //NON-NLS
408  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
409  RecentActivityExtracterModuleFactory.getModuleName(),
410  ((result.get("name").toString() != null) ? result.get("name").toString() : ""))); //NON-NLS
411  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
412  RecentActivityExtracterModuleFactory.getModuleName(),
413  ((result.get("value").toString() != null) ? result.get("value").toString() : ""))); //NON-NLS
414  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
415  RecentActivityExtracterModuleFactory.getModuleName(),
416  NbBundle.getMessage(this.getClass(), "Firefox.moduleName")));
417 
418  if (checkColumn == true) {
419  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
420  RecentActivityExtracterModuleFactory.getModuleName(),
421  (Long.valueOf(result.get("creationTime").toString())))); //NON-NLS
422  }
423  String domain = extractDomain(host);
424  if (domain != null && domain.isEmpty() == false) {
425  domain = domain.replaceFirst("^\\.+(?!$)", "");
426  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
427  RecentActivityExtracterModuleFactory.getModuleName(), domain));
428  }
429 
430  BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_COOKIE, cookiesFile, bbattributes);
431  if (bbart != null) {
432  bbartifacts.add(bbart);
433  }
434  }
435  ++j;
436  dbFile.delete();
437  }
438 
439  services.fireModuleDataEvent(new ModuleDataEvent(
440  NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
441  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE, bbartifacts));
442  }
443 
447  private void getDownload() {
448  getDownloadPreVersion24();
449  getDownloadVersion24();
450  }
451 
457  private void getDownloadPreVersion24() {
458 
459  FileManager fileManager = currentCase.getServices().getFileManager();
460  List<AbstractFile> downloadsFiles;
461  try {
462  downloadsFiles = fileManager.findFiles(dataSource, "downloads.sqlite", "Firefox"); //NON-NLS
463  } catch (TskCoreException ex) {
464  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getDlPre24.errMsg.errFetchFiles");
465  logger.log(Level.WARNING, msg);
466  this.addErrorMessage(this.getName() + ": " + msg);
467  return;
468  }
469 
470  if (downloadsFiles.isEmpty()) {
471  logger.log(Level.INFO, "Didn't find any pre-version-24.0 Firefox download files."); //NON-NLS
472  return;
473  }
474 
475  dataFound = true;
476  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
477  int j = 0;
478  for (AbstractFile downloadsFile : downloadsFiles) {
479  if (downloadsFile.getSize() == 0) {
480  continue;
481  }
482  String fileName = downloadsFile.getName();
483  String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
484  int errors = 0;
485  try {
486  ContentUtils.writeToFile(downloadsFile, new File(temps), context::dataSourceIngestIsCancelled);
487  } catch (ReadContentInputStreamException ex) {
488  logger.log(Level.WARNING, String.format("Error reading Firefox download artifacts file '%s' (id=%d).",
489  fileName, downloadsFile.getId()), ex); //NON-NLS
490  this.addErrorMessage(
491  NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
492  fileName));
493  continue;
494  } catch (IOException ex) {
495  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Firefox download artifacts file '%s' (id=%d).",
496  temps, fileName, downloadsFile.getId()), ex); //NON-NLS
497  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getDlPre24.errMsg.errAnalyzeFiles",
498  this.getName(), fileName));
499  continue;
500  }
501  File dbFile = new File(temps);
502  if (context.dataSourceIngestIsCancelled()) {
503  dbFile.delete();
504  break;
505  }
506 
507  List<HashMap<String, Object>> tempList = this.dbConnect(temps, DOWNLOAD_QUERY);
508  logger.log(Level.INFO, "{0}- Now getting downloads from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
509  for (HashMap<String, Object> result : tempList) {
510 
511  if (context.dataSourceIngestIsCancelled()) {
512  break;
513  }
514 
515  String source = result.get("source").toString();
516 
517  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
518 
519  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
520  RecentActivityExtracterModuleFactory.getModuleName(),
521  source)); //NON-NLS
522  //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("source").toString() != null) ? EscapeUtil.decodeURL(result.get("source").toString()) : "")));
523  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
524  RecentActivityExtracterModuleFactory.getModuleName(),
525  (Long.valueOf(result.get("startTime").toString())))); //NON-NLS
526 
527  String target = result.get("target").toString(); //NON-NLS
528  String downloadedFilePath = "";
529  if (target != null) {
530  try {
531  downloadedFilePath = URLDecoder.decode(target.replaceAll("file:///", ""), "UTF-8"); //NON-NLS
532  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
533  RecentActivityExtracterModuleFactory.getModuleName(),
534  downloadedFilePath));
535  long pathID = Util.findID(dataSource, downloadedFilePath);
536  if (pathID != -1) {
537  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
538  RecentActivityExtracterModuleFactory.getModuleName(),
539  pathID));
540  }
541  } catch (UnsupportedEncodingException ex) {
542  logger.log(Level.SEVERE, "Error decoding Firefox download URL in " + temps, ex); //NON-NLS
543  errors++;
544  }
545  }
546 
547  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
548  RecentActivityExtracterModuleFactory.getModuleName(),
549  NbBundle.getMessage(this.getClass(), "Firefox.moduleName")));
550  String domain = extractDomain(source);
551  if (domain != null && domain.isEmpty() == false) {
552  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
553  RecentActivityExtracterModuleFactory.getModuleName(),
554  domain)); //NON-NLS
555  }
556 
557  BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
558  if (bbart != null) {
559  bbartifacts.add(bbart);
560  }
561 
562  // find the downloaded file and create a TSK_DOWNLOAD_SOURCE for it.
563  try {
564  for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) {
565  BlackboardArtifact downloadSourceArt = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE);
566  downloadSourceArt.addAttributes(createDownloadSourceAttributes(source));
567  bbartifacts.add(downloadSourceArt);
568  break;
569  }
570  } catch (TskCoreException ex) {
571  logger.log(Level.SEVERE, String.format("Error creating download source artifact for file '%s'",
572  downloadedFilePath), ex); //NON-NLS
573  }
574  }
575  if (errors > 0) {
576  this.addErrorMessage(
577  NbBundle.getMessage(this.getClass(), "Firefox.getDlPre24.errMsg.errParsingArtifacts",
578  this.getName(), errors));
579  }
580  j++;
581  dbFile.delete();
582  break;
583  }
584 
585  services.fireModuleDataEvent(new ModuleDataEvent(
586  NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
587  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, bbartifacts));
588  }
589 
595  private void getDownloadVersion24() {
596  FileManager fileManager = currentCase.getServices().getFileManager();
597  List<AbstractFile> downloadsFiles;
598  try {
599  downloadsFiles = fileManager.findFiles(dataSource, "places.sqlite", "Firefox"); //NON-NLS
600  } catch (TskCoreException ex) {
601  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getDlV24.errMsg.errFetchFiles");
602  logger.log(Level.WARNING, msg);
603  this.addErrorMessage(this.getName() + ": " + msg);
604  return;
605  }
606 
607  if (downloadsFiles.isEmpty()) {
608  logger.log(Level.INFO, "Didn't find any version-24.0 Firefox download files."); //NON-NLS
609  return;
610  }
611 
612  dataFound = true;
613  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
614  int j = 0;
615  for (AbstractFile downloadsFile : downloadsFiles) {
616  if (downloadsFile.getSize() == 0) {
617  continue;
618  }
619  String fileName = downloadsFile.getName();
620  String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + "-downloads" + j + ".db"; //NON-NLS
621  int errors = 0;
622  try {
623  ContentUtils.writeToFile(downloadsFile, new File(temps), context::dataSourceIngestIsCancelled);
624  } catch (ReadContentInputStreamException ex) {
625  logger.log(Level.WARNING, String.format("Error reading Firefox download artifacts file '%s' (id=%d).",
626  fileName, downloadsFile.getId()), ex); //NON-NLS
627  this.addErrorMessage(
628  NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
629  fileName));
630  continue;
631  } catch (IOException ex) {
632  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Firefox download artifacts file '%s' (id=%d).",
633  temps, fileName, downloadsFile.getId()), ex); //NON-NLS
634  this.addErrorMessage(
635  NbBundle.getMessage(this.getClass(), "Firefox.getDlV24.errMsg.errAnalyzeFile", this.getName(),
636  fileName));
637  continue;
638  }
639  File dbFile = new File(temps);
640  if (context.dataSourceIngestIsCancelled()) {
641  dbFile.delete();
642  break;
643  }
644 
645  List<HashMap<String, Object>> tempList = this.dbConnect(temps, DOWNLOAD_QUERY_V24);
646 
647  logger.log(Level.INFO, "{0} - Now getting downloads from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
648  for (HashMap<String, Object> result : tempList) {
649 
650  if (context.dataSourceIngestIsCancelled()) {
651  break;
652  }
653 
654  String url = result.get("url").toString();
655 
656  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
657 
658  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
659  RecentActivityExtracterModuleFactory.getModuleName(),
660  url)); //NON-NLS
661  //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("source").toString() != null) ? EscapeUtil.decodeURL(result.get("source").toString()) : "")));
662  //TODO Revisit usage of deprecated constructor as per TSK-583
663  //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "RecentActivity", "Last Visited", (Long.valueOf(result.get("startTime").toString()))));
664 
665  String target = result.get("target").toString(); //NON-NLS
666  String downloadedFilePath = "";
667  if (target != null) {
668  try {
669  downloadedFilePath = URLDecoder.decode(target.replaceAll("file:///", ""), "UTF-8"); //NON-NLS
670  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
671  RecentActivityExtracterModuleFactory.getModuleName(),
672  downloadedFilePath));
673  long pathID = Util.findID(dataSource, downloadedFilePath);
674  if (pathID != -1) {
675  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
676  RecentActivityExtracterModuleFactory.getModuleName(),
677  pathID));
678  }
679  } catch (UnsupportedEncodingException ex) {
680  logger.log(Level.SEVERE, "Error decoding Firefox download URL in " + temps, ex); //NON-NLS
681  errors++;
682  }
683  }
684  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
685  RecentActivityExtracterModuleFactory.getModuleName(),
686  Long.valueOf(result.get("lastModified").toString()))); //NON-NLS
687  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
688  RecentActivityExtracterModuleFactory.getModuleName(),
689  NbBundle.getMessage(this.getClass(), "Firefox.moduleName")));
690  String domain = extractDomain(url);
691  if (domain != null && domain.isEmpty() == false) {
692  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
693  RecentActivityExtracterModuleFactory.getModuleName(), domain)); //NON-NLS
694  }
695 
696  BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
697  if (bbart != null) {
698  bbartifacts.add(bbart);
699  }
700 
701  // find the downloaded file and create a TSK_DOWNLOAD_SOURCE for it.
702  try {
703  for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) {
704  BlackboardArtifact downloadSourceArt = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE);
705  downloadSourceArt.addAttributes(createDownloadSourceAttributes(url));
706  bbartifacts.add(downloadSourceArt);
707  break;
708  }
709  } catch (TskCoreException ex) {
710  logger.log(Level.SEVERE, String.format("Error creating download source artifact for file '%s'",
711  downloadedFilePath), ex); //NON-NLS
712  }
713  }
714  if (errors > 0) {
715  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getDlV24.errMsg.errParsingArtifacts",
716  this.getName(), errors));
717  }
718  j++;
719  dbFile.delete();
720  break;
721  }
722 
723  services.fireModuleDataEvent(new ModuleDataEvent(
724  NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
725  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, bbartifacts));
726  }
727 
732  private void getFormsHistory() {
733  FileManager fileManager = currentCase.getServices().getFileManager();
734  List<AbstractFile> formHistoryFiles;
735 
736  // Some fields are just noisy and can me excluded
737  Set<String> excludedFieldNames = new HashSet<>(Arrays.asList(
738  "it", // some kind of timestamp
739  "ts" // some kind of timestamp
740  ));
741 
742  try {
743  formHistoryFiles = fileManager.findFiles(dataSource, "formhistory.sqlite", "Firefox"); //NON-NLS
744  } catch (TskCoreException ex) {
745  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.errFetchingFiles");
746  logger.log(Level.WARNING, msg);
747  this.addErrorMessage(this.getName() + ": " + msg);
748  return;
749  }
750 
751  if (formHistoryFiles.isEmpty()) {
752  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.noFilesFound");
753  logger.log(Level.INFO, msg);
754  return;
755  }
756 
757  dataFound = true;
758  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
759  int j = 0;
760  for (AbstractFile formHistoryFile : formHistoryFiles) {
761  if (formHistoryFile.getSize() == 0) {
762  continue;
763  }
764 
765  String fileName = formHistoryFile.getName();
766  String tempFilePath = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
767  try {
768  ContentUtils.writeToFile(formHistoryFile, new File(tempFilePath), context::dataSourceIngestIsCancelled);
769  } catch (ReadContentInputStreamException ex) {
770  logger.log(Level.WARNING, String.format("Error reading Firefox web history artifacts file '%s' (id=%d).",
771  fileName, formHistoryFile.getId()), ex); //NON-NLS
772  this.addErrorMessage(
773  NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.errAnalyzeFile", this.getName(),
774  fileName));
775  continue;
776  } catch (IOException ex) {
777  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Firefox web history artifacts file '%s' (id=%d).",
778  tempFilePath, fileName, formHistoryFile.getId()), ex); //NON-NLS
779  this.addErrorMessage(
780  NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.errAnalyzeFile", this.getName(),
781  fileName));
782  continue;
783  }
784  File dbFile = new File(tempFilePath);
785  if (context.dataSourceIngestIsCancelled()) {
786  dbFile.delete();
787  break;
788  }
789 
790  // The table schema is a little different in newer version of Firefox
791  boolean isFirefoxV64 = Util.checkColumn("timesUsed", "moz_formhistory", tempFilePath);
792  String formHistoryQuery = (isFirefoxV64) ? FORMHISTORY_QUERY_V64 : FORMHISTORY_QUERY;
793 
794  List<HashMap<String, Object>> tempList = this.dbConnect(tempFilePath, formHistoryQuery);
795  logger.log(Level.INFO, "{0} - Now getting history from {1} with {2} artifacts identified.", new Object[]{moduleName, tempFilePath, tempList.size()}); //NON-NLS
796  for (HashMap<String, Object> result : tempList) {
797 
798  if (context.dataSourceIngestIsCancelled()) {
799  break;
800  }
801 
802  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
803 
804  String fieldName = ((result.get("fieldname").toString() != null) ? result.get("fieldname").toString() : "");
805  // filter out unuseful values
806  if (excludedFieldNames.contains(fieldName.toLowerCase())) {
807  continue;
808  }
809 
810  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
811  RecentActivityExtracterModuleFactory.getModuleName(),
812  fieldName)); //NON-NLS
813 
814  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
815  RecentActivityExtracterModuleFactory.getModuleName(),
816  ((result.get("value").toString() != null) ? result.get("value").toString() : ""))); //NON-NLS
817 
818  // Newer versions of firefox have additional columns
819  if (isFirefoxV64) {
820  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
821  RecentActivityExtracterModuleFactory.getModuleName(),
822  (Long.valueOf(result.get("firstUsed").toString()) / 1000000))); //NON-NLS
823 
824  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
825  RecentActivityExtracterModuleFactory.getModuleName(),
826  (Long.valueOf(result.get("lastUsed").toString()) / 1000000))); //NON-NLS
827 
828  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
829  RecentActivityExtracterModuleFactory.getModuleName(),
830  (Integer.valueOf(result.get("timesUsed").toString())))); //NON-NLS
831 
832  }
833  // Add artifact
834  BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_FORM_AUTOFILL, formHistoryFile, bbattributes);
835  if (bbart != null) {
836  this.indexArtifact(bbart);
837  bbartifacts.add(bbart);
838  }
839  }
840  ++j;
841  dbFile.delete();
842  }
843 
844  services.fireModuleDataEvent(new ModuleDataEvent(
845  NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
846  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_FORM_AUTOFILL, bbartifacts));
847  }
848 
849 
855  private void getAutofillProfiles() {
856  FileManager fileManager = currentCase.getServices().getFileManager();
857  List<AbstractFile> autofillProfilesFiles;
858  try {
859  autofillProfilesFiles = fileManager.findFiles(dataSource, "autofill-profiles.json", "Firefox"); //NON-NLS
860  } catch (TskCoreException ex) {
861  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errGettingFiles");
862  logger.log(Level.SEVERE, msg, ex);
863  this.addErrorMessage(this.getName() + ": " + msg);
864  return;
865  }
866 
867  if (autofillProfilesFiles.isEmpty()) {
868  logger.log(Level.INFO, "Didn't find any Firefox Autofill Profiles files."); //NON-NLS
869  return;
870  }
871 
872  dataFound = true;
873  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
874  int j = 0;
875 
876  while (j < autofillProfilesFiles.size()) {
877  AbstractFile profileFile = autofillProfilesFiles.get(j++);
878  if (profileFile.getSize() == 0) {
879  continue;
880  }
881  String temps = RAImageIngestModule.getRATempPath(currentCase, "Firefox") + File.separator + profileFile.getName() + j + ".json"; //NON-NLS
882  try {
883  ContentUtils.writeToFile(profileFile, new File(temps), context::dataSourceIngestIsCancelled);
884  } catch (ReadContentInputStreamException ex) {
885  logger.log(Level.WARNING, String.format("Error reading Firefox Autofill profiles artifacts file '%s' (id=%d).",
886  profileFile.getName(), profileFile.getId()), ex); //NON-NLS
887  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile",
888  this.getName(), profileFile.getName()));
889  continue;
890  } catch (IOException ex) {
891  logger.log(Level.SEVERE, String.format("Error writing temp file '%s' for Firefox Autofill profiles file '%s' (id=%d).",
892  temps, profileFile.getName(), profileFile.getId()), ex); //NON-NLS
893  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile",
894  this.getName(), profileFile.getName()));
895  continue;
896  }
897 
898  logger.log(Level.INFO, "{0}- Now getting Bookmarks from {1}", new Object[]{moduleName, temps}); //NON-NLS
899  File dbFile = new File(temps);
900  if (context.dataSourceIngestIsCancelled()) {
901  dbFile.delete();
902  break;
903  }
904 
905  FileReader tempReader;
906  try {
907  tempReader = new FileReader(temps);
908  } catch (FileNotFoundException ex) {
909  logger.log(Level.SEVERE, "Error while trying to read the Autofill profiles json file for Firefox.", ex); //NON-NLS
910  this.addErrorMessage(
911  NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzeFile", this.getName(),
912  profileFile.getName()));
913  continue;
914  }
915 
916  final JsonParser parser = new JsonParser();
917 
918  JsonObject jsonRootObject;
919  JsonArray jAddressesArray;
920 
921  try {
922  jsonRootObject = parser.parse(tempReader).getAsJsonObject();
923  jAddressesArray = jsonRootObject.getAsJsonArray("addresses"); //NON-NLS
924  } catch (JsonIOException | JsonSyntaxException | IllegalStateException ex) {
925  logger.log(Level.WARNING, "Error parsing Json for Firefox Autofill profiles.", ex); //NON-NLS
926  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile3",
927  this.getName(), profileFile.getName()));
928  continue;
929  }
930 
931  for (JsonElement result : jAddressesArray) {
932  JsonObject address = result.getAsJsonObject();
933  if (address == null) {
934  continue;
935  }
936 
937  JsonElement nameEl = address.get("name"); //NON-NLS
938  String name = (nameEl != null) ? nameEl.getAsString() : "";
939 
940  JsonElement emailEl = address.get("email"); //NON-NLS
941  String email = (emailEl != null) ? emailEl.getAsString() : "";
942 
943  JsonElement telEl = address.get("tel"); //NON-NLS
944  String tel = (telEl != null) ? telEl.getAsString() : "";
945  JsonElement telCountryCodeEl = address.get("tel-country-code"); //NON-NLS
946  String telCountryCode = (telCountryCodeEl != null) ? telCountryCodeEl.getAsString() : "";
947  JsonElement telNationalEl = address.get("tel-national"); //NON-NLS
948  String telNational = (telNationalEl != null) ? telNationalEl.getAsString() : "";
949 
950  String phoneNumber = makeTelNumber(tel, telCountryCode, telNational);
951 
952  JsonElement createdEl = address.get("timeCreated"); //NON-NLS
953  Long datetimeCreated = (createdEl != null) ? createdEl.getAsLong()/1000 : Long.valueOf(0);
954  JsonElement lastusedEl = address.get("timeLastUsed"); //NON-NLS
955  Long datetimeLastUsed = (lastusedEl != null) ? lastusedEl.getAsLong()/1000 : Long.valueOf(0);
956  JsonElement timesUsedEl = address.get("timesUsed"); //NON-NLS
957  Integer timesUsed = (timesUsedEl != null) ? timesUsedEl.getAsShort() : Integer.valueOf(0);
958 
959  JsonElement addressLine1El = address.get("address-line1"); //NON-NLS
960  String addressLine1 = (addressLine1El != null) ? addressLine1El.getAsString() : "";
961  JsonElement addressLine2El = address.get("address-line2"); //NON-NLS
962  String addressLine2 = (addressLine2El != null) ? addressLine2El.getAsString() : "";
963  JsonElement addressLine3El = address.get("address-line3"); //NON-NLS
964  String addressLine3 = (addressLine3El != null) ? addressLine3El.getAsString() : "";
965 
966  JsonElement postalCodeEl = address.get("postal-code"); //NON-NLS
967  String postalCode = (postalCodeEl != null) ? postalCodeEl.getAsString() : "";
968  JsonElement countryEl = address.get("country"); //NON-NLS
969  String country = (countryEl != null) ? countryEl.getAsString() : "";
970 
971  String mailingAddress = makeFullAddress(addressLine1, addressLine2, addressLine3, postalCode, country );
972 
973  try {
974  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
975  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME_PERSON,
976  RecentActivityExtracterModuleFactory.getModuleName(),
977  name)); //NON-NLS
978 
979  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL,
980  RecentActivityExtracterModuleFactory.getModuleName(),
981  email)); //NON-NLS
982 
983  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER,
984  RecentActivityExtracterModuleFactory.getModuleName(),
985  phoneNumber)); //NON-NLS
986 
987  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LOCATION,
988  RecentActivityExtracterModuleFactory.getModuleName(),
989  mailingAddress)); //NON-NLS
990 
991  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
992  RecentActivityExtracterModuleFactory.getModuleName(),
993  datetimeCreated)); //NON-NLS
994 
995  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
996  RecentActivityExtracterModuleFactory.getModuleName(),
997  datetimeLastUsed)); //NON-NLS
998 
999  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
1000  RecentActivityExtracterModuleFactory.getModuleName(),
1001  timesUsed)); //NON-NLS
1002 
1003  BlackboardArtifact bbart = profileFile.newArtifact(ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS);
1004 
1005  // index the artifact for keyword search
1006  if (bbart != null) {
1007  bbart.addAttributes(bbattributes);
1008  this.indexArtifact(bbart);
1009  bbartifacts.add(bbart);
1010  }
1011 
1012  // If an email address is found, create an account instance for it
1013  if (email != null && !email.isEmpty()) {
1014  try {
1015  Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.EMAIL, email, NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), profileFile);
1016  } catch (NoCurrentCaseException | TskCoreException ex) {
1017  logger.log(Level.SEVERE, String.format("Error creating email account instance for '%s' from Firefox profiles file '%s' .",
1018  email, profileFile.getName()), ex); //NON-NLS
1019  }
1020  }
1021 
1022  // If a phone number is found, create an account instance for it
1023  if (phoneNumber != null && !phoneNumber.isEmpty()) {
1024  try {
1025  Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.PHONE, phoneNumber, NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), profileFile);
1026  } catch (NoCurrentCaseException | TskCoreException ex) {
1027  logger.log(Level.SEVERE, String.format("Error creating phone number account instance for '%s' from Chrome profiles file '%s' .",
1028  phoneNumber, profileFile.getName()), ex); //NON-NLS
1029  }
1030  }
1031 
1032  } catch (TskCoreException ex) {
1033  logger.log(Level.SEVERE, "Error while trying to insert Firefox Autofill profile artifact{0}", ex); //NON-NLS
1034  this.addErrorMessage(
1035  NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile4",
1036  this.getName(), profileFile.getName()));
1037  }
1038  }
1039  dbFile.delete();
1040  }
1041 
1042  IngestServices.getInstance().fireModuleDataEvent(new ModuleDataEvent(
1043  NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
1044  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS, bbartifacts));
1045  }
1046 
1055  private String extractDomain(String url) {
1056  if (url == null || url.isEmpty()) {
1057  return url;
1058  }
1059 
1060  if (url.toLowerCase().startsWith(PLACE_URL_PREFIX)) {
1061  /*
1062  * Ignore URLs that begin with the matched text.
1063  */
1064  return null;
1065  }
1066 
1067  return NetworkUtils.extractDomain(url);
1068  }
1069 
1070 
1080  private String makeTelNumber(String tel, String telCountryCode, String telNational) {
1081 
1082  if (tel != null && !tel.isEmpty()) {
1083  return tel;
1084  }
1085 
1086  if ((telCountryCode != null && !telCountryCode.isEmpty()) &&
1087  (telNational != null && !telNational.isEmpty())) {
1088  return telCountryCode + telNational;
1089  }
1090 
1091  return "";
1092  }
1093 
1105  private String makeFullAddress(String addressLine1, String addressLine2, String addressLine3, String postalCode, String country ) {
1106  String fullAddress = "";
1107  fullAddress = appendAddressField(fullAddress, addressLine1 );
1108  fullAddress = appendAddressField(fullAddress, addressLine2 );
1109  fullAddress = appendAddressField(fullAddress, addressLine3 );
1110  fullAddress = appendAddressField(fullAddress, postalCode );
1111  fullAddress = appendAddressField(fullAddress, country );
1112 
1113  return fullAddress;
1114  }
1115 
1124  private String appendAddressField(String address, String addressfield) {
1125 
1126  String updatedAddress = address;
1127  if (addressfield != null && !addressfield.isEmpty()) {
1128  if (!updatedAddress.isEmpty()) {
1129  updatedAddress += ", ";
1130  }
1131  updatedAddress += addressfield;
1132  }
1133 
1134  return updatedAddress;
1135  }
1136 
1137 }

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