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;
45 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
47 import org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
49 import org.
sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
55 class Firefox
extends Extract {
57 private static final Logger logger = Logger.getLogger(Firefox.class.getName());
58 private static final String PLACE_URL_PREFIX =
"place:";
59 private static final String HISTORY_QUERY =
"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";
60 private static final String COOKIE_QUERY =
"SELECT name,value,host,expiry,(lastAccessed/1000000) AS lastAccessed,(creationTime/1000000) AS creationTime FROM moz_cookies";
61 private static final String COOKIE_QUERY_V3 =
"SELECT name,value,host,expiry,(lastAccessed/1000000) AS lastAccessed FROM moz_cookies";
62 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";
63 private static final String DOWNLOAD_QUERY =
"SELECT target, source,(startTime/1000000) AS startTime, maxBytes FROM moz_downloads";
64 private static final String DOWNLOAD_QUERY_V24 =
"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";
65 private final IngestServices services = IngestServices.getInstance();
66 private Content dataSource;
67 private IngestJobContext context;
70 moduleName = NbBundle.getMessage(Firefox.class,
"Firefox.moduleName");
74 public void process(Content dataSource, IngestJobContext context) {
75 this.dataSource = dataSource;
76 this.context = context;
84 private void getHistory() {
85 FileManager fileManager = currentCase.getServices().getFileManager();
86 List<AbstractFile> historyFiles;
88 historyFiles = fileManager.findFiles(dataSource,
"places.sqlite",
"Firefox");
89 }
catch (TskCoreException ex) {
90 String msg = NbBundle.getMessage(this.getClass(),
"Firefox.getHistory.errMsg.errFetchingFiles");
91 logger.log(Level.WARNING, msg);
92 this.addErrorMessage(this.getName() +
": " + msg);
96 if (historyFiles.isEmpty()) {
97 String msg = NbBundle.getMessage(this.getClass(),
"Firefox.getHistory.errMsg.noFilesFound");
98 logger.log(Level.INFO, msg);
103 Collection<BlackboardArtifact> bbartifacts =
new ArrayList<>();
105 for (AbstractFile historyFile : historyFiles) {
106 if (historyFile.getSize() == 0) {
110 String fileName = historyFile.getName();
111 String temps = RAImageIngestModule.getRATempPath(currentCase,
"firefox") + File.separator + fileName + j +
".db";
113 ContentUtils.writeToFile(historyFile,
new File(temps), context::dataSourceIngestIsCancelled);
114 }
catch (ReadContentInputStreamException ex) {
115 logger.log(Level.WARNING, String.format(
"Error reading Firefox web history artifacts file '%s' (id=%d).",
116 fileName, historyFile.getId()), ex);
117 this.addErrorMessage(
118 NbBundle.getMessage(
this.getClass(),
"Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
121 }
catch (IOException ex) {
122 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Firefox web history artifacts file '%s' (id=%d).",
123 temps, fileName, historyFile.getId()), ex);
124 this.addErrorMessage(
125 NbBundle.getMessage(
this.getClass(),
"Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
129 File dbFile =
new File(temps);
130 if (context.dataSourceIngestIsCancelled()) {
134 List<HashMap<String, Object>> tempList = this.dbConnect(temps, HISTORY_QUERY);
135 logger.log(Level.INFO,
"{0} - Now getting history from {1} with {2} artifacts identified.",
new Object[]{moduleName, temps, tempList.size()});
136 for (HashMap<String, Object> result : tempList) {
137 String url = result.get(
"url").toString();
139 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
140 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
141 NbBundle.getMessage(
this.getClass(),
142 "Firefox.parentModuleName.noSpace"),
143 ((url != null) ? url :
"")));
145 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
146 NbBundle.getMessage(
this.getClass(),
147 "Firefox.parentModuleName.noSpace"),
148 (Long.valueOf(result.get(
"visit_date").toString()))));
149 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER,
150 NbBundle.getMessage(
this.getClass(),
151 "Firefox.parentModuleName.noSpace"),
152 ((result.get(
"ref").toString() != null) ? result.get(
"ref").toString() :
"")));
153 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
154 NbBundle.getMessage(
this.getClass(),
155 "Firefox.parentModuleName.noSpace"),
156 ((result.get(
"title").toString() != null) ? result.get(
"title").toString() :
"")));
157 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
158 NbBundle.getMessage(
this.getClass(),
159 "Firefox.parentModuleName.noSpace"),
160 NbBundle.getMessage(
this.getClass(),
"Firefox.moduleName")));
161 String domain = extractDomain(url);
162 if (domain != null && domain.isEmpty() ==
false) {
163 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
164 NbBundle.getMessage(
this.getClass(),
165 "Firefox.parentModuleName.noSpace"), domain));
168 BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY, historyFile, bbattributes);
170 bbartifacts.add(bbart);
177 services.fireModuleDataEvent(
new ModuleDataEvent(
178 NbBundle.getMessage(
this.getClass(),
"Firefox.parentModuleName"),
179 BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, bbartifacts));
185 private void getBookmark() {
187 FileManager fileManager = currentCase.getServices().getFileManager();
188 List<AbstractFile> bookmarkFiles;
190 bookmarkFiles = fileManager.findFiles(dataSource,
"places.sqlite",
"Firefox");
191 }
catch (TskCoreException ex) {
192 String msg = NbBundle.getMessage(this.getClass(),
"Firefox.getBookmark.errMsg.errFetchFiles");
193 logger.log(Level.WARNING, msg);
194 this.addErrorMessage(this.getName() +
": " + msg);
198 if (bookmarkFiles.isEmpty()) {
199 logger.log(Level.INFO,
"Didn't find any firefox bookmark files.");
204 Collection<BlackboardArtifact> bbartifacts =
new ArrayList<>();
206 for (AbstractFile bookmarkFile : bookmarkFiles) {
207 if (bookmarkFile.getSize() == 0) {
210 String fileName = bookmarkFile.getName();
211 String temps = RAImageIngestModule.getRATempPath(currentCase,
"firefox") + File.separator + fileName + j +
".db";
213 ContentUtils.writeToFile(bookmarkFile,
new File(temps), context::dataSourceIngestIsCancelled);
214 }
catch (ReadContentInputStreamException ex) {
215 logger.log(Level.WARNING, String.format(
"Error reading Firefox bookmark artifacts file '%s' (id=%d).",
216 fileName, bookmarkFile.getId()), ex);
217 this.addErrorMessage(
218 NbBundle.getMessage(
this.getClass(),
"Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
221 }
catch (IOException ex) {
222 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Firefox bookmark artifacts file '%s' (id=%d).",
223 temps, fileName, bookmarkFile.getId()), ex);
224 this.addErrorMessage(NbBundle.getMessage(
this.getClass(),
"Firefox.getBookmark.errMsg.errAnalyzeFile",
225 this.getName(), fileName));
228 File dbFile =
new File(temps);
229 if (context.dataSourceIngestIsCancelled()) {
233 List<HashMap<String, Object>> tempList = this.dbConnect(temps, BOOKMARK_QUERY);
234 logger.log(Level.INFO,
"{0} - Now getting bookmarks from {1} with {2} artifacts identified.",
new Object[]{moduleName, temps, tempList.size()});
235 for (HashMap<String, Object> result : tempList) {
236 String url = result.get(
"url").toString();
238 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
239 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
240 NbBundle.getMessage(
this.getClass(),
241 "Firefox.parentModuleName.noSpace"),
242 ((url != null) ? url :
"")));
243 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
244 NbBundle.getMessage(
this.getClass(),
245 "Firefox.parentModuleName.noSpace"),
246 ((result.get(
"title").toString() != null) ? result.get(
"title").toString() :
"")));
247 if (Long.valueOf(result.get(
"dateAdded").toString()) > 0) {
248 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
249 NbBundle.getMessage(
this.getClass(),
250 "Firefox.parentModuleName.noSpace"),
251 (Long.valueOf(result.get(
"dateAdded").toString()))));
253 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
254 NbBundle.getMessage(
this.getClass(),
255 "Firefox.parentModuleName.noSpace"),
256 NbBundle.getMessage(
this.getClass(),
"Firefox.moduleName")));
257 String domain = extractDomain(url);
258 if (domain != null && domain.isEmpty() ==
false) {
259 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
260 NbBundle.getMessage(
this.getClass(),
261 "Firefox.parentModuleName.noSpace"),
265 BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK, bookmarkFile, bbattributes);
267 bbartifacts.add(bbart);
274 services.fireModuleDataEvent(
new ModuleDataEvent(
275 NbBundle.getMessage(
this.getClass(),
"Firefox.parentModuleName"),
276 BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK, bbartifacts));
282 private void getCookie() {
283 FileManager fileManager = currentCase.getServices().getFileManager();
284 List<AbstractFile> cookiesFiles;
286 cookiesFiles = fileManager.findFiles(dataSource,
"cookies.sqlite",
"Firefox");
287 }
catch (TskCoreException ex) {
288 String msg = NbBundle.getMessage(this.getClass(),
"Firefox.getCookie.errMsg.errFetchFile");
289 logger.log(Level.WARNING, msg);
290 this.addErrorMessage(this.getName() +
": " + msg);
294 if (cookiesFiles.isEmpty()) {
295 logger.log(Level.INFO,
"Didn't find any Firefox cookie files.");
300 Collection<BlackboardArtifact> bbartifacts =
new ArrayList<>();
302 for (AbstractFile cookiesFile : cookiesFiles) {
303 if (cookiesFile.getSize() == 0) {
306 String fileName = cookiesFile.getName();
307 String temps = RAImageIngestModule.getRATempPath(currentCase,
"firefox") + File.separator + fileName + j +
".db";
309 ContentUtils.writeToFile(cookiesFile,
new File(temps), context::dataSourceIngestIsCancelled);
310 }
catch (ReadContentInputStreamException ex) {
311 logger.log(Level.WARNING, String.format(
"Error reading Firefox cookie artifacts file '%s' (id=%d).",
312 fileName, cookiesFile.getId()), ex);
313 this.addErrorMessage(
314 NbBundle.getMessage(
this.getClass(),
"Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
317 }
catch (IOException ex) {
318 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Firefox cookie artifacts file '%s' (id=%d).",
319 temps, fileName, cookiesFile.getId()), ex);
320 this.addErrorMessage(
321 NbBundle.getMessage(
this.getClass(),
"Firefox.getCookie.errMsg.errAnalyzeFile", this.getName(),
325 File dbFile =
new File(temps);
326 if (context.dataSourceIngestIsCancelled()) {
330 boolean checkColumn = Util.checkColumn(
"creationTime",
"moz_cookies", temps);
333 query = COOKIE_QUERY;
335 query = COOKIE_QUERY_V3;
338 List<HashMap<String, Object>> tempList = this.dbConnect(temps, query);
339 logger.log(Level.INFO,
"{0} - Now getting cookies from {1} with {2} artifacts identified.",
new Object[]{moduleName, temps, tempList.size()});
340 for (HashMap<String, Object> result : tempList) {
341 String host = result.get(
"host").toString();
343 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
344 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
345 NbBundle.getMessage(
this.getClass(),
346 "Firefox.parentModuleName.noSpace"),
347 ((host != null) ? host :
"")));
348 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME,
349 NbBundle.getMessage(
this.getClass(),
350 "Firefox.parentModuleName.noSpace"),
351 (Long.valueOf(result.get(
"lastAccessed").toString()))));
352 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
353 NbBundle.getMessage(
this.getClass(),
354 "Firefox.parentModuleName.noSpace"),
355 ((result.get(
"name").toString() != null) ? result.get(
"name").toString() :
"")));
356 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
357 NbBundle.getMessage(
this.getClass(),
358 "Firefox.parentModuleName.noSpace"),
359 ((result.get(
"value").toString() != null) ? result.get(
"value").toString() :
"")));
360 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
361 NbBundle.getMessage(
this.getClass(),
362 "Firefox.parentModuleName.noSpace"),
363 NbBundle.getMessage(
this.getClass(),
"Firefox.moduleName")));
365 if (checkColumn ==
true) {
366 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
367 NbBundle.getMessage(
this.getClass(),
368 "Firefox.parentModuleName.noSpace"),
369 (Long.valueOf(result.get(
"creationTime").toString()))));
371 String domain = extractDomain(host);
372 if (domain != null && domain.isEmpty() ==
false) {
373 domain = domain.replaceFirst(
"^\\.+(?!$)",
"");
374 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
375 NbBundle.getMessage(
this.getClass(),
376 "Firefox.parentModuleName.noSpace"), domain));
379 BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_COOKIE, cookiesFile, bbattributes);
381 bbartifacts.add(bbart);
388 services.fireModuleDataEvent(
new ModuleDataEvent(
389 NbBundle.getMessage(
this.getClass(),
"Firefox.parentModuleName"),
390 BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE, bbartifacts));
396 private void getDownload() {
397 getDownloadPreVersion24();
398 getDownloadVersion24();
406 private void getDownloadPreVersion24() {
408 FileManager fileManager = currentCase.getServices().getFileManager();
409 List<AbstractFile> downloadsFiles;
411 downloadsFiles = fileManager.findFiles(dataSource,
"downloads.sqlite",
"Firefox");
412 }
catch (TskCoreException ex) {
413 String msg = NbBundle.getMessage(this.getClass(),
"Firefox.getDlPre24.errMsg.errFetchFiles");
414 logger.log(Level.WARNING, msg);
415 this.addErrorMessage(this.getName() +
": " + msg);
419 if (downloadsFiles.isEmpty()) {
420 logger.log(Level.INFO,
"Didn't find any pre-version-24.0 Firefox download files.");
425 Collection<BlackboardArtifact> bbartifacts =
new ArrayList<>();
427 for (AbstractFile downloadsFile : downloadsFiles) {
428 if (downloadsFile.getSize() == 0) {
431 String fileName = downloadsFile.getName();
432 String temps = RAImageIngestModule.getRATempPath(currentCase,
"firefox") + File.separator + fileName + j +
".db";
435 ContentUtils.writeToFile(downloadsFile,
new File(temps), context::dataSourceIngestIsCancelled);
436 }
catch (ReadContentInputStreamException ex) {
437 logger.log(Level.WARNING, String.format(
"Error reading Firefox download artifacts file '%s' (id=%d).",
438 fileName, downloadsFile.getId()), ex);
439 this.addErrorMessage(
440 NbBundle.getMessage(
this.getClass(),
"Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
443 }
catch (IOException ex) {
444 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Firefox download artifacts file '%s' (id=%d).",
445 temps, fileName, downloadsFile.getId()), ex);
446 this.addErrorMessage(NbBundle.getMessage(
this.getClass(),
"Firefox.getDlPre24.errMsg.errAnalyzeFiles",
447 this.getName(), fileName));
450 File dbFile =
new File(temps);
451 if (context.dataSourceIngestIsCancelled()) {
456 List<HashMap<String, Object>> tempList = this.dbConnect(temps, DOWNLOAD_QUERY);
457 logger.log(Level.INFO,
"{0}- Now getting downloads from {1} with {2} artifacts identified.",
new Object[]{moduleName, temps, tempList.size()});
458 for (HashMap<String, Object> result : tempList) {
459 String source = result.get(
"source").toString();
461 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
463 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
464 NbBundle.getMessage(
this.getClass(),
465 "Firefox.parentModuleName.noSpace"),
468 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
469 NbBundle.getMessage(
this.getClass(),
470 "Firefox.parentModuleName.noSpace"),
471 (Long.valueOf(result.get(
"startTime").toString()))));
473 String target = result.get(
"target").toString();
475 if (target != null) {
477 String decodedTarget = URLDecoder.decode(target.replaceAll(
"file:///",
""),
"UTF-8");
478 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
479 NbBundle.getMessage(
this.getClass(),
480 "Firefox.parentModuleName.noSpace"),
482 long pathID = Util.findID(dataSource, decodedTarget);
484 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
485 NbBundle.getMessage(
this.getClass(),
486 "Firefox.parentModuleName.noSpace"),
489 }
catch (UnsupportedEncodingException ex) {
490 logger.log(Level.SEVERE,
"Error decoding Firefox download URL in " + temps, ex);
495 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
496 NbBundle.getMessage(
this.getClass(),
497 "Firefox.parentModuleName.noSpace"),
498 NbBundle.getMessage(
this.getClass(),
"Firefox.moduleName")));
499 String domain = extractDomain(source);
500 if (domain != null && domain.isEmpty() ==
false) {
501 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
502 NbBundle.getMessage(
this.getClass(),
503 "Firefox.parentModuleName.noSpace"),
507 BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
509 bbartifacts.add(bbart);
513 this.addErrorMessage(
514 NbBundle.getMessage(
this.getClass(),
"Firefox.getDlPre24.errMsg.errParsingArtifacts",
515 this.getName(), errors));
522 services.fireModuleDataEvent(
new ModuleDataEvent(
523 NbBundle.getMessage(
this.getClass(),
"Firefox.parentModuleName"),
524 BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, bbartifacts));
532 private void getDownloadVersion24() {
533 FileManager fileManager = currentCase.getServices().getFileManager();
534 List<AbstractFile> downloadsFiles;
536 downloadsFiles = fileManager.findFiles(dataSource,
"places.sqlite",
"Firefox");
537 }
catch (TskCoreException ex) {
538 String msg = NbBundle.getMessage(this.getClass(),
"Firefox.getDlV24.errMsg.errFetchFiles");
539 logger.log(Level.WARNING, msg);
540 this.addErrorMessage(this.getName() +
": " + msg);
544 if (downloadsFiles.isEmpty()) {
545 logger.log(Level.INFO,
"Didn't find any version-24.0 Firefox download files.");
550 Collection<BlackboardArtifact> bbartifacts =
new ArrayList<>();
552 for (AbstractFile downloadsFile : downloadsFiles) {
553 if (downloadsFile.getSize() == 0) {
556 String fileName = downloadsFile.getName();
557 String temps = RAImageIngestModule.getRATempPath(currentCase,
"firefox") + File.separator + fileName +
"-downloads" + j +
".db";
560 ContentUtils.writeToFile(downloadsFile,
new File(temps), context::dataSourceIngestIsCancelled);
561 }
catch (ReadContentInputStreamException ex) {
562 logger.log(Level.WARNING, String.format(
"Error reading Firefox download artifacts file '%s' (id=%d).",
563 fileName, downloadsFile.getId()), ex);
564 this.addErrorMessage(
565 NbBundle.getMessage(
this.getClass(),
"Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
568 }
catch (IOException ex) {
569 logger.log(Level.SEVERE, String.format(
"Error writing temp sqlite db file '%s' for Firefox download artifacts file '%s' (id=%d).",
570 temps, fileName, downloadsFile.getId()), ex);
571 this.addErrorMessage(
572 NbBundle.getMessage(
this.getClass(),
"Firefox.getDlV24.errMsg.errAnalyzeFile", this.getName(),
576 File dbFile =
new File(temps);
577 if (context.dataSourceIngestIsCancelled()) {
582 List<HashMap<String, Object>> tempList = this.dbConnect(temps, DOWNLOAD_QUERY_V24);
584 logger.log(Level.INFO,
"{0} - Now getting downloads from {1} with {2} artifacts identified.",
new Object[]{moduleName, temps, tempList.size()});
585 for (HashMap<String, Object> result : tempList) {
586 String url = result.get(
"url").toString();
588 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
590 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
591 NbBundle.getMessage(
this.getClass(),
592 "Firefox.parentModuleName.noSpace"),
598 String target = result.get(
"target").toString();
599 if (target != null) {
601 String decodedTarget = URLDecoder.decode(target.replaceAll(
"file:///",
""),
"UTF-8");
602 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
603 NbBundle.getMessage(
this.getClass(),
604 "Firefox.parentModuleName.noSpace"),
606 long pathID = Util.findID(dataSource, decodedTarget);
608 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
609 NbBundle.getMessage(
this.getClass(),
610 "Firefox.parentModuleName.noSpace"),
613 }
catch (UnsupportedEncodingException ex) {
614 logger.log(Level.SEVERE,
"Error decoding Firefox download URL in " + temps, ex);
618 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
619 NbBundle.getMessage(
this.getClass(),
620 "Firefox.parentModuleName.noSpace"),
621 Long.valueOf(result.get(
"lastModified").toString())));
622 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
623 NbBundle.getMessage(
this.getClass(),
624 "Firefox.parentModuleName.noSpace"),
625 NbBundle.getMessage(
this.getClass(),
"Firefox.moduleName")));
626 String domain = extractDomain(url);
627 if (domain != null && domain.isEmpty() ==
false) {
628 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
629 NbBundle.getMessage(
this.getClass(),
630 "Firefox.parentModuleName.noSpace"),
634 BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
636 bbartifacts.add(bbart);
640 this.addErrorMessage(NbBundle.getMessage(
this.getClass(),
"Firefox.getDlV24.errMsg.errParsingArtifacts",
641 this.getName(), errors));
648 services.fireModuleDataEvent(
new ModuleDataEvent(
649 NbBundle.getMessage(
this.getClass(),
"Firefox.parentModuleName"),
650 BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, bbartifacts));
661 private String extractDomain(String url) {
662 if (url == null || url.isEmpty()) {
666 if (url.toLowerCase().startsWith(PLACE_URL_PREFIX)) {
673 return NetworkUtils.extractDomain(url);