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;
 
   44 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
 
   46 import org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
 
   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);
 
  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() : 
"")))); 
 
  151                 this.addArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY, historyFile, bbattributes);
 
  157         services.fireModuleDataEvent(
new ModuleDataEvent(
 
  158                 NbBundle.getMessage(
this.getClass(), 
"Firefox.parentModuleName"), BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY));
 
  164     private void getBookmark() {
 
  166         FileManager fileManager = currentCase.getServices().getFileManager();
 
  167         List<AbstractFile> bookmarkFiles;
 
  169             bookmarkFiles = fileManager.findFiles(dataSource, 
"places.sqlite", 
"Firefox"); 
 
  170         } 
catch (TskCoreException ex) {
 
  171             String msg = NbBundle.getMessage(this.getClass(), 
"Firefox.getBookmark.errMsg.errFetchFiles");
 
  172             logger.log(Level.WARNING, msg);
 
  173             this.addErrorMessage(this.getName() + 
": " + msg);
 
  177         if (bookmarkFiles.isEmpty()) {
 
  178             logger.log(Level.INFO, 
"Didn't find any firefox bookmark files."); 
 
  185         for (AbstractFile bookmarkFile : bookmarkFiles) {
 
  186             if (bookmarkFile.getSize() == 0) {
 
  189             String fileName = bookmarkFile.getName();
 
  190             String temps = RAImageIngestModule.getRATempPath(currentCase, 
"firefox") + File.separator + fileName + j + 
".db"; 
 
  192                 ContentUtils.writeToFile(bookmarkFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  193             } 
catch (IOException ex) {
 
  194                 logger.log(Level.SEVERE, 
"Error writing the sqlite db for firefox bookmark artifacts.{0}", ex); 
 
  195                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Firefox.getBookmark.errMsg.errAnalyzeFile",
 
  196                         this.getName(), fileName));
 
  199             File dbFile = 
new File(temps);
 
  200             if (context.dataSourceIngestIsCancelled()) {
 
  204             List<HashMap<String, Object>> tempList = this.dbConnect(temps, bookmarkQuery);
 
  205             logger.log(Level.INFO, 
"{0} - Now getting bookmarks from {1} with {2} artifacts identified.", 
new Object[]{moduleName, temps, tempList.size()}); 
 
  206             for (HashMap<String, Object> result : tempList) {
 
  208                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  209                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  210                         NbBundle.getMessage(
this.getClass(),
 
  211                                 "Firefox.parentModuleName.noSpace"),
 
  212                         ((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
""))); 
 
  213                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
 
  214                         NbBundle.getMessage(
this.getClass(),
 
  215                                 "Firefox.parentModuleName.noSpace"),
 
  216                         ((result.get(
"title").toString() != null) ? result.get(
"title").toString() : 
""))); 
 
  217                 if (Long.valueOf(result.get(
"dateAdded").toString()) > 0) { 
 
  218                     bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
 
  219                             NbBundle.getMessage(
this.getClass(),
 
  220                                     "Firefox.parentModuleName.noSpace"),
 
  221                             (Long.valueOf(result.get(
"dateAdded").toString())))); 
 
  223                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  224                         NbBundle.getMessage(
this.getClass(),
 
  225                                 "Firefox.parentModuleName.noSpace"),
 
  226                         NbBundle.getMessage(
this.getClass(), 
"Firefox.moduleName")));
 
  227                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  228                         NbBundle.getMessage(
this.getClass(),
 
  229                                 "Firefox.parentModuleName.noSpace"),
 
  230                         (Util.extractDomain((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
"")))); 
 
  231                 this.addArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK, bookmarkFile, bbattributes);
 
  238         services.fireModuleDataEvent(
new ModuleDataEvent(
 
  239                 NbBundle.getMessage(
this.getClass(), 
"Firefox.parentModuleName"), BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK));
 
  245     private void getCookie() {
 
  246         FileManager fileManager = currentCase.getServices().getFileManager();
 
  247         List<AbstractFile> cookiesFiles;
 
  249             cookiesFiles = fileManager.findFiles(dataSource, 
"cookies.sqlite", 
"Firefox"); 
 
  250         } 
