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;
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
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));
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.getTypeID(),
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.getTypeID(),
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.getTypeID(),
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.getTypeID(),
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.getTypeID(),
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.getTypeID(),
149 NbBundle.getMessage(this.getClass(),
150 "Firefox.parentModuleName.noSpace"), (Util.extractDomain((result.get("url").toString() != null) ? result.get("url").toString() : "")))); //NON-NLS
151 this.addArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY, historyFile, bbattributes);
152 }
153 ++j;
154 dbFile.delete();
155 }
156
157 services.fireModuleDataEvent(new ModuleDataEvent(
158 NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY));
159 }
160
164 private void getBookmark() {
165
166 FileManager fileManager = currentCase.getServices().getFileManager();
167 List<AbstractFile> bookmarkFiles;
168 try {
169 bookmarkFiles = fileManager.findFiles(dataSource, "places.sqlite", "Firefox"); //NON-NLS
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);
174 return;
175 }
176
177 if (bookmarkFiles.isEmpty()) {
178 logger.log(Level.INFO, "Didn't find any firefox bookmark files."); //NON-NLS
179 return;
180 }
181
182 dataFound = true;
183
184 int j = 0;
185 for (AbstractFile bookmarkFile : bookmarkFiles) {
186 if (bookmarkFile.getSize() == 0) {
187 continue;
188 }
189 String fileName = bookmarkFile.getName();
190 String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
191 try {
192 ContentUtils.writeToFile(bookmarkFile, new File(temps));
193 } catch (IOException ex) {
194 logger.log(Level.SEVERE, "Error writing the sqlite db for firefox bookmark artifacts.{0}", ex); //NON-NLS
195 this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getBookmark.errMsg.errAnalyzeFile",
196 this.getName(), fileName));
197 continue;
198 }
199 File dbFile = new File(temps);
200 if (context.dataSourceIngestIsCancelled()) {
201 dbFile.delete();
202 break;
203 }
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()}); //NON-NLS
206 for (HashMap<String, Object> result : tempList) {
207
208 Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
209 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(),
210 NbBundle.getMessage(this.getClass(),
211 "Firefox.parentModuleName.noSpace"),
212 ((result.get("url").toString() != null) ? result.get("url").toString() : ""))); //NON-NLS
213 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE.getTypeID(),
214 NbBundle.getMessage(this.getClass(),
215 "Firefox.parentModuleName.noSpace"),
216 ((result.get("title").toString() != null) ? result.get("title").toString() : ""))); //NON-NLS
217 if (Long.valueOf(result.get("dateAdded").toString()) > 0) { //NON-NLS
218 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID(),
219 NbBundle.getMessage(this.getClass(),
220 "Firefox.parentModuleName.noSpace"),
221 (Long.valueOf(result.get("dateAdded").toString())))); //NON-NLS
222 }
223 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),
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.getTypeID(),
228 NbBundle.getMessage(this.getClass(),
229 "Firefox.parentModuleName.noSpace"),
230 (Util.extractDomain((result.get("url").toString() != null) ? result.get("url").toString() : "")))); //NON-NLS
231 this.addArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK, bookmarkFile, bbattributes);
232
233 }
234 ++j;
235 dbFile.delete();
236 }
237
238 services.fireModuleDataEvent(new ModuleDataEvent(
239 NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK));
240 }
241
245 private void getCookie() {
246 FileManager fileManager = currentCase.getServices().getFileManager();
247 List<AbstractFile> cookiesFiles;
248 try {
249 cookiesFiles = fileManager.findFiles(dataSource, "cookies.sqlite", "Firefox"); //NON-NLS
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);
254 return;
255 }
256
257 if (cookiesFiles.isEmpty()) {
258 logger.log(Level.INFO, "Didn't find any Firefox cookie files."); //NON-NLS
259 return;
260 }
261
262 dataFound = true;
263 int j = 0;
264 for (AbstractFile cookiesFile : cookiesFiles) {
265 if (cookiesFile.getSize() == 0) {
266 continue;
267 }
268 String fileName = cookiesFile.getName();
269 String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
270 try {
271 ContentUtils.writeToFile(cookiesFile, new File(temps));
272 } catch (IOException ex) {
273 logger.log(Level.SEVERE, "Error writing the sqlite db for firefox cookie artifacts.{0}", ex); //NON-NLS
274 this.addErrorMessage(
275 NbBundle.getMessage(this.getClass(), "Firefox.getCookie.errMsg.errAnalyzeFile", this.getName(),
276 fileName));
277 continue;
278 }
279 File dbFile = new File(temps);
280 if (context.dataSourceIngestIsCancelled()) {
281 dbFile.delete();
282 break;
283 }
284 boolean checkColumn = Util.checkColumn("creationTime", "moz_cookies", temps); //NON-NLS
285 String query;
286 if (checkColumn) {
287 query = cookieQuery;
288 } else {
289 query = cookieQueryV3;
290 }
291
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()}); //NON-NLS
294 for (HashMap<String, Object> result : tempList) {
295
296 Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
297 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(),
298 NbBundle.getMessage(this.getClass(),
299 "Firefox.parentModuleName.noSpace"),
300 ((result.get("host").toString() != null) ? result.get("host").toString() : ""))); //NON-NLS
301 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(),
302 NbBundle.getMessage(this.getClass(),
303 "Firefox.parentModuleName.noSpace"),
304 (Long.valueOf(result.get("lastAccessed").toString())))); //NON-NLS
305 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(),
306 NbBundle.getMessage(this.getClass(),
307 "Firefox.parentModuleName.noSpace"),
308 ((result.get("name").toString() != null) ? result.get("name").toString() : ""))); //NON-NLS
309 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(),
310 NbBundle.getMessage(this.getClass(),
311 "Firefox.parentModuleName.noSpace"),
312 ((result.get("value").toString() != null) ? result.get("value").toString() : ""))); //NON-NLS
313 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),
314 NbBundle.getMessage(this.getClass(),
315 "Firefox.parentModuleName.noSpace"),
316 NbBundle.getMessage(this.getClass(), "Firefox.moduleName")));
317
318 if (checkColumn == true) {
319 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID(),
320 NbBundle.getMessage(this.getClass(),
321 "Firefox.parentModuleName.noSpace"),
322 (Long.valueOf(result.get("creationTime").toString())))); //NON-NLS
323 }
324 String domain = Util.extractDomain(result.get("host").toString()); //NON-NLS
325 domain = domain.replaceFirst("^\\.+(?!$)", "");
326 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(),
327 NbBundle.getMessage(this.getClass(),
328 "Firefox.parentModuleName.noSpace"), domain));
329 this.addArtifact(ARTIFACT_TYPE.TSK_WEB_COOKIE, cookiesFile, bbattributes);
330 }
331 ++j;
332 dbFile.delete();
333 }
334
335 services.fireModuleDataEvent(new ModuleDataEvent(
336 NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE));
337 }
338
342 private void getDownload() {
343 getDownloadPreVersion24();
344 getDownloadVersion24();
345 }
346
352 private void getDownloadPreVersion24() {
353
354 FileManager fileManager = currentCase.getServices().getFileManager();
355 List<AbstractFile> downloadsFiles;
356 try {
357 downloadsFiles = fileManager.findFiles(dataSource, "downloads.sqlite", "Firefox"); //NON-NLS
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);
362 return;
363 }
364
365 if (downloadsFiles.isEmpty()) {
366 logger.log(Level.INFO, "Didn't find any pre-version-24.0 Firefox download files."); //NON-NLS
367 return;
368 }
369
370 dataFound = true;
371 int j = 0;
372 for (AbstractFile downloadsFile : downloadsFiles) {
373 if (downloadsFile.getSize() == 0) {
374 continue;
375 }
376 String fileName = downloadsFile.getName();
377 String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + j + ".db"; //NON-NLS
378 int errors = 0;
379 try {
380 ContentUtils.writeToFile(downloadsFile, new File(temps));
381 } catch (IOException ex) {
382 logger.log(Level.SEVERE, "Error writing the sqlite db for firefox download artifacts.{0}", ex); //NON-NLS
383 this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getDlPre24.errMsg.errAnalyzeFiles",
384 this.getName(), fileName));
385 continue;
386 }
387 File dbFile = new File(temps);
388 if (context.dataSourceIngestIsCancelled()) {
389 dbFile.delete();
390 break;
391 }
392
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()}); //NON-NLS
395 for (HashMap<String, Object> result : tempList) {
396
397 Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
398
399 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(),
400 NbBundle.getMessage(this.getClass(),
401 "Firefox.parentModuleName.noSpace"),
402 ((result.get("source").toString() != null) ? result.get("source").toString() : ""))); //NON-NLS
403 //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("source").toString() != null) ? EscapeUtil.decodeURL(result.get("source").toString()) : "")));
404 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID(),
405 NbBundle.getMessage(this.getClass(),
406 "Firefox.parentModuleName.noSpace"),
407 (Long.valueOf(result.get("startTime").toString())))); //NON-NLS
408
409 String target = result.get("target").toString(); //NON-NLS
410
411 if (target != null) {
412 try {
413 String decodedTarget = URLDecoder.decode(target.toString().replaceAll("file:///", ""), "UTF-8"); //NON-NLS
414 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH.getTypeID(),
415 NbBundle.getMessage(this.getClass(),
416 "Firefox.parentModuleName.noSpace"),
417 decodedTarget));
418 long pathID = Util.findID(dataSource, decodedTarget);
419 if (pathID != -1) {
420 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID(),
421 NbBundle.getMessage(this.getClass(),
422 "Firefox.parentModuleName.noSpace"),
423 pathID));
424 }
425 } catch (UnsupportedEncodingException ex) {
426 logger.log(Level.SEVERE, "Error decoding Firefox download URL in " + temps, ex); //NON-NLS
427 errors++;
428 }
429 }
430
431 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),
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.getTypeID(),
436 NbBundle.getMessage(this.getClass(),
437 "Firefox.parentModuleName.noSpace"),
438 (Util.extractDomain((result.get("source").toString() != null) ? result.get("source").toString() : "")))); //NON-NLS
439 this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
440
441 }
442 if (errors > 0) {
443 this.addErrorMessage(
444 NbBundle.getMessage(this.getClass(), "Firefox.getDlPre24.errMsg.errParsingArtifacts",
445 this.getName(), errors));
446 }
447 j++;
448 dbFile.delete();
449 break;
450 }
451
452 services.fireModuleDataEvent(new ModuleDataEvent(
453 NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD));
454 }
455
461 private void getDownloadVersion24() {
462 FileManager fileManager = currentCase.getServices().getFileManager();
463 List<AbstractFile> downloadsFiles;
464 try {
465 downloadsFiles = fileManager.findFiles(dataSource, "places.sqlite", "Firefox"); //NON-NLS
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);
470 return;
471 }
472
473 if (downloadsFiles.isEmpty()) {
474 logger.log(Level.INFO, "Didn't find any version-24.0 Firefox download files."); //NON-NLS
475 return;
476 }
477
478 dataFound = true;
479 int j = 0;
480 for (AbstractFile downloadsFile : downloadsFiles) {
481 if (downloadsFile.getSize() == 0) {
482 continue;
483 }
484 String fileName = downloadsFile.getName();
485 String temps = RAImageIngestModule.getRATempPath(currentCase, "firefox") + File.separator + fileName + "-downloads" + j + ".db"; //NON-NLS
486 int errors = 0;
487 try {
488 ContentUtils.writeToFile(downloadsFile, new File(temps));
489 } catch (IOException ex) {
490 logger.log(Level.SEVERE, "Error writing the sqlite db for firefox download artifacts.{0}", ex); //NON-NLS
491 this.addErrorMessage(
492 NbBundle.getMessage(this.getClass(), "Firefox.getDlV24.errMsg.errAnalyzeFile", this.getName(),
493 fileName));
494 continue;
495 }
496 File dbFile = new File(temps);
497 if (context.dataSourceIngestIsCancelled()) {
498 dbFile.delete();
499 break;
500 }
501
502 List<HashMap<String, Object>> tempList = this.dbConnect(temps, downloadQueryVersion24);
503
504 logger.log(Level.INFO, "{0} - Now getting downloads from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
505 for (HashMap<String, Object> result : tempList) {
506
507 Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
508
509 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(),
510 NbBundle.getMessage(this.getClass(),
511 "Firefox.parentModuleName.noSpace"),
512 ((result.get("url").toString() != null) ? result.get("url").toString() : ""))); //NON-NLS
513 //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", ((result.get("source").toString() != null) ? EscapeUtil.decodeURL(result.get("source").toString()) : "")));
514 //TODO Revisit usage of deprecated constructor as per TSK-583
515 //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "RecentActivity", "Last Visited", (Long.valueOf(result.get("startTime").toString()))));
516
517 String target = result.get("target").toString(); //NON-NLS
518 if (target != null) {
519 try {
520 String decodedTarget = URLDecoder.decode(target.toString().replaceAll("file:///", ""), "UTF-8"); //NON-NLS
521 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH.getTypeID(),
522 NbBundle.getMessage(this.getClass(),
523 "Firefox.parentModuleName.noSpace"),
524 decodedTarget));
525 long pathID = Util.findID(dataSource, decodedTarget);
526 if (pathID != -1) {
527 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID(),
528 NbBundle.getMessage(this.getClass(),
529 "Firefox.parentModuleName.noSpace"),
530 pathID));
531 }
532 } catch (UnsupportedEncodingException ex) {
533 logger.log(Level.SEVERE, "Error decoding Firefox download URL in " + temps, ex); //NON-NLS
534 errors++;
535 }
536 }
537 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID(),
538 NbBundle.getMessage(this.getClass(),
539 "Firefox.parentModuleName.noSpace"),
540 Long.valueOf(result.get("lastModified").toString()))); //NON-NLS
541 bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),
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.getTypeID(),
546 NbBundle.getMessage(this.getClass(),
547 "Firefox.parentModuleName.noSpace"),
548 (Util.extractDomain((result.get("url").toString() != null) ? result.get("url").toString() : "")))); //NON-NLS
549 this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
550
551 }
552 if (errors > 0) {
553 this.addErrorMessage(NbBundle.getMessage(this.getClass(), "Firefox.getDlV24.errMsg.errParsingArtifacts",
554 this.getName(), errors));
555 }
556 j++;
557 dbFile.delete();
558 break;
559 }
560
561 services.fireModuleDataEvent(new ModuleDataEvent(
562 NbBundle.getMessage(this.getClass(), "Firefox.parentModuleName"), BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD));
563 }
564 }