23 package org.sleuthkit.autopsy.recentactivity;
 
   26 import java.io.IOException;
 
   27 import java.io.UnsupportedEncodingException;
 
   28 import java.net.URLDecoder;
 
   29 import java.util.ArrayList;
 
   30 import java.util.Collection;
 
   31 import java.util.HashMap;
 
   32 import java.util.List;
 
   33 import java.util.logging.Level;
 
   35 import org.openide.util.NbBundle;
 
   53 class Firefox 
extends Extract {
 
   55     private static final Logger logger = Logger.getLogger(Firefox.class.getName());
 
   56     private static final String historyQuery = 
"SELECT moz_historyvisits.id,url,title,visit_count,(visit_date/1000000) AS visit_date,from_visit,(SELECT url FROM moz_places WHERE id=moz_historyvisits.from_visit) as ref FROM moz_places, moz_historyvisits WHERE moz_places.id = moz_historyvisits.place_id AND hidden = 0"; 
 
   57     private static final String cookieQuery = 
"SELECT name,value,host,expiry,(lastAccessed/1000000) AS lastAccessed,(creationTime/1000000) AS creationTime FROM moz_cookies"; 
 
   58     private static final String cookieQueryV3 = 
"SELECT name,value,host,expiry,(lastAccessed/1000000) AS lastAccessed FROM moz_cookies"; 
 
   59     private static final String bookmarkQuery = 
"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"; 
 
   60     private static final String downloadQuery = 
"SELECT target, source,(startTime/1000000) AS startTime, maxBytes FROM moz_downloads"; 
 
   61     private static final String downloadQueryVersion24 = 
"SELECT url, content AS target, (lastModified/1000000) AS lastModified FROM moz_places, moz_annos WHERE moz_places.id = moz_annos.place_id AND moz_annos.anno_attribute_id = 3"; 
 
   62     private final IngestServices services = IngestServices.getInstance();
 
   63     private Content dataSource;
 
   64     private IngestJobContext context;
 
   67         moduleName = NbBundle.getMessage(Firefox.class, 
"Firefox.moduleName");
 
   71     public void process(Content dataSource, IngestJobContext context) {
 
   72         this.dataSource = dataSource;
 
   73         this.context = context;
 
   81     private void getHistory() {
 
   82         FileManager fileManager = currentCase.getServices().getFileManager();
 
   83         List<AbstractFile> historyFiles;
 
   85             historyFiles = fileManager.findFiles(dataSource, 
"places.sqlite", 
"Firefox"); 
 
   86         } 
catch (TskCoreException ex) {
 
   87             String msg = NbBundle.getMessage(this.getClass(), 
"Firefox.getHistory.errMsg.errFetchingFiles");
 
   88             logger.log(Level.WARNING, msg);
 
   89             this.addErrorMessage(this.getName() + 
": " + msg);
 
   93         if (historyFiles.isEmpty()) {
 
   94             String msg = NbBundle.getMessage(this.getClass(), 
"Firefox.getHistory.errMsg.noFilesFound");
 
   95             logger.log(Level.INFO, msg);
 
  100         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  102         for (AbstractFile historyFile : historyFiles) {
 
  103             if (historyFile.getSize() == 0) {
 
  107             String fileName = historyFile.getName();
 
  108             String temps = RAImageIngestModule.getRATempPath(currentCase, 
"firefox") + File.separator + fileName + j + 
".db"; 
 
  110                 ContentUtils.writeToFile(historyFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  111             } 
catch (IOException ex) {
 
  112                 logger.log(Level.SEVERE, 
"Error writing the sqlite db for firefox web history artifacts.{0}", ex); 
 
  113                 this.addErrorMessage(
 
  114                         NbBundle.getMessage(
this.getClass(), 
"Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
 
  118             File dbFile = 
new File(temps);
 
  119             if (context.dataSourceIngestIsCancelled()) {
 
  123             List<HashMap<String, Object>> tempList = this.dbConnect(temps, historyQuery);
 
  124             logger.log(Level.INFO, 
"{0} - Now getting history from {1} with {2} artifacts identified.", 
new Object[]{moduleName, temps, tempList.size()}); 
 
  125             for (HashMap<String, Object> result : tempList) {
 
  126                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  127                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  128                         NbBundle.getMessage(
this.getClass(),
 
  129                                 "Firefox.parentModuleName.noSpace"),
 
  130                         ((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
""))); 
 
  132                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
 
  133                         NbBundle.getMessage(
this.getClass(),
 
  134                                 "Firefox.parentModuleName.noSpace"),
 
  135                         (Long.valueOf(result.get(
"visit_date").toString())))); 
 
  136                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER,
 
  137                         NbBundle.getMessage(
this.getClass(),
 
  138                                 "Firefox.parentModuleName.noSpace"),
 
  139                         ((result.get(
"ref").toString() != null) ? result.get(
"ref").toString() : 
""))); 
 
  140                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
 
  141                         NbBundle.getMessage(
this.getClass(),
 
  142                                 "Firefox.parentModuleName.noSpace"),
 
  143                         ((result.get(
"title").toString() != null) ? result.get(
"title").toString() : 
""))); 
 
  144                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  145                         NbBundle.getMessage(
this.getClass(),
 
  146                                 "Firefox.parentModuleName.noSpace"),
 
  147                         NbBundle.getMessage(
this.getClass(), 
"Firefox.moduleName")));
 
  148                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  149                         NbBundle.getMessage(
this.getClass(),
 
  150                                 "Firefox.parentModuleName.noSpace"), (Util.extractDomain((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
"")))); 
 
  152                 BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY, historyFile, bbattributes);
 
  154                     bbartifacts.add(bbart);
 
  161         services.fireModuleDataEvent(
new ModuleDataEvent(
 
  162                 NbBundle.getMessage(
this.getClass(), 
"Firefox.parentModuleName"),
 
  163                 BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, bbartifacts));
 
  169     private void getBookmark() {
 
  171         FileManager fileManager = currentCase.getServices().getFileManager();
 
  172         List<AbstractFile> bookmarkFiles;
 
  174             bookmarkFiles = fileManager.findFiles(dataSource, 
"places.sqlite", 
"Firefox"); 
 
  175         } 