catch (TskCoreException ex) {
 
  251             String msg = NbBundle.getMessage(this.getClass(), 
"Firefox.getCookie.errMsg.errFetchFile");
 
  252             logger.log(Level.WARNING, msg);
 
  253             this.addErrorMessage(this.getName() + 
": " + msg);
 
  257         if (cookiesFiles.isEmpty()) {
 
  258             logger.log(Level.INFO, 
"Didn't find any Firefox cookie files."); 
 
  264         for (AbstractFile cookiesFile : cookiesFiles) {
 
  265             if (cookiesFile.getSize() == 0) {
 
  268             String fileName = cookiesFile.getName();
 
  269             String temps = RAImageIngestModule.getRATempPath(currentCase, 
"firefox") + File.separator + fileName + j + 
".db"; 
 
  271                 ContentUtils.writeToFile(cookiesFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  272             } 
catch (IOException ex) {
 
  273                 logger.log(Level.SEVERE, 
"Error writing the sqlite db for firefox cookie artifacts.{0}", ex); 
 
  274                 this.addErrorMessage(
 
  275                         NbBundle.getMessage(
this.getClass(), 
"Firefox.getCookie.errMsg.errAnalyzeFile", this.getName(),
 
  279             File dbFile = 
new File(temps);
 
  280             if (context.dataSourceIngestIsCancelled()) {
 
  284             boolean checkColumn = Util.checkColumn(
"creationTime", 
"moz_cookies", temps); 
 
  289                 query = cookieQueryV3;
 
  292             List<HashMap<String, Object>> tempList = this.dbConnect(temps, query);
 
  293             logger.log(Level.INFO, 
"{0} - Now getting cookies from {1} with {2} artifacts identified.", 
new Object[]{moduleName, temps, tempList.size()}); 
 
  294             for (HashMap<String, Object> result : tempList) {
 
  296                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  297                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  298                         NbBundle.getMessage(
this.getClass(),
 
  299                                 "Firefox.parentModuleName.noSpace"),
 
  300                         ((result.get(
"host").toString() != null) ? result.get(
"host").toString() : 
""))); 
 
  301                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME,
 
  302                         NbBundle.getMessage(
this.getClass(),
 
  303                                 "Firefox.parentModuleName.noSpace"),
 
  304                         (Long.valueOf(result.get(
"lastAccessed").toString())))); 
 
  305                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
 
  306                         NbBundle.getMessage(
this.getClass(),
 
  307                                 "Firefox.parentModuleName.noSpace"),
 
  308                         ((result.get(
"name").toString() != null) ? result.get(
"name").toString() : 
""))); 
 
  309                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
 
  310                         NbBundle.getMessage(
this.getClass(),
 
  311                                 "Firefox.parentModuleName.noSpace"),
 
  312                         ((result.get(
"value").toString() != null) ? result.get(
"value").toString() : 
""))); 
 
  313                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  314                         NbBundle.getMessage(
this.getClass(),
 
  315                                 "Firefox.parentModuleName.noSpace"),
 
  316                         NbBundle.getMessage(
this.getClass(), 
"Firefox.moduleName")));
 
  318                 if (checkColumn == 
true) {
 
  319                     bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
 
  320                             NbBundle.getMessage(
this.getClass(),
 
  321                                     "Firefox.parentModuleName.noSpace"),
 
  322                             (Long.valueOf(result.get(
"creationTime").toString())))); 
 
  324                 String domain = Util.extractDomain(result.get(
"host").toString()); 
 
  325                 domain = domain.replaceFirst(
"^\\.+(?!$)", 
"");
 
  326                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  327                         NbBundle.getMessage(
this.getClass(),
 
  328                                 "Firefox.parentModuleName.noSpace"), domain));
 
  329                 this.addArtifact(ARTIFACT_TYPE.TSK_WEB_COOKIE, cookiesFile, bbattributes);
 
  335         services.fireModuleDataEvent(
new ModuleDataEvent(
 
  336                 NbBundle.getMessage(
this.getClass(), 
"Firefox.parentModuleName"), BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE));
 
  342     private void getDownload() {
 
  343         getDownloadPreVersion24();
 
  344         getDownloadVersion24();
 
  352     private void getDownloadPreVersion24() {
 
  354         FileManager fileManager = currentCase.getServices().getFileManager();
 
  355         List<AbstractFile> downloadsFiles;
 
  357             downloadsFiles = fileManager.findFiles(dataSource, 
"downloads.sqlite", 
"Firefox"); 
 
  358         } 
catch (TskCoreException ex) {
 
  359             String msg = NbBundle.getMessage(this.getClass(), 
"Firefox.getDlPre24.errMsg.errFetchFiles");
 
  360             logger.log(Level.WARNING, msg);
 
  361             this.addErrorMessage(this.getName() + 
": " + msg);
 
  365         if (downloadsFiles.isEmpty()) {
 
  366             logger.log(Level.INFO, 
"Didn't find any pre-version-24.0 Firefox download files."); 
 
  372         for (AbstractFile downloadsFile : downloadsFiles) {
 
  373             if (downloadsFile.getSize() == 0) {
 
  376             String fileName = downloadsFile.getName();
 
  377             String temps = RAImageIngestModule.getRATempPath(currentCase, 
"firefox") + File.separator + fileName + j + 
".db"; 
 
  380                 ContentUtils.writeToFile(downloadsFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  381             } 
catch (IOException ex) {
 
  382                 logger.log(Level.SEVERE, 
"Error writing the sqlite db for firefox download artifacts.{0}", ex); 
 
  383                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Firefox.getDlPre24.errMsg.errAnalyzeFiles",
 
  384                         this.getName(), fileName));
 
  387             File dbFile = 
new File(temps);
 
  388             if (context.dataSourceIngestIsCancelled()) {
 
  393             List<HashMap<String, Object>> tempList = this.dbConnect(temps, downloadQuery);
 
  394             logger.log(Level.INFO, 
"{0}- Now getting downloads from {1} with {2} artifacts identified.", 
new Object[]{moduleName, temps, tempList.size()}); 
 
  395             for (HashMap<String, Object> result : tempList) {
 
  397                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  399                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  400                         NbBundle.getMessage(
this.getClass(),
 
  401                                 "Firefox.parentModuleName.noSpace"),
 
  402                         ((result.get(
"source").toString() != null) ? result.get(
"source").toString() : 
""))); 
 
  404                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
 
  405                         NbBundle.getMessage(
this.getClass(),
 
  406                                 "Firefox.parentModuleName.noSpace"),
 
  407                         (Long.valueOf(result.get(
"startTime").toString())))); 
 
  409                 String target = result.get(
"target").toString(); 
 
  411                 if (target != null) {
 
  413                         String decodedTarget = URLDecoder.decode(target.toString().replaceAll(
"file:///", 
""), 
"UTF-8"); 
 
  414                         bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
 
  415                                 NbBundle.getMessage(
this.getClass(),
 
  416                                         "Firefox.parentModuleName.noSpace"),
 
  418                         long pathID = Util.findID(dataSource, decodedTarget);
 
  420                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
 
  421                                     NbBundle.getMessage(
this.getClass(),
 
  422                                             "Firefox.parentModuleName.noSpace"),
 
  425                     } 
catch (UnsupportedEncodingException ex) {
 
  426                         logger.log(Level.SEVERE, 
"Error decoding Firefox download URL in " + temps, ex); 
 
  431                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  432                         NbBundle.getMessage(
this.getClass(),
 
  433                                 "Firefox.parentModuleName.noSpace"),
 
  434                         NbBundle.getMessage(
this.getClass(), 
"Firefox.moduleName")));
 
  435                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  436                         NbBundle.getMessage(
this.getClass(),
 
  437                                 "Firefox.parentModuleName.noSpace"),
 
  438                         (Util.extractDomain((result.get(
"source").toString() != null) ? result.get(
"source").toString() : 
"")))); 
 
  439                 this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
 
  443                 this.addErrorMessage(
 
  444                         NbBundle.getMessage(
this.getClass(), 
"Firefox.getDlPre24.errMsg.errParsingArtifacts",
 
  445                                 this.getName(), errors));
 
  452         services.fireModuleDataEvent(
new ModuleDataEvent(
 
  453                 NbBundle.getMessage(
this.getClass(), 
"Firefox.parentModuleName"), BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD));
 
  461     private void getDownloadVersion24() {
 
  462         FileManager fileManager = currentCase.getServices().getFileManager();
 
  463         List<AbstractFile> downloadsFiles;
 
  465             downloadsFiles = fileManager.findFiles(dataSource, 
"places.sqlite", 
"Firefox"); 
 
  466         } 
catch (TskCoreException ex) {
 
  467             String msg = NbBundle.getMessage(this.getClass(), 
"Firefox.getDlV24.errMsg.errFetchFiles");
 
  468             logger.log(Level.WARNING, msg);
 
  469             this.addErrorMessage(this.getName() + 
": " + msg);
 
  473         if (downloadsFiles.isEmpty()) {
 
  474             logger.log(Level.INFO, 
"Didn't find any version-24.0 Firefox download files."); 
 
  480         for (AbstractFile downloadsFile : downloadsFiles) {
 
  481             if (downloadsFile.getSize() == 0) {
 
  484             String fileName = downloadsFile.getName();
 
  485             String temps = RAImageIngestModule.getRATempPath(currentCase, 
"firefox") + File.separator + fileName + 
"-downloads" + j + 
".db"; 
 
  488                 ContentUtils.writeToFile(downloadsFile, 
new File(temps), context::dataSourceIngestIsCancelled);
 
  489             } 
catch (IOException ex) {
 
  490                 logger.log(Level.SEVERE, 
"Error writing the sqlite db for firefox download artifacts.{0}", ex); 
 
  491                 this.addErrorMessage(
 
  492                         NbBundle.getMessage(
this.getClass(), 
"Firefox.getDlV24.errMsg.errAnalyzeFile", this.getName(),
 
  496             File dbFile = 
new File(temps);
 
  497             if (context.dataSourceIngestIsCancelled()) {
 
  502             List<HashMap<String, Object>> tempList = this.dbConnect(temps, downloadQueryVersion24);
 
  504             logger.log(Level.INFO, 
"{0} - Now getting downloads from {1} with {2} artifacts identified.", 
new Object[]{moduleName, temps, tempList.size()}); 
 
  505             for (HashMap<String, Object> result : tempList) {
 
  507                 Collection<BlackboardAttribute> bbattributes = 
new ArrayList<>();
 
  509                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
 
  510                         NbBundle.getMessage(
this.getClass(),
 
  511                                 "Firefox.parentModuleName.noSpace"),
 
  512                         ((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
""))); 
 
  517                 String target = result.get(
"target").toString(); 
 
  518                 if (target != null) {
 
  520                         String decodedTarget = URLDecoder.decode(target.toString().replaceAll(
"file:///", 
""), 
"UTF-8"); 
 
  521                         bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
 
  522                                 NbBundle.getMessage(
this.getClass(),
 
  523                                         "Firefox.parentModuleName.noSpace"),
 
  525                         long pathID = Util.findID(dataSource, decodedTarget);
 
  527                             bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
 
  528                                     NbBundle.getMessage(
this.getClass(),
 
  529                                             "Firefox.parentModuleName.noSpace"),
 
  532                     } 
catch (UnsupportedEncodingException ex) {
 
  533                         logger.log(Level.SEVERE, 
"Error decoding Firefox download URL in " + temps, ex); 
 
  537                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
 
  538                         NbBundle.getMessage(
this.getClass(),
 
  539                                 "Firefox.parentModuleName.noSpace"),
 
  540                         Long.valueOf(result.get(
"lastModified").toString()))); 
 
  541                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
 
  542                         NbBundle.getMessage(
this.getClass(),
 
  543                                 "Firefox.parentModuleName.noSpace"),
 
  544                         NbBundle.getMessage(
this.getClass(), 
"Firefox.moduleName")));
 
  545                 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
 
  546                         NbBundle.getMessage(
this.getClass(),
 
  547                                 "Firefox.parentModuleName.noSpace"),
 
  548                         (Util.extractDomain((result.get(
"url").toString() != null) ? result.get(
"url").toString() : 
"")))); 
 
  549                 this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
 
  553                 this.addErrorMessage(NbBundle.getMessage(
this.getClass(), 
"Firefox.getDlV24.errMsg.errParsingArtifacts",
 
  554                         this.getName(), errors));
 
  561         services.fireModuleDataEvent(
new ModuleDataEvent(
 
  562                 NbBundle.getMessage(
this.getClass(), 
"Firefox.parentModuleName"), BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD));