Autopsy  4.13.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 webDownloadArtifact = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
548  if (webDownloadArtifact != null) {
549  bbartifacts.add(webDownloadArtifact);
550 
551  // find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact.
552  try {
553  for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) {
554  BlackboardArtifact associatedObjectArtifact = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
555  associatedObjectArtifact.addAttribute(
556  new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
557  RecentActivityExtracterModuleFactory.getModuleName(), webDownloadArtifact.getArtifactID()));
558 
559  bbartifacts.add(associatedObjectArtifact);
560  break;
561  }
562  } catch (TskCoreException ex) {
563  logger.log(Level.SEVERE, String.format("Error creating associated object artifact for file '%s'",
564  downloadedFilePath), ex); //NON-NLS
565  }
566  }
567  }
568  if (errors > 0) {
569  this.addErrorMessage(
570  NbBundle.getMessage(this.getClass(), "Firefox.getDlPre24.errMsg.errParsingArtifacts",
571  this.getName(), errors));
572  }
573  j++;
574  dbFile.delete();
575  break;
576  }
577 
578  postArtifacts(bbartifacts);
579  }
580 
586  private void getDownloadVersion24() {
587  FileManager fileManager = currentCase.getServices().getFileManager();
588  List<AbstractFile> downloadsFiles;
589  try {
590  downloadsFiles = fileManager.findFiles(dataSource, "places.sqlite", "Firefox"); //NON-NLS
591  } catch (TskCoreException ex) {
592  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getDlV24.errMsg.errFetchFiles");
593  logger.log(Level.WARNING, msg);
594  this.addErrorMessage(this.getName() + ": " + msg);
595  return;
596  }
597 
598  if (downloadsFiles.isEmpty()) {
599  logger.log(Level.INFO, "Didn't find any version-24.0 Firefox download files."); //NON-NLS
600  return;
601  }
602 
603  dataFound = true;
604  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
605  int j = 0;
606  for (AbstractFile downloadsFile : downloadsFiles) {
607  if (downloadsFile.getSize() == 0) {
608  continue;
609  }
610  String fileName = downloadsFile.getName();
611  String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + "-downloads" + j + ".db"; //NON-NLS
612  int errors = 0;
613  try {
614  ContentUtils.writeToFile(downloadsFile, new File(temps), context::dataSourceIngestIsCancelled);
615  } catch (ReadContentInputStreamException ex) {
616  logger.log(Level.WARNING, String.format("Error reading Firefox download artifacts file '%s' (id=%d).",
617  fileName, downloadsFile.getId()), ex); //NON-NLS
618  this.addErrorMessage(
619  NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
620  fileName));
621  continue;
622  } catch (IOException ex) {
623  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Firefox download artifacts file '%s' (id=%d).",
624  temps, fileName, downloadsFile.getId()), ex); //NON-NLS
625  this.addErrorMessage(
626  NbBundle.getMessage(this.getClass(), "Firefox.getDlV24.errMsg.errAnalyzeFile", this.getName(),
627  fileName));
628  continue;
629  }
630  File dbFile = new File(temps);
631  if (context.dataSourceIngestIsCancelled()) {
632  dbFile.delete();
633  break;
634  }
635 
636  List<HashMap<String, Object>> tempList = this.dbConnect(temps, DOWNLOAD_QUERY_V24);
637 
638  logger.log(Level.INFO, "{0} - Now getting downloads from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
639  for (HashMap<String, Object> result : tempList) {
640 
641  if (context.dataSourceIngestIsCancelled()) {
642  break;
643  }
644 
645  String url = result.get("url").toString();
646 
647  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
648 
649  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
650  RecentActivityExtracterModuleFactory.getModuleName(),
651  url)); //NON-NLS
652  //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("source").toString() != null) ? EscapeUtil.decodeURL(result.get("source").toString()) : "")));
653  //TODO Revisit usage of deprecated constructor as per TSK-583
654  //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "RecentActivity", "Last Visited", (Long.valueOf(result.get("startTime").toString()))));
655 
656  String target = result.get("target").toString(); //NON-NLS
657  String downloadedFilePath = "";
658  if (target != null) {
659  try {
660  downloadedFilePath = URLDecoder.decode(target.replaceAll("file:///", ""), "UTF-8"); //NON-NLS
661  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
662  RecentActivityExtracterModuleFactory.getModuleName(),
663  downloadedFilePath));
664  long pathID = Util.findID(dataSource, downloadedFilePath);
665  if (pathID != -1) {
666  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
667  RecentActivityExtracterModuleFactory.getModuleName(),
668  pathID));
669  }
670  } catch (UnsupportedEncodingException ex) {
671  logger.log(Level.SEVERE, "Error decoding Firefox download URL in " + temps, ex); //NON-NLS
672  errors++;
673  }
674  }
675  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
676  RecentActivityExtracterModuleFactory.getModuleName(),
677  Long.valueOf(result.get("lastModified").toString()))); //NON-NLS
678  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
679  RecentActivityExtracterModuleFactory.getModuleName(),
680  NbBundle.getMessage(this.getClass(), "Firefox.moduleName")));
681  String domain = extractDomain(url);
682  if (domain != null && domain.isEmpty() == false) {
683  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
684  RecentActivityExtracterModuleFactory.getModuleName(), domain)); //NON-NLS
685  }
686 
687  BlackboardArtifact webDownloadArtifact = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
688  if (webDownloadArtifact != null) {
689  bbartifacts.add(webDownloadArtifact);
690 
691  // find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact.
692  try {
693  for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) {
694  BlackboardArtifact associatedObjectArtifact = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
695  associatedObjectArtifact.addAttribute(
696  new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
697  RecentActivityExtracterModuleFactory.getModuleName(), webDownloadArtifact.getArtifactID()));
698  bbartifacts.add(associatedObjectArtifact);
699  break;
700  }
701  } catch (TskCoreException ex) {
702  logger.log(Level.SEVERE, String.format("Error creating associated object artifact for file '%s'",
703  downloadedFilePath), ex); //NON-NLS
704  }
705  }
706  }
707  if (errors > 0) {
708  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getDlV24.errMsg.errParsingArtifacts",
709  this.getName(), errors));
710  }
711  j++;
712  dbFile.delete();
713  break;
714  }
715 
716  postArtifacts(bbartifacts);
717  }
718 
723  private void getFormsHistory() {
724  FileManager fileManager = currentCase.getServices().getFileManager();
725  List<AbstractFile> formHistoryFiles;
726 
727  // Some fields are just noisy and can me excluded
728  Set<String> excludedFieldNames = new HashSet<>(Arrays.asList(
729  "it", // some kind of timestamp
730  "ts" // some kind of timestamp
731  ));
732 
733  try {
734  formHistoryFiles = fileManager.findFiles(dataSource, "formhistory.sqlite", "Firefox"); //NON-NLS
735  } catch (TskCoreException ex) {
736  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.errFetchingFiles");
737  logger.log(Level.WARNING, msg);
738  this.addErrorMessage(this.getName() + ": " + msg);
739  return;
740  }
741 
742  if (formHistoryFiles.isEmpty()) {
743  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.noFilesFound");
744  logger.log(Level.INFO, msg);
745  return;
746  }
747 
748  dataFound = true;
749  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
750  int j = 0;
751  for (AbstractFile formHistoryFile : formHistoryFiles) {
752  if (formHistoryFile.getSize() == 0) {
753  continue;
754  }
755 
756  String fileName = formHistoryFile.getName();
757  String tempFilePath = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
758  try {
759  ContentUtils.writeToFile(formHistoryFile, new File(tempFilePath), context::dataSourceIngestIsCancelled);
760  } catch (ReadContentInputStreamException ex) {
761  logger.log(Level.WARNING, String.format("Error reading Firefox web history artifacts file '%s' (id=%d).",
762  fileName, formHistoryFile.getId()), ex); //NON-NLS
763  this.addErrorMessage(
764  NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.errAnalyzeFile", this.getName(),
765  fileName));
766  continue;
767  } catch (IOException ex) {
768  logger.log(Level.SEVERE, String.format("Error writing temp sqlite db file '%s' for Firefox web history artifacts file '%s' (id=%d).",
769  tempFilePath, fileName, formHistoryFile.getId()), ex); //NON-NLS
770  this.addErrorMessage(
771  NbBundle.getMessage(this.getClass(), "Firefox.getFormsAutofill.errMsg.errAnalyzeFile", this.getName(),
772  fileName));
773  continue;
774  }
775  File dbFile = new File(tempFilePath);
776  if (context.dataSourceIngestIsCancelled()) {
777  dbFile.delete();
778  break;
779  }
780 
781  // The table schema is a little different in newer version of Firefox
782  boolean isFirefoxV64 = Util.checkColumn("timesUsed", "moz_formhistory", tempFilePath);
783  String formHistoryQuery = (isFirefoxV64) ? FORMHISTORY_QUERY_V64 : FORMHISTORY_QUERY;
784 
785  List<HashMap<String, Object>> tempList = this.dbConnect(tempFilePath, formHistoryQuery);
786  logger.log(Level.INFO, "{0} - Now getting history from {1} with {2} artifacts identified.", new Object[]{moduleName, tempFilePath, tempList.size()}); //NON-NLS
787  for (HashMap<String, Object> result : tempList) {
788 
789  if (context.dataSourceIngestIsCancelled()) {
790  break;
791  }
792 
793  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
794 
795  String fieldName = ((result.get("fieldname").toString() != null) ? result.get("fieldname").toString() : "");
796  // filter out unuseful values
797  if (excludedFieldNames.contains(fieldName.toLowerCase())) {
798  continue;
799  }
800 
801  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
802  RecentActivityExtracterModuleFactory.getModuleName(),
803  fieldName)); //NON-NLS
804 
805  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
806  RecentActivityExtracterModuleFactory.getModuleName(),
807  ((result.get("value").toString() != null) ? result.get("value").toString() : ""))); //NON-NLS
808 
809  // Newer versions of firefox have additional columns
810  if (isFirefoxV64) {
811  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
812  RecentActivityExtracterModuleFactory.getModuleName(),
813  (Long.valueOf(result.get("firstUsed").toString()) / 1000000))); //NON-NLS
814 
815  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
816  RecentActivityExtracterModuleFactory.getModuleName(),
817  (Long.valueOf(result.get("lastUsed").toString()) / 1000000))); //NON-NLS
818 
819  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
820  RecentActivityExtracterModuleFactory.getModuleName(),
821  (Integer.valueOf(result.get("timesUsed").toString())))); //NON-NLS
822 
823  }
824  // Add artifact
825  BlackboardArtifact bbart = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_FORM_AUTOFILL, formHistoryFile, bbattributes);
826  if (bbart != null) {
827  bbartifacts.add(bbart);
828  }
829  }
830  ++j;
831  dbFile.delete();
832  }
833 
834  postArtifacts(bbartifacts);
835  }
836 
837 
843  private void getAutofillProfiles() {
844  FileManager fileManager = currentCase.getServices().getFileManager();
845  List<AbstractFile> autofillProfilesFiles;
846  try {
847  autofillProfilesFiles = fileManager.findFiles(dataSource, "autofill-profiles.json", "Firefox"); //NON-NLS
848  } catch (TskCoreException ex) {
849  String msg = NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errGettingFiles");
850  logger.log(Level.SEVERE, msg, ex);
851  this.addErrorMessage(this.getName() + ": " + msg);
852  return;
853  }
854 
855  if (autofillProfilesFiles.isEmpty()) {
856  logger.log(Level.INFO, "Didn't find any Firefox Autofill Profiles files."); //NON-NLS
857  return;
858  }
859 
860  dataFound = true;
861  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
862  int j = 0;
863 
864  while (j < autofillProfilesFiles.size()) {
865  AbstractFile profileFile = autofillProfilesFiles.get(j++);
866  if (profileFile.getSize() == 0) {
867  continue;
868  }
869  String temps = RAImageIngestModule.getRATempPath(currentCase, "Firefox") + File.separator + profileFile.getName() + j + ".json"; //NON-NLS
870  try {
871  ContentUtils.writeToFile(profileFile, new File(temps), context::dataSourceIngestIsCancelled);
872  } catch (ReadContentInputStreamException ex) {
873  logger.log(Level.WARNING, String.format("Error reading Firefox Autofill profiles artifacts file '%s' (id=%d).",
874  profileFile.getName(), profileFile.getId()), ex); //NON-NLS
875  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile",
876  this.getName(), profileFile.getName()));
877  continue;
878  } catch (IOException ex) {
879  logger.log(Level.SEVERE, String.format("Error writing temp file '%s' for Firefox Autofill profiles file '%s' (id=%d).",
880  temps, profileFile.getName(), profileFile.getId()), ex); //NON-NLS
881  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile",
882  this.getName(), profileFile.getName()));
883  continue;
884  }
885 
886  logger.log(Level.INFO, "{0}- Now getting Bookmarks from {1}", new Object[]{moduleName, temps}); //NON-NLS
887  File dbFile = new File(temps);
888  if (context.dataSourceIngestIsCancelled()) {
889  dbFile.delete();
890  break;
891  }
892 
893  FileReader tempReader;
894  try {
895  tempReader = new FileReader(temps);
896  } catch (FileNotFoundException ex) {
897  logger.log(Level.SEVERE, "Error while trying to read the Autofill profiles json file for Firefox.", ex); //NON-NLS
898  this.addErrorMessage(
899  NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzeFile", this.getName(),
900  profileFile.getName()));
901  continue;
902  }
903 
904  final JsonParser parser = new JsonParser();
905 
906  JsonObject jsonRootObject;
907  JsonArray jAddressesArray;
908 
909  try {
910  jsonRootObject = parser.parse(tempReader).getAsJsonObject();
911  jAddressesArray = jsonRootObject.getAsJsonArray("addresses"); //NON-NLS
912  } catch (JsonIOException | JsonSyntaxException | IllegalStateException ex) {
913  logger.log(Level.WARNING, "Error parsing Json for Firefox Autofill profiles.", ex); //NON-NLS
914  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile3",
915  this.getName(), profileFile.getName()));
916  continue;
917  }
918 
919  for (JsonElement result : jAddressesArray) {
920  JsonObject address = result.getAsJsonObject();
921  if (address == null) {
922  continue;
923  }
924 
925  JsonElement nameEl = address.get("name"); //NON-NLS
926  String name = (nameEl != null) ? nameEl.getAsString() : "";
927 
928  JsonElement emailEl = address.get("email"); //NON-NLS
929  String email = (emailEl != null) ? emailEl.getAsString() : "";
930 
931  JsonElement telEl = address.get("tel"); //NON-NLS
932  String tel = (telEl != null) ? telEl.getAsString() : "";
933  JsonElement telCountryCodeEl = address.get("tel-country-code"); //NON-NLS
934  String telCountryCode = (telCountryCodeEl != null) ? telCountryCodeEl.getAsString() : "";
935  JsonElement telNationalEl = address.get("tel-national"); //NON-NLS
936  String telNational = (telNationalEl != null) ? telNationalEl.getAsString() : "";
937 
938  String phoneNumber = makeTelNumber(tel, telCountryCode, telNational);
939 
940  JsonElement createdEl = address.get("timeCreated"); //NON-NLS
941  Long datetimeCreated = (createdEl != null) ? createdEl.getAsLong()/1000 : Long.valueOf(0);
942  JsonElement lastusedEl = address.get("timeLastUsed"); //NON-NLS
943  Long datetimeLastUsed = (lastusedEl != null) ? lastusedEl.getAsLong()/1000 : Long.valueOf(0);
944  JsonElement timesUsedEl = address.get("timesUsed"); //NON-NLS
945  Integer timesUsed = (timesUsedEl != null) ? timesUsedEl.getAsShort() : Integer.valueOf(0);
946 
947  JsonElement addressLine1El = address.get("address-line1"); //NON-NLS
948  String addressLine1 = (addressLine1El != null) ? addressLine1El.getAsString() : "";
949  JsonElement addressLine2El = address.get("address-line2"); //NON-NLS
950  String addressLine2 = (addressLine2El != null) ? addressLine2El.getAsString() : "";
951  JsonElement addressLine3El = address.get("address-line3"); //NON-NLS
952  String addressLine3 = (addressLine3El != null) ? addressLine3El.getAsString() : "";
953 
954  JsonElement postalCodeEl = address.get("postal-code"); //NON-NLS
955  String postalCode = (postalCodeEl != null) ? postalCodeEl.getAsString() : "";
956  JsonElement countryEl = address.get("country"); //NON-NLS
957  String country = (countryEl != null) ? countryEl.getAsString() : "";
958 
959  String mailingAddress = makeFullAddress(addressLine1, addressLine2, addressLine3, postalCode, country );
960 
961  try {
962  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
963  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME_PERSON,
964  RecentActivityExtracterModuleFactory.getModuleName(),
965  name)); //NON-NLS
966 
967  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL,
968  RecentActivityExtracterModuleFactory.getModuleName(),
969  email)); //NON-NLS
970 
971  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER,
972  RecentActivityExtracterModuleFactory.getModuleName(),
973  phoneNumber)); //NON-NLS
974 
975  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LOCATION,
976  RecentActivityExtracterModuleFactory.getModuleName(),
977  mailingAddress)); //NON-NLS
978 
979  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
980  RecentActivityExtracterModuleFactory.getModuleName(),
981  datetimeCreated)); //NON-NLS
982 
983  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
984  RecentActivityExtracterModuleFactory.getModuleName(),
985  datetimeLastUsed)); //NON-NLS
986 
987  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
988  RecentActivityExtracterModuleFactory.getModuleName(),
989  timesUsed)); //NON-NLS
990 
991  BlackboardArtifact bbart = profileFile.newArtifact(ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS);
992 
993  if (bbart != null) {
994  bbart.addAttributes(bbattributes);
995  bbartifacts.add(bbart);
996  }
997 
998  // If an email address is found, create an account instance for it
999  if (email != null && !email.isEmpty()) {
1000  try {
1001  Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.EMAIL, email, NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), profileFile);
1002  } catch (NoCurrentCaseException | TskCoreException ex) {
1003  logger.log(Level.SEVERE, String.format("Error creating email account instance for '%s' from Firefox profiles file '%s' .",
1004  email, profileFile.getName()), ex); //NON-NLS
1005  }
1006  }
1007 
1008  // If a phone number is found, create an account instance for it
1009  if (phoneNumber != null && !phoneNumber.isEmpty()) {
1010  try {
1011  Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.PHONE, phoneNumber, NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), profileFile);
1012  } catch (NoCurrentCaseException | TskCoreException ex) {
1013  logger.log(Level.SEVERE, String.format("Error creating phone number account instance for '%s' from Chrome profiles file '%s' .",
1014  phoneNumber, profileFile.getName()), ex); //NON-NLS
1015  }
1016  }
1017 
1018  } catch (TskCoreException ex) {
1019  logger.log(Level.SEVERE, "Error while trying to insert Firefox Autofill profile artifact{0}", ex); //NON-NLS
1020  this.addErrorMessage(
1021  NbBundle.getMessage(this.getClass(), "Firefox.getAutofillProfiles.errMsg.errAnalyzingFile4",
1022  this.getName(), profileFile.getName()));
1023  }
1024  }
1025  dbFile.delete();
1026  }
1027 
1028  postArtifacts(bbartifacts);
1029  }
1030 
1039  private String extractDomain(String url) {
1040  if (url == null || url.isEmpty()) {
1041  return url;
1042  }
1043 
1044  if (url.toLowerCase().startsWith(PLACE_URL_PREFIX)) {
1045  /*
1046  * Ignore URLs that begin with the matched text.
1047  */
1048  return null;
1049  }
1050 
1051  return NetworkUtils.extractDomain(url);
1052  }
1053 
1054 
1064  private String makeTelNumber(String tel, String telCountryCode, String telNational) {
1065 
1066  if (tel != null && !tel.isEmpty()) {
1067  return tel;
1068  }
1069 
1070  if ((telCountryCode != null && !telCountryCode.isEmpty()) &&
1071  (telNational != null && !telNational.isEmpty())) {
1072  return telCountryCode + telNational;
1073  }
1074 
1075  return "";
1076  }
1077 
1089  private String makeFullAddress(String addressLine1, String addressLine2, String addressLine3, String postalCode, String country ) {
1090  String fullAddress = "";
1091  fullAddress = appendAddressField(fullAddress, addressLine1 );
1092  fullAddress = appendAddressField(fullAddress, addressLine2 );
1093  fullAddress = appendAddressField(fullAddress, addressLine3 );
1094  fullAddress = appendAddressField(fullAddress, postalCode );
1095  fullAddress = appendAddressField(fullAddress, country );
1096 
1097  return fullAddress;
1098  }
1099 
1108  private String appendAddressField(String address, String addressfield) {
1109 
1110  String updatedAddress = address;
1111  if (addressfield != null && !addressfield.isEmpty()) {
1112  if (!updatedAddress.isEmpty()) {
1113  updatedAddress += ", ";
1114  }
1115  updatedAddress += addressfield;
1116  }
1117 
1118  return updatedAddress;
1119  }
1120 
1121 }

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