catch (TskCoreException ex) {
 
  176             String msg = NbBundle.getMessage(this.getClass(), 
"Firefox.getBookmark.errMsg.errFetchFiles");
 
  177             logger.log(Level.WARNING, msg);
 
  178             this.addErrorMessage(this.getName() + 
": " + msg);
 
  182         if (bookmarkFiles.isEmpty()) {
 
  183             logger.log(Level.INFO, 
"Didn't find any firefox bookmark files."); 
 
  188         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  190         for (AbstractFile bookmarkFile : bookmarkFiles) {
 
  191             if (bookmarkFile.getSize() == 0) {
 
  194             String fileName = bookmarkFile.getName();
 
  195             String temps = RAImageIngestModule.getRATempPath(currentCase, 
"firefox") + File.separator + fileName + j + 
".db"; 
 
  197                 ContentUtils.writeToFile(bookmarkFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  198             } 
catch (IOException ex) {
 
  199                 logger.log(Level.SEVERE, 
"Error writing the sqlite db for firefox bookmark artifacts.{0}", ex); 
 
  200                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Firefox.getBookmark.errMsg.errAnalyzeFile",
 
  201                         this.getName(), fileName));
 
  204             File dbFile = 
new File(temps);
 
  205             if (context.dataSourceIngestIsCancelled()) {
 
  209             List<HashMap<String, Object>> tempList = this.dbConnect(temps, bookmarkQuery);
 
  210             logger.log(Level.INFO, 
"{0} - Now getting bookmarks from {1} with {2} artifacts identified.", 
new Object[]{moduleName, temps, tempList.size()}); 
 
  211             for (HashMap<String, Object> result : tempList) {
 
  213                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  214                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  215                         NbBundle.getMessage(
this.getClass(),
 
  216                                 "Firefox.parentModuleName.noSpace"),
 
  217                         ((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
""))); 
 
  218                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
 
  219                         NbBundle.getMessage(
this.getClass(),
 
  220                                 "Firefox.parentModuleName.noSpace"),
 
  221                         ((result.get(
"title").toString() != null) ? result.get(
"title").toString() : 
""))); 
 
  222                 if (Long.valueOf(result.get(
"dateAdded").toString()) > 0) { 
 
  223                     bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
 
  224                             NbBundle.getMessage(
this.getClass(),
 
  225                                     "Firefox.parentModuleName.noSpace"),
 
  226                             (Long.valueOf(result.get(
"dateAdded").toString())))); 
 
  228                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  229                         NbBundle.getMessage(
this.getClass(),
 
  230                                 "Firefox.parentModuleName.noSpace"),
 
  231                         NbBundle.getMessage(
this.getClass(), 
"Firefox.moduleName")));
 
  232                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  233                         NbBundle.getMessage(
this.getClass(),
 
  234                                 "Firefox.parentModuleName.noSpace"),
 
  235                         (Util.extractDomain((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
"")))); 
 
  237                 BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK, bookmarkFile, bbattributes);
 
  239                     bbartifacts.add(bbart);
 
  246         services.fireModuleDataEvent(
new ModuleDataEvent(
 
  247                 NbBundle.getMessage(
this.getClass(), 
"Firefox.parentModuleName"),
 
  248                 BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK, bbartifacts));
 
  254     private void getCookie() {
 
  255         FileManager fileManager = currentCase.getServices().getFileManager();
 
  256         List<AbstractFile> cookiesFiles;
 
  258             cookiesFiles = fileManager.findFiles(dataSource, 
"cookies.sqlite", 
"Firefox"); 
 
  259         } 
catch (TskCoreException ex) {
 
  260             String msg = NbBundle.getMessage(this.getClass(), 
"Firefox.getCookie.errMsg.errFetchFile");
 
  261             logger.log(Level.WARNING, msg);
 
  262             this.addErrorMessage(this.getName() + 
": " + msg);
 
  266         if (cookiesFiles.isEmpty()) {
 
  267             logger.log(Level.INFO, 
"Didn't find any Firefox cookie files."); 
 
  272         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  274         for (AbstractFile cookiesFile : cookiesFiles) {
 
  275             if (cookiesFile.getSize() == 0) {
 
  278             String fileName = cookiesFile.getName();
 
  279             String temps = RAImageIngestModule.getRATempPath(currentCase, 
"firefox") + File.separator + fileName + j + 
".db"; 
 
  281                 ContentUtils.writeToFile(cookiesFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  282             } 
catch (IOException ex) {
 
  283                 logger.log(Level.SEVERE, 
"Error writing the sqlite db for firefox cookie artifacts.{0}", ex); 
 
  284                 this.addErrorMessage(
 
  285                         NbBundle.getMessage(
this.getClass(), 
"Firefox.getCookie.errMsg.errAnalyzeFile", this.getName(),
 
  289             File dbFile = 
new File(temps);
 
  290             if (context.dataSourceIngestIsCancelled()) {
 
  294             boolean checkColumn = Util.checkColumn(
"creationTime", 
"moz_cookies", temps); 
 
  299                 query = cookieQueryV3;
 
  302             List<HashMap<String, Object>> tempList = this.dbConnect(temps, query);
 
  303             logger.log(Level.INFO, 
"{0} - Now getting cookies from {1} with {2} artifacts identified.", 
new Object[]{moduleName, temps, tempList.size()}); 
 
  304             for (HashMap<String, Object> result : tempList) {
 
  306                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  307                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  308                         NbBundle.getMessage(
this.getClass(),
 
  309                                 "Firefox.parentModuleName.noSpace"),
 
  310                         ((result.get(
"host").toString() != null) ? result.get(
"host").toString() : 
""))); 
 
  311                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME,
 
  312                         NbBundle.getMessage(
this.getClass(),
 
  313                                 "Firefox.parentModuleName.noSpace"),
 
  314                         (Long.valueOf(result.get(
"lastAccessed").toString())))); 
 
  315                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
 
  316                         NbBundle.getMessage(
this.getClass(),
 
  317                                 "Firefox.parentModuleName.noSpace"),
 
  318                         ((result.get(
"name").toString() != null) ? result.get(
"name").toString() : 
""))); 
 
  319                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
 
  320                         NbBundle.getMessage(
this.getClass(),
 
  321                                 "Firefox.parentModuleName.noSpace"),
 
  322                         ((result.get(
"value").toString() != null) ? result.get(
"value").toString() : 
""))); 
 
  323                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  324                         NbBundle.getMessage(
this.getClass(),
 
  325                                 "Firefox.parentModuleName.noSpace"),
 
  326                         NbBundle.getMessage(
this.getClass(), 
"Firefox.moduleName")));
 
  328                 if (checkColumn == 
true) {
 
  329                     bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
 
  330                             NbBundle.getMessage(
this.getClass(),
 
  331                                     "Firefox.parentModuleName.noSpace"),
 
  332                             (Long.valueOf(result.get(
"creationTime").toString())))); 
 
  334                 String domain = Util.extractDomain(result.get(
"host").toString()); 
 
  335                 domain = domain.replaceFirst(
"^\\.+(?!$)", 
"");
 
  336                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  337                         NbBundle.getMessage(
this.getClass(),
 
  338                                 "Firefox.parentModuleName.noSpace"), domain));
 
  340                 BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_COOKIE, cookiesFile, bbattributes);
 
  342                     bbartifacts.add(bbart);
 
  349         services.fireModuleDataEvent(
new ModuleDataEvent(
 
  350                 NbBundle.getMessage(
this.getClass(), 
"Firefox.parentModuleName"),
 
  351                 BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE, bbartifacts));
 
  357     private void getDownload() {
 
  358         getDownloadPreVersion24();
 
  359         getDownloadVersion24();
 
  367     private void getDownloadPreVersion24() {
 
  369         FileManager fileManager = currentCase.getServices().getFileManager();
 
  370         List<AbstractFile> downloadsFiles;
 
  372             downloadsFiles = fileManager.findFiles(dataSource, 
"downloads.sqlite", 
"Firefox"); 
 
  373         } 
catch (TskCoreException ex) {
 
  374             String msg = NbBundle.getMessage(this.getClass(), 
"Firefox.getDlPre24.errMsg.errFetchFiles");
 
  375             logger.log(Level.WARNING, msg);
 
  376             this.addErrorMessage(this.getName() + 
": " + msg);
 
  380         if (downloadsFiles.isEmpty()) {
 
  381             logger.log(Level.INFO, 
"Didn't find any pre-version-24.0 Firefox download files."); 
 
  386         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  388         for (AbstractFile downloadsFile : downloadsFiles) {
 
  389             if (downloadsFile.getSize() == 0) {
 
  392             String fileName = downloadsFile.getName();
 
  393             String temps = RAImageIngestModule.getRATempPath(currentCase, 
"firefox") + File.separator + fileName + j + 
".db"; 
 
  396                 ContentUtils.writeToFile(downloadsFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  397             } 
catch (IOException ex) {
 
  398                 logger.log(Level.SEVERE, 
"Error writing the sqlite db for firefox download artifacts.{0}", ex); 
 
  399                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Firefox.getDlPre24.errMsg.errAnalyzeFiles",
 
  400                         this.getName(), fileName));
 
  403             File dbFile = 
new File(temps);
 
  404             if (context.dataSourceIngestIsCancelled()) {
 
  409             List<HashMap<String, Object>> tempList = this.dbConnect(temps, downloadQuery);
 
  410             logger.log(Level.INFO, 
"{0}- Now getting downloads from {1} with {2} artifacts identified.", 
new Object[]{moduleName, temps, tempList.size()}); 
 
  411             for (HashMap<String, Object> result : tempList) {
 
  413                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  415                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  416                         NbBundle.getMessage(
this.getClass(),
 
  417                                 "Firefox.parentModuleName.noSpace"),
 
  418                         ((result.get(
"source").toString() != null) ? result.get(
"source").toString() : 
""))); 
 
  420                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
 
  421                         NbBundle.getMessage(
this.getClass(),
 
  422                                 "Firefox.parentModuleName.noSpace"),
 
  423                         (Long.valueOf(result.get(
"startTime").toString())))); 
 
  425                 String target = result.get(
"target").toString(); 
 
  427                 if (target != null) {
 
  429                         String decodedTarget = URLDecoder.decode(target.toString().replaceAll(
"file:///", 
""), 
"UTF-8"); 
 
  430                         bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
 
  431                                 NbBundle.getMessage(
this.getClass(),
 
  432                                         "Firefox.parentModuleName.noSpace"),
 
  434                         long pathID = Util.findID(dataSource, decodedTarget);
 
  436                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
 
  437                                     NbBundle.getMessage(
this.getClass(),
 
  438                                             "Firefox.parentModuleName.noSpace"),
 
  441                     } 
catch (UnsupportedEncodingException ex) {
 
  442                         logger.log(Level.SEVERE, 
"Error decoding Firefox download URL in " + temps, ex); 
 
  447                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  448                         NbBundle.getMessage(
this.getClass(),
 
  449                                 "Firefox.parentModuleName.noSpace"),
 
  450                         NbBundle.getMessage(
this.getClass(), 
"Firefox.moduleName")));
 
  451                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  452                         NbBundle.getMessage(
this.getClass(),
 
  453                                 "Firefox.parentModuleName.noSpace"),
 
  454                         (Util.extractDomain((result.get(
"source").toString() != null) ? result.get(
"source").toString() : 
"")))); 
 
  456                 BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
 
  458                     bbartifacts.add(bbart);
 
  462                 this.addErrorMessage(
 
  463                         NbBundle.getMessage(
this.getClass(), 
"Firefox.getDlPre24.errMsg.errParsingArtifacts",
 
  464                                 this.getName(), errors));
 
  471         services.fireModuleDataEvent(
new ModuleDataEvent(
 
  472                 NbBundle.getMessage(
this.getClass(), 
"Firefox.parentModuleName"),
 
  473                 BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, bbartifacts));
 
  481     private void getDownloadVersion24() {
 
  482         FileManager fileManager = currentCase.getServices().getFileManager();
 
  483         List<AbstractFile> downloadsFiles;
 
  485             downloadsFiles = fileManager.findFiles(dataSource, 
"places.sqlite", 
"Firefox"); 
 
  486         } 
catch (TskCoreException ex) {
 
  487             String msg = NbBundle.getMessage(this.getClass(), 
"Firefox.getDlV24.errMsg.errFetchFiles");
 
  488             logger.log(Level.WARNING, msg);
 
  489             this.addErrorMessage(this.getName() + 
": " + msg);
 
  493         if (downloadsFiles.isEmpty()) {
 
  494             logger.log(Level.INFO, 
"Didn't find any version-24.0 Firefox download files."); 
 
  499         Collection<BlackboardArtifact> bbartifacts = 
new ArrayList<>();
 
  501         for (AbstractFile downloadsFile : downloadsFiles) {
 
  502             if (downloadsFile.getSize() == 0) {
 
  505             String fileName = downloadsFile.getName();
 
  506             String temps = RAImageIngestModule.getRATempPath(currentCase, 
"firefox") + File.separator + fileName + 
"-downloads" + j + 
".db"; 
 
  509                 ContentUtils.writeToFile(downloadsFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  510             } 
catch (IOException ex) {
 
  511                 logger.log(Level.SEVERE, 
"Error writing the sqlite db for firefox download artifacts.{0}", ex); 
 
  512                 this.addErrorMessage(
 
  513                         NbBundle.getMessage(
this.getClass(), 
"Firefox.getDlV24.errMsg.errAnalyzeFile", this.getName(),
 
  517             File dbFile = 
new File(temps);
 
  518             if (context.dataSourceIngestIsCancelled()) {
 
  523             List<HashMap<String, Object>> tempList = this.dbConnect(temps, downloadQueryVersion24);
 
  525             logger.log(Level.INFO, 
"{0} - Now getting downloads from {1} with {2} artifacts identified.", 
new Object[]{moduleName, temps, tempList.size()}); 
 
  526             for (HashMap<String, Object> result : tempList) {
 
  528                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  530                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  531                         NbBundle.getMessage(
this.getClass(),
 
  532                                 "Firefox.parentModuleName.noSpace"),
 
  533                         ((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
""))); 
 
  538                 String target = result.get(
"target").toString(); 
 
  539                 if (target != null) {
 
  541                         String decodedTarget = URLDecoder.decode(target.toString().replaceAll(
"file:///", 
""), 
"UTF-8"); 
 
  542                         bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
 
  543                                 NbBundle.getMessage(
this.getClass(),
 
  544                                         "Firefox.parentModuleName.noSpace"),
 
  546                         long pathID = Util.findID(dataSource, decodedTarget);
 
  548                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
 
  549                                     NbBundle.getMessage(
this.getClass(),
 
  550                                             "Firefox.parentModuleName.noSpace"),
 
  553                     } 
catch (UnsupportedEncodingException ex) {
 
  554                         logger.log(Level.SEVERE, 
"Error decoding Firefox download URL in " + temps, ex); 
 
  558                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
 
  559                         NbBundle.getMessage(
this.getClass(),
 
  560                                 "Firefox.parentModuleName.noSpace"),
 
  561                         Long.valueOf(result.get(
"lastModified").toString()))); 
 
  562                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  563                         NbBundle.getMessage(
this.getClass(),
 
  564                                 "Firefox.parentModuleName.noSpace"),
 
  565                         NbBundle.getMessage(
this.getClass(), 
"Firefox.moduleName")));
 
  566                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  567                         NbBundle.getMessage(
this.getClass(),
 
  568                                 "Firefox.parentModuleName.noSpace"),
 
  569                         (Util.extractDomain((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
"")))); 
 
  571                 BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
 
  573                     bbartifacts.add(bbart);
 
  577                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Firefox.getDlV24.errMsg.errParsingArtifacts",
 
  578                         this.getName(), errors));
 
  585         services.fireModuleDataEvent(
new ModuleDataEvent(
 
  586                 NbBundle.getMessage(
this.getClass(), 
"Firefox.parentModuleName"),
 
  587                 BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, bbartifacts));