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

Copyright © 2012-2020 Basis Technology. Generated on: Wed Apr 8 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.