1 /*
2 *
3 * Autopsy Forensic Browser
4 *
5 * Copyright 2012-2014 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 java.io.File;
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;
34
35 import org.openide.util.NbBundle;
44 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
46 import org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
49
53 class Firefox extends Extract {
54
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"; //NON-NLS
57 private static final String cookieQuery = "SELECT name,value,host,expiry,(lastAccessed/1000000) AS lastAccessed,(creationTime/1000000) AS creationTime FROM moz_cookies"; //NON-NLS
58 private static final String cookieQueryV3 = "SELECT name,value,host,expiry,(lastAccessed/1000000) AS lastAccessed FROM moz_cookies"; //NON-NLS
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"; //NON-NLS
60 private static final String downloadQuery = "SELECT target, source,(startTime/1000000) AS startTime, maxBytes FROM moz_downloads"; //NON-NLS
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"; //NON-NLS
62 private final IngestServices services = IngestServices.getInstance();
63 private Content dataSource;
64 private IngestJobContext context;
65
66 Firefox() {
67 moduleName = NbBundle.getMessage(Firefox.class, "Firefox.moduleName");
68 }
69
70 @Override
71 public void process(Content dataSource, IngestJobContext context) {
72 this.dataSource = dataSource;
73 this.context = context;
74 dataFound = false;
75 this.getHistory();
76 this.getBookmark();
77 this.getDownload();
78 this.getCookie();
79 }
80
81 private void getHistory() {
82 FileManager fileManager = currentCase.getServices().getFileManager();
83 List<AbstractFile> historyFiles;
84 try {
85 historyFiles = fileManager.findFiles(dataSource, "places.sqlite", "Firefox"); //NON-NLS
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);
90 return;
91 }
92
93 if (historyFiles.isEmpty()) {
94 String msg = NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.noFilesFound");
95 logger.log(Level.INFO, msg);
96 return;
97 }
98
99 dataFound = true;
100 Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
101 int j = 0;
102 for (AbstractFile historyFile : historyFiles) {
103 if (historyFile.getSize() == 0) {
104 continue;
105 }
106
107 String fileName = historyFile.getName();
108 String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
109 try {
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); //NON-NLS
113 this.addErrorMessage(
114 NbBundle.getMessage(this.getClass(), "Firefox.getHistory.errMsg.errAnalyzeFile", this.getName(),
115 fileName));
116 continue;
117 }
118 File dbFile = new File(temps);
119 if (context.dataSourceIngestIsCancelled()) {
120 dbFile.delete();
121 break;
122 }
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()}); //NON-NLS
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() : ""))); //NON-NLS
131 //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("url").toString() != null) ? EscapeUtil.decodeURL(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())))); //NON-NLS
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() : ""))); //NON-NLS
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() : ""))); //NON-NLS
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() : "")))); //NON-NLS
151
152 BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY, historyFile, bbattributes);
153 if (bbart != null) {
154 bbartifacts.add(bbart);
155 }
156 }
157 ++j;
158 dbFile.delete();
159 }
160
161 services.fireModuleDataEvent(new ModuleDataEvent(
162 NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
163 BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, bbartifacts));
164 }
165
169 private void getBookmark() {
170
171 FileManager fileManager = currentCase.getServices().getFileManager();
172 List<AbstractFile> bookmarkFiles;
173 try {
174 bookmarkFiles = fileManager.findFiles(dataSource, "places.sqlite", "Firefox"); //NON-NLS
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);
179 return;
180 }
181
182 if (bookmarkFiles.isEmpty()) {
183 logger.log(Level.INFO, "Didn't find any firefox bookmark files."); //NON-NLS
184 return;
185 }
186
187 dataFound = true;
188 Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
189 int j = 0;
190 for (AbstractFile bookmarkFile : bookmarkFiles) {
191 if (bookmarkFile.getSize() == 0) {
192 continue;
193 }
194 String fileName = bookmarkFile.getName();
195 String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
196 try {
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); //NON-NLS
200 this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getBookmark.errMsg.errAnalyzeFile",
201 this.getName(), fileName));
202 continue;
203 }
204 File dbFile = new File(temps);
205 if (context.dataSourceIngestIsCancelled()) {
206 dbFile.delete();
207 break;
208 }
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()}); //NON-NLS
211 for (HashMap<String, Object> result : tempList) {
212
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() : ""))); //NON-NLS
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() : ""))); //NON-NLS
222 if (Long.valueOf(result.get("dateAdded").toString()) > 0) { //NON-NLS
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())))); //NON-NLS
227 }
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() : "")))); //NON-NLS
236
237 BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK, bookmarkFile, bbattributes);
238 if (bbart != null) {
239 bbartifacts.add(bbart);
240 }
241 }
242 ++j;
243 dbFile.delete();
244 }
245
246 services.fireModuleDataEvent(new ModuleDataEvent(
247 NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
248 BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK, bbartifacts));
249 }
250
254 private void getCookie() {
255 FileManager fileManager = currentCase.getServices().getFileManager();
256 List<AbstractFile> cookiesFiles;
257 try {
258 cookiesFiles = fileManager.findFiles(dataSource, "cookies.sqlite", "Firefox"); //NON-NLS
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);
263 return;
264 }
265
266 if (cookiesFiles.isEmpty()) {
267 logger.log(Level.INFO, "Didn't find any Firefox cookie files."); //NON-NLS
268 return;
269 }
270
271 dataFound = true;
272 Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
273 int j = 0;
274 for (AbstractFile cookiesFile : cookiesFiles) {
275 if (cookiesFile.getSize() == 0) {
276 continue;
277 }
278 String fileName = cookiesFile.getName();
279 String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
280 try {
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); //NON-NLS
284 this.addErrorMessage(
285 NbBundle.getMessage(this.getClass(), "Firefox.getCookie.errMsg.errAnalyzeFile", this.getName(),
286 fileName));
287 continue;
288 }
289 File dbFile = new File(temps);
290 if (context.dataSourceIngestIsCancelled()) {
291 dbFile.delete();
292 break;
293 }
294 boolean checkColumn = Util.checkColumn("creationTime", "moz_cookies", temps); //NON-NLS
295 String query;
296 if (checkColumn) {
297 query = cookieQuery;
298 } else {
299 query = cookieQueryV3;
300 }
301
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()}); //NON-NLS
304 for (HashMap<String, Object> result : tempList) {
305
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() : ""))); //NON-NLS
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())))); //NON-NLS
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() : ""))); //NON-NLS
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() : ""))); //NON-NLS
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")));
327
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())))); //NON-NLS
333 }
334 String domain = Util.extractDomain(result.get("host").toString()); //NON-NLS
335 domain = domain.replaceFirst("^\\.+(?!$)", "");
336 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
337 NbBundle.getMessage(this.getClass(),
338 "Firefox.parentModuleName.noSpace"), domain));
339
340 BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_COOKIE, cookiesFile, bbattributes);
341 if (bbart != null) {
342 bbartifacts.add(bbart);
343 }
344 }
345 ++j;
346 dbFile.delete();
347 }
348
349 services.fireModuleDataEvent(new ModuleDataEvent(
350 NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
351 BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE, bbartifacts));
352 }
353
357 private void getDownload() {
358 getDownloadPreVersion24();
359 getDownloadVersion24();
360 }
361
367 private void getDownloadPreVersion24() {
368
369 FileManager fileManager = currentCase.getServices().getFileManager();
370 List<AbstractFile> downloadsFiles;
371 try {
372 downloadsFiles = fileManager.findFiles(dataSource, "downloads.sqlite", "Firefox"); //NON-NLS
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);
377 return;
378 }
379
380 if (downloadsFiles.isEmpty()) {
381 logger.log(Level.INFO, "Didn't find any pre-version-24.0 Firefox download files."); //NON-NLS
382 return;
383 }
384
385 dataFound = true;
386 Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
387 int j = 0;
388 for (AbstractFile downloadsFile : downloadsFiles) {
389 if (downloadsFile.getSize() == 0) {
390 continue;
391 }
392 String fileName = downloadsFile.getName();
393 String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
394 int errors = 0;
395 try {
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); //NON-NLS
399 this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getDlPre24.errMsg.errAnalyzeFiles",
400 this.getName(), fileName));
401 continue;
402 }
403 File dbFile = new File(temps);
404 if (context.dataSourceIngestIsCancelled()) {
405 dbFile.delete();
406 break;
407 }
408
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()}); //NON-NLS
411 for (HashMap<String, Object> result : tempList) {
412
413 Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
414
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() : ""))); //NON-NLS
419 //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("source").toString() != null) ? EscapeUtil.decodeURL(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())))); //NON-NLS
424
425 String target = result.get("target").toString(); //NON-NLS
426
427 if (target != null) {
428 try {
429 String decodedTarget = URLDecoder.decode(target.toString().replaceAll("file:///", ""), "UTF-8"); //NON-NLS
430 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
431 NbBundle.getMessage(this.getClass(),
432 "Firefox.parentModuleName.noSpace"),
433 decodedTarget));
434 long pathID = Util.findID(dataSource, decodedTarget);
435 if (pathID != -1) {
436 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
437 NbBundle.getMessage(this.getClass(),
438 "Firefox.parentModuleName.noSpace"),
439 pathID));
440 }
441 } catch (UnsupportedEncodingException ex) {
442 logger.log(Level.SEVERE, "Error decoding Firefox download URL in " + temps, ex); //NON-NLS
443 errors++;
444 }
445 }
446
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() : "")))); //NON-NLS
455
456 BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
457 if (bbart != null) {
458 bbartifacts.add(bbart);
459 }
460 }
461 if (errors > 0) {
462 this.addErrorMessage(
463 NbBundle.getMessage(this.getClass(), "Firefox.getDlPre24.errMsg.errParsingArtifacts",
464 this.getName(), errors));
465 }
466 j++;
467 dbFile.delete();
468 break;
469 }
470
471 services.fireModuleDataEvent(new ModuleDataEvent(
472 NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
473 BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, bbartifacts));
474 }
475
481 private void getDownloadVersion24() {
482 FileManager fileManager = currentCase.getServices().getFileManager();
483 List<AbstractFile> downloadsFiles;
484 try {
485 downloadsFiles = fileManager.findFiles(dataSource, "places.sqlite", "Firefox"); //NON-NLS
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);
490 return;
491 }
492
493 if (downloadsFiles.isEmpty()) {
494 logger.log(Level.INFO, "Didn't find any version-24.0 Firefox download files."); //NON-NLS
495 return;
496 }
497
498 dataFound = true;
499 Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
500 int j = 0;
501 for (AbstractFile downloadsFile : downloadsFiles) {
502 if (downloadsFile.getSize() == 0) {
503 continue;
504 }
505 String fileName = downloadsFile.getName();
506 String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + "-downloads" + j + ".db"; //NON-NLS
507 int errors = 0;
508 try {
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); //NON-NLS
512 this.addErrorMessage(
513 NbBundle.getMessage(this.getClass(), "Firefox.getDlV24.errMsg.errAnalyzeFile", this.getName(),
514 fileName));
515 continue;
516 }
517 File dbFile = new File(temps);
518 if (context.dataSourceIngestIsCancelled()) {
519 dbFile.delete();
520 break;
521 }
522
523 List<HashMap<String, Object>> tempList = this.dbConnect(temps, downloadQueryVersion24);
524
525 logger.log(Level.INFO, "{0} - Now getting downloads from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
526 for (HashMap<String, Object> result : tempList) {
527
528 Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
529
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() : ""))); //NON-NLS
534 //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("source").toString() != null) ? EscapeUtil.decodeURL(result.get("source").toString()) : "")));
535 //TODO Revisit usage of deprecated constructor as per TSK-583
536 //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "RecentActivity", "Last Visited", (Long.valueOf(result.get("startTime").toString()))));
537
538 String target = result.get("target").toString(); //NON-NLS
539 if (target != null) {
540 try {
541 String decodedTarget = URLDecoder.decode(target.toString().replaceAll("file:///", ""), "UTF-8"); //NON-NLS
542 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
543 NbBundle.getMessage(this.getClass(),
544 "Firefox.parentModuleName.noSpace"),
545 decodedTarget));
546 long pathID = Util.findID(dataSource, decodedTarget);
547 if (pathID != -1) {
548 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID,
549 NbBundle.getMessage(this.getClass(),
550 "Firefox.parentModuleName.noSpace"),
551 pathID));
552 }
553 } catch (UnsupportedEncodingException ex) {
554 logger.log(Level.SEVERE, "Error decoding Firefox download URL in " + temps, ex); //NON-NLS
555 errors++;
556 }
557 }
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()))); //NON-NLS
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() : "")))); //NON-NLS
570
571 BlackboardArtifact bbart = this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
572 if (bbart != null) {
573 bbartifacts.add(bbart);
574 }
575 }
576 if (errors > 0) {
577 this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getDlV24.errMsg.errParsingArtifacts",
578 this.getName(), errors));
579 }
580 j++;
581 dbFile.delete();
582 break;
583 }
584
585 services.fireModuleDataEvent(new ModuleDataEvent(
586 NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"),
587 BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, bbartifacts));
588 }
589 }