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

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