Autopsy  4.10.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ExtractEdge.java
Go to the documentation of this file.
1 /*
2  *
3  * Autopsy Forensic Browser
4  *
5  * Copyright 2019 Basis Technology Corp.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.recentactivity;
20 
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileNotFoundException;
24 import java.io.IOException;
25 import java.nio.file.Path;
26 import java.nio.file.Paths;
27 import java.text.ParseException;
28 import java.text.SimpleDateFormat;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Collection;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Scanner;
35 import java.util.logging.Level;
36 import org.openide.modules.InstalledFileLocator;
37 import org.openide.util.NbBundle.Messages;
51 import org.sleuthkit.datamodel.AbstractFile;
52 import org.sleuthkit.datamodel.BlackboardArtifact;
53 import org.sleuthkit.datamodel.Content;
54 import org.sleuthkit.datamodel.TskCoreException;
55 
59 final class ExtractEdge extends Extract {
60 
61  private static final Logger LOG = Logger.getLogger(ExtractEdge.class.getName());
62  private final IngestServices services = IngestServices.getInstance();
63  private final Path moduleTempResultPath;
64  private Content dataSource;
65  private IngestJobContext context;
66  private HashMap<String, ArrayList<String>> containersTable;
67 
68  private static final String EDGE = "Edge"; //NON-NLS
69 
70  private static final String EDGE_KEYWORD_VISIT = "Visited:"; //NON-NLS
71  private static final String IGNORE_COMMA_IN_QUOTES_REGEX = ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)"; //NON-NLS
72 
73  private static final String EDGE_TABLE_TYPE_DOWNLOAD = "iedownload"; //NON-NLS
74  private static final String EDGE_TABLE_TYPE_HISTORY = "History"; //NON-NLS
75  private static final String EDGE_TABLE_TYPE_COOKIE = "cookie"; //NON-NLS
76 
77  private static final String EDGE_HEAD_URL = "url"; //NON-NLS
78  private static final String EDGE_HEAD_ACCESSTIME = "accessedtime"; //NON-NLS
79  private static final String EDGE_HEAD_NAME = "name"; //NON-NLS
80  private static final String EDGE_HEAD_CONTAINER_ID = "containerid"; //NON-NLS
81  private static final String EDGE_HEAD_RESPONSEHEAD = "responseheaders"; //NON-NLS
82  private static final String EDGE_HEAD_TITLE = "title"; //NON-NLS
83  private static final String EDGE_HEAD_RDOMAIN = "rdomain"; //NON-NLS
84  private static final String EDGE_HEAD_VALUE = "value"; //NON-NLS
85  private static final String EDGE_HEAD_LASTMOD = "lastmodified"; //NON-NLS
86 
87  private static final String EDGE_WEBCACHE_PREFIX = "WebCacheV01"; //NON-NLS
88  private static final String EDGE_CONTAINER_FILE_PREFIX = "Container_"; //NON-NLS
89  private static final String EDGE_CONTAINER_FILE_EXT = ".csv"; //NON-NLS
90  private static final String EDGE_WEBCACHE_EXT = ".dat"; //NON-NLS
91 
92  private static final String ESE_TOOL_NAME = "ESEDatabaseView.exe"; //NON-NLS
93  private static final String EDGE_WEBCACHE_NAME = "WebCacheV01.dat"; //NON-NLS
94  private static final String EDGE_SPARTAN_NAME = "Spartan.edb"; //NON-NLS
95  private static final String EDGE_CONTAINTERS_FILE_NAME = "Containers.csv"; //NON-NLS
96  private static final String EDGE_FAVORITE_FILE_NAME = "Favorites.csv"; //NON-NLS
97  private static final String EDGE_OUTPUT_FILE_NAME = "Output.txt"; //NON-NLS
98  private static final String EDGE_ERROR_FILE_NAME = "File.txt"; //NON-NLS
99  private static final String EDGE_WEBCACHE_FOLDER_NAME = "WebCache"; //NON-NLS
100  private static final String EDGE_SPARTAN_FOLDER_NAME = "MicrosoftEdge"; //NON-NLS
101 
102  private static final String ESE_TOOL_FOLDER = "ESEDatabaseView"; //NON-NLS
103  private static final String EDGE_RESULT_FOLDER_NAME = "results"; //NON-NLS
104 
105  private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a"); //NON-NLS
106 
107  @Messages({
108  "ExtractEdge_process_errMsg_unableFindESEViewer=Unable to find ESEDatabaseViewer",
109  "ExtractEdge_process_errMsg_errGettingWebCacheFiles=Error trying to retrieving Edge WebCacheV01 file",
110  "ExtractEdge_process_errMsg_webcacheFail=Failure processing Microsoft Edge WebCacheV01.dat file",
111  "ExtractEdge_process_errMsg_spartanFail=Failure processing Microsoft Edge spartan.edb file",
112  "ExtractEdge_Module_Name=Microsoft Edge",
113  "ExtractEdge_getHistory_containerFileNotFound=Error while trying to analyze Edge history",
114  "Progress_Message_Edge_History=Microsoft Edge History",
115  "Progress_Message_Edge_Bookmarks=Microsoft Edge Bookmarks",
116  "Progress_Message_Edge_Cookies=Microsoft Edge Cookies",
117  })
118 
122  ExtractEdge() throws NoCurrentCaseException {
123  moduleTempResultPath = Paths.get(RAImageIngestModule.getRATempPath(Case.getCurrentCaseThrows(), EDGE), EDGE_RESULT_FOLDER_NAME);
124  }
125 
126  @Override
127  protected String getName() {
128  return Bundle.ExtractEdge_Module_Name();
129  }
130 
131  @Override
132  void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
133  this.dataSource = dataSource;
134  this.context = context;
135  this.setFoundData(false);
136 
137  List<AbstractFile> webCacheFiles = null;
138  List<AbstractFile> spartanFiles = null;
139 
140  try {
141  webCacheFiles = fetchWebCacheDBFiles();
142  } catch (TskCoreException ex) {
143  this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_errGettingWebCacheFiles());
144  LOG.log(Level.SEVERE, "Error fetching 'WebCacheV01.dat' files for Microsoft Edge", ex); //NON-NLS
145  }
146 
147  try {
148  spartanFiles = fetchSpartanDBFiles(); // For later use with bookmarks
149  } catch (TskCoreException ex) {
150  this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_spartanFail());
151  LOG.log(Level.SEVERE, "Error fetching 'spartan.edb' files for Microsoft Edge", ex); //NON-NLS
152  }
153 
154  // No edge files found
155  if (webCacheFiles == null && spartanFiles == null) {
156  return;
157  }
158 
159  this.setFoundData(true);
160 
161  if (!PlatformUtil.isWindowsOS()) {
162  LOG.log(Level.WARNING, "Microsoft Edge files found, unable to parse on Non-Windows system"); //NON-NLS
163  return;
164  }
165 
166  final String esedumper = getPathForESEDumper();
167  if (esedumper == null) {
168  this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_unableFindESEViewer());
169  LOG.log(Level.SEVERE, "Error finding ESEDatabaseViewer program"); //NON-NLS
170  return; //If we cannot find the ESEDatabaseView we cannot proceed
171  }
172 
173  try {
174  this.processWebCacheDbFile(esedumper, webCacheFiles, progressBar);
175  } catch (IOException | TskCoreException ex) {
176  this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_webcacheFail());
177  LOG.log(Level.SEVERE, "Error returned from processWebCacheDbFile", ex); // NON-NLS
178  }
179 
180  progressBar.progress(Bundle.Progress_Message_Edge_Bookmarks());
181  try {
182  this.processSpartanDbFile(esedumper, spartanFiles);
183  } catch (IOException | TskCoreException ex) {
184  this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_spartanFail());
185  LOG.log(Level.SEVERE, "Error returned from processSpartanDbFile", ex); // NON-NLS
186  }
187  }
188 
198  void processWebCacheDbFile(String eseDumperPath, List<AbstractFile> webCacheFiles, DataSourceIngestModuleProgress progressBar) throws IOException, TskCoreException {
199 
200  for (AbstractFile webCacheFile : webCacheFiles) {
201 
202  if (context.dataSourceIngestIsCancelled()) {
203  return;
204  }
205 
206  clearContainerTable();
207 
208  //Run the dumper
209  String tempWebCacheFileName = EDGE_WEBCACHE_PREFIX
210  + Integer.toString((int) webCacheFile.getId()) + EDGE_WEBCACHE_EXT; //NON-NLS
211  File tempWebCacheFile = new File(RAImageIngestModule.getRATempPath(currentCase, EDGE), tempWebCacheFileName);
212 
213  try {
214  ContentUtils.writeToFile(webCacheFile, tempWebCacheFile,
215  context::dataSourceIngestIsCancelled);
216  } catch (IOException ex) {
217  throw new IOException("Error writingToFile: " + webCacheFile, ex); //NON-NLS
218  }
219 
220  File resultsDir = new File(moduleTempResultPath.toAbsolutePath() + Integer.toString((int) webCacheFile.getId()));
221  resultsDir.mkdirs();
222  try {
223  executeDumper(eseDumperPath, tempWebCacheFile.getAbsolutePath(),
224  resultsDir.getAbsolutePath());
225 
226  if (context.dataSourceIngestIsCancelled()) {
227  return;
228  }
229 
230  progressBar.progress(Bundle.Progress_Message_Edge_History());
231 
232  this.getHistory(webCacheFile, resultsDir);
233 
234  if (context.dataSourceIngestIsCancelled()) {
235  return;
236  }
237 
238  progressBar.progress(Bundle.Progress_Message_Edge_Cookies());
239 
240  this.getCookies(webCacheFile, resultsDir);
241 
242  } finally {
243  tempWebCacheFile.delete();
244  FileUtil.deleteFileDir(resultsDir);
245  }
246  }
247  }
248 
258  void processSpartanDbFile(String eseDumperPath, List<AbstractFile> spartanFiles) throws IOException, TskCoreException {
259 
260  for (AbstractFile spartanFile : spartanFiles) {
261 
262  if (context.dataSourceIngestIsCancelled()) {
263  return;
264  }
265 
266  //Run the dumper
267  String tempSpartanFileName = EDGE_WEBCACHE_PREFIX
268  + Integer.toString((int) spartanFile.getId()) + EDGE_WEBCACHE_EXT;
269  File tempSpartanFile = new File(RAImageIngestModule.getRATempPath(currentCase, EDGE), tempSpartanFileName);
270 
271  try {
272  ContentUtils.writeToFile(spartanFile, tempSpartanFile,
273  context::dataSourceIngestIsCancelled);
274  } catch (IOException ex) {
275  throw new IOException("Error writingToFile: " + spartanFile, ex); //NON-NLS
276  }
277 
278  File resultsDir = new File(moduleTempResultPath.toAbsolutePath() + Integer.toString((int) spartanFile.getId()));
279  resultsDir.mkdirs();
280  try {
281  executeDumper(eseDumperPath, tempSpartanFile.getAbsolutePath(),
282  resultsDir.getAbsolutePath());
283 
284  if (context.dataSourceIngestIsCancelled()) {
285  return;
286  }
287 
288  this.getBookmarks(spartanFile, resultsDir);
289 
290  } finally {
291  tempSpartanFile.delete();
292  FileUtil.deleteFileDir(resultsDir);
293  }
294  }
295  }
296 
306  private void getHistory(AbstractFile origFile, File resultDir) throws TskCoreException, FileNotFoundException {
307  ArrayList<File> historyFiles = getHistoryFiles(resultDir);
308 
309  if (historyFiles == null) {
310  return;
311  }
312 
313  for (File file : historyFiles) {
314  Scanner fileScanner;
315  try {
316  fileScanner = new Scanner(new FileInputStream(file.toString()));
317  } catch (FileNotFoundException ex) {
318  LOG.log(Level.WARNING, "Unable to find the ESEDatabaseView file at " + file.getPath(), ex); //NON-NLS
319  continue; // If we couldn't open this file, continue to the next file
320  }
321 
322  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
323 
324  try {
325  List<String> headers = null;
326  while (fileScanner.hasNext()) {
327  String line = fileScanner.nextLine();
328  if (headers == null) {
329  headers = Arrays.asList(line.toLowerCase().split(","));
330  continue;
331  }
332 
333  if (line.contains(EDGE_KEYWORD_VISIT)) {
334  BlackboardArtifact ba = getHistoryArtifact(origFile, headers, line);
335  if (ba != null) {
336  bbartifacts.add(ba);
337  this.indexArtifact(ba);
338  }
339  }
340  }
341  } finally {
342  fileScanner.close();
343  }
344 
345  if (!bbartifacts.isEmpty()) {
346  services.fireModuleDataEvent(new ModuleDataEvent(
347  RecentActivityExtracterModuleFactory.getModuleName(),
348  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, bbartifacts));
349  }
350  }
351  }
352 
361  private void getBookmarks(AbstractFile origFile, File resultDir) throws TskCoreException {
362  Scanner fileScanner;
363  File favoriteFile = new File(resultDir, EDGE_FAVORITE_FILE_NAME);
364 
365  try {
366  fileScanner = new Scanner(new FileInputStream(favoriteFile));
367  } catch (FileNotFoundException ex) {
368  // This is a non-fatal error, if the favorites file is not found
369  // there might have not been any favorites\bookmarks
370  return;
371  }
372 
373  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
374 
375  try {
376  List<String> headers = null;
377  while (fileScanner.hasNext()) {
378  String line = fileScanner.nextLine();
379  if (headers == null) {
380  headers = Arrays.asList(line.toLowerCase().split(","));
381  continue;
382  }
383 
384  BlackboardArtifact ba = getBookmarkArtifact(origFile, headers, line);
385  if (ba != null) {
386  bbartifacts.add(ba);
387  this.indexArtifact(ba);
388  }
389  }
390  } finally {
391  fileScanner.close();
392  }
393 
394  if (!bbartifacts.isEmpty()) {
395  services.fireModuleDataEvent(new ModuleDataEvent(
396  RecentActivityExtracterModuleFactory.getModuleName(),
397  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, bbartifacts));
398  }
399  }
400 
408  private void getCookies(AbstractFile origFile, File resultDir) throws TskCoreException {
409  File containerFiles[] = resultDir.listFiles((dir, name) -> name.toLowerCase().contains(EDGE_TABLE_TYPE_COOKIE));
410 
411  if (containerFiles == null) {
412  return;
413  }
414 
415  for (File file : containerFiles) {
416  Scanner fileScanner;
417  try {
418  fileScanner = new Scanner(new FileInputStream(file.toString()));
419  } catch (FileNotFoundException ex) {
420  LOG.log(Level.WARNING, "Unable to find the ESEDatabaseView file at " + file.getPath(), ex); //NON-NLS
421  continue; // If we couldn't open this file, continue to the next file
422  }
423 
424  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
425 
426  try {
427  List<String> headers = null;
428  while (fileScanner.hasNext()) {
429  String line = fileScanner.nextLine();
430  if (headers == null) {
431  headers = Arrays.asList(line.toLowerCase().split(","));
432  continue;
433  }
434 
435  BlackboardArtifact ba = getCookieArtifact(origFile, headers, line);
436  if (ba != null) {
437  bbartifacts.add(ba);
438  this.indexArtifact(ba);
439  }
440  }
441  } finally {
442  fileScanner.close();
443  }
444 
445  if (!bbartifacts.isEmpty()) {
446  services.fireModuleDataEvent(new ModuleDataEvent(
447  RecentActivityExtracterModuleFactory.getModuleName(),
448  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, bbartifacts));
449  }
450  }
451  }
452 
463  private void getDownloads(AbstractFile origFile, File resultDir) throws TskCoreException, FileNotFoundException {
464  ArrayList<File> downloadFiles = getDownloadFiles(resultDir);
465 
466  if (downloadFiles == null) {
467  return;
468  }
469 
470  for (File file : downloadFiles) {
471  Scanner fileScanner;
472  try {
473  fileScanner = new Scanner(new FileInputStream(file.toString()));
474  } catch (FileNotFoundException ex) {
475  LOG.log(Level.WARNING, "Unable to find the ESEDatabaseView file at " + file.getPath(), ex); //NON-NLS
476  continue; // If we couldn't open this file, continue to the next file
477  }
478  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
479 
480  try {
481  List<String> headers = null;
482  while (fileScanner.hasNext()) {
483  String line = fileScanner.nextLine();
484  if (headers == null) {
485  headers = Arrays.asList(line.toLowerCase().split(","));
486  continue;
487  }
488 
489  if (line.contains(EDGE_TABLE_TYPE_DOWNLOAD)) {
490 
491  BlackboardArtifact ba = getDownloadArtifact(origFile, headers, line);
492  if (ba != null) {
493  bbartifacts.add(ba);
494  this.indexArtifact(ba);
495  }
496  }
497  }
498  } finally {
499  fileScanner.close();
500  }
501 
502  if (!bbartifacts.isEmpty()) {
503  services.fireModuleDataEvent(new ModuleDataEvent(
504  RecentActivityExtracterModuleFactory.getModuleName(),
505  BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, bbartifacts));
506  }
507  }
508  }
509 
515  private String getPathForESEDumper() {
516  Path path = Paths.get(ESE_TOOL_FOLDER, ESE_TOOL_NAME);
517  File eseToolFile = InstalledFileLocator.getDefault().locate(path.toString(),
518  ExtractEdge.class.getPackage().getName(), false);
519  if (eseToolFile != null) {
520  return eseToolFile.getAbsolutePath();
521  }
522 
523  return null;
524  }
525 
532  private List<AbstractFile> fetchWebCacheDBFiles() throws TskCoreException {
534  = currentCase.getServices().getFileManager();
535  return fileManager.findFiles(dataSource, EDGE_WEBCACHE_NAME, EDGE_WEBCACHE_FOLDER_NAME);
536  }
537 
544  private List<AbstractFile> fetchSpartanDBFiles() throws TskCoreException {
546  = currentCase.getServices().getFileManager();
547  return fileManager.findFiles(dataSource, EDGE_SPARTAN_NAME, EDGE_SPARTAN_FOLDER_NAME);
548  }
549 
561  private void executeDumper(String dumperPath, String inputFilePath,
562  String outputDir) throws IOException {
563 
564  final Path outputFilePath = Paths.get(outputDir, EDGE_OUTPUT_FILE_NAME);
565  final Path errFilePath = Paths.get(outputDir, EDGE_ERROR_FILE_NAME);
566  LOG.log(Level.INFO, "Writing ESEDatabaseViewer results to: {0}", outputDir); //NON-NLS
567 
568  List<String> commandLine = new ArrayList<>();
569  commandLine.add(dumperPath);
570  commandLine.add("/table"); //NON-NLS
571  commandLine.add(inputFilePath);
572  commandLine.add("*"); //NON-NLS
573  commandLine.add("/scomma"); //NON-NLS
574  commandLine.add(outputDir + "\\" + "*.csv"); //NON-NLS
575 
576  ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
577  processBuilder.redirectOutput(outputFilePath.toFile());
578  processBuilder.redirectError(errFilePath.toFile());
579 
580  ExecUtil.execute(processBuilder, new DataSourceIngestModuleProcessTerminator(context));
581  }
582 
593  private BlackboardArtifact getHistoryArtifact(AbstractFile origFile, List<String> headers, String line) throws TskCoreException {
594  String[] rowSplit = line.split(",");
595 
596  int index = headers.indexOf(EDGE_HEAD_URL);
597  String urlUserStr = rowSplit[index];
598 
599  String[] str = urlUserStr.split("@");
600  String user = (str[0].replace(EDGE_KEYWORD_VISIT, "")).trim();
601  String url = str[1];
602 
603  index = headers.indexOf(EDGE_HEAD_ACCESSTIME);
604  String accessTime = rowSplit[index].trim();
605  Long ftime = null;
606  try {
607  Long epochtime = DATE_FORMATTER.parse(accessTime).getTime();
608  ftime = epochtime / 1000;
609  } catch (ParseException ex) {
610  LOG.log(Level.WARNING, "The Accessed Time format in history file seems invalid " + accessTime, ex); //NON-NLS
611  }
612 
613  BlackboardArtifact bbart = origFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY);
614 
615  bbart.addAttributes(createHistoryAttribute(url, ftime,
616  null, null,
617  this.getName(),
618  NetworkUtils.extractDomain(url), user));
619 
620  return bbart;
621  }
622 
632  private BlackboardArtifact getCookieArtifact(AbstractFile origFile, List<String> headers, String line) throws TskCoreException {
633  String[] lineSplit = line.split(","); // NON-NLS
634 
635  String accessTime = lineSplit[headers.indexOf(EDGE_HEAD_LASTMOD)].trim();
636  Long ftime = null;
637  try {
638  Long epochtime = DATE_FORMATTER.parse(accessTime).getTime();
639  ftime = epochtime / 1000;
640  } catch (ParseException ex) {
641  LOG.log(Level.WARNING, "The Accessed Time format in history file seems invalid " + accessTime, ex); //NON-NLS
642  }
643 
644  String domain = lineSplit[headers.indexOf(EDGE_HEAD_RDOMAIN)].trim();
645  String name = hexToChar(lineSplit[headers.indexOf(EDGE_HEAD_NAME)].trim());
646  String value = hexToChar(lineSplit[headers.indexOf(EDGE_HEAD_VALUE)].trim());
647  String url = flipDomain(domain);
648 
649  BlackboardArtifact bbart = origFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE);
650  bbart.addAttributes(createCookieAttributes(url, ftime, name, value, this.getName(), NetworkUtils.extractDomain(url)));
651  return bbart;
652  }
653 
667  private BlackboardArtifact getDownloadArtifact(AbstractFile origFile, List<String> headers, String line) throws TskCoreException {
668  BlackboardArtifact bbart = null;
669 
670  String[] lineSplit = line.split(","); // NON-NLS
671  String rheader = lineSplit[headers.indexOf(EDGE_HEAD_RESPONSEHEAD)];
672 
673  return bbart;
674  }
675 
688  private BlackboardArtifact getBookmarkArtifact(AbstractFile origFile, List<String> headers, String line) throws TskCoreException {
689  // split on all commas as long as they are not inbetween quotes
690  String[] lineSplit = line.split(IGNORE_COMMA_IN_QUOTES_REGEX, -1);
691 
692  String url = lineSplit[headers.indexOf(EDGE_HEAD_URL)];
693  String title = lineSplit[headers.indexOf(EDGE_HEAD_TITLE)].replace("\"", ""); // NON-NLS
694 
695  if (url.isEmpty()) {
696  return null;
697  }
698 
699  BlackboardArtifact bbart = origFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK);
700  bbart.addAttributes(createBookmarkAttributes(url, title, null,
701  this.getName(), NetworkUtils.extractDomain(url)));
702  return bbart;
703  }
704 
711  private String hexToChar(String hexString) {
712  String[] hexValues = hexString.split(" "); // NON-NLS
713  StringBuilder output = new StringBuilder();
714 
715  for (String str : hexValues) {
716  try {
717  int value = Integer.parseInt(str, 16);
718  if (value > 31) { // Ignore non-print characters
719  output.append((char) value);
720  }
721  } catch (NumberFormatException ex) {
722  return null;
723  }
724  }
725 
726  return output.toString();
727  }
728 
740  private String flipDomain(String domain) {
741  if (domain == null || domain.isEmpty()) {
742  return null;
743  }
744 
745  String[] tokens = domain.split("\\."); // NON-NLS
746 
747  if (tokens.length < 2 || tokens.length > 3) {
748  return domain; // don't know what to do, just send it back as is
749  }
750 
751  StringBuilder buf = new StringBuilder();
752  if (tokens.length > 2) {
753  buf.append(tokens[2]);
754  buf.append(".");
755  }
756  buf.append(tokens[1]);
757  buf.append(".");
758  buf.append(tokens[0]);
759 
760  return buf.toString();
761  }
762 
770  private ArrayList<File> getDownloadFiles(File resultDir) throws FileNotFoundException {
771  return getContainerFiles(resultDir, EDGE_TABLE_TYPE_DOWNLOAD);
772  }
773 
781  private ArrayList<File> getHistoryFiles(File resultDir) throws FileNotFoundException {
782  return getContainerFiles(resultDir, EDGE_TABLE_TYPE_HISTORY);
783  }
784 
793  private ArrayList<File> getContainerFiles(File resultDir, String type) throws FileNotFoundException {
794  HashMap<String, ArrayList<String>> idTable = getContainerIDTable(resultDir);
795 
796  ArrayList<String> idList = idTable.get(type);
797  if (idList == null) {
798  return null;
799  }
800 
801  ArrayList<File> fileList = new ArrayList<>();
802  for (String str : idList) {
803  String fileName = EDGE_CONTAINER_FILE_PREFIX + str + EDGE_CONTAINER_FILE_EXT;
804  fileList.add(new File(resultDir, fileName));
805  }
806 
807  return fileList;
808  }
809 
820  private HashMap<String, ArrayList<String>> getContainerIDTable(File resultDir) throws FileNotFoundException {
821 
822  if (containersTable == null) {
823  File containerFile = new File(resultDir, EDGE_CONTAINTERS_FILE_NAME);
824 
825  try (Scanner fileScanner = new Scanner(new FileInputStream(containerFile))) {
826  List<String> headers = null;
827  containersTable = new HashMap<>();
828  int nameIdx = 0;
829  int idIdx = 0;
830  while (fileScanner.hasNext()) {
831  String line = fileScanner.nextLine();
832  if (headers == null) {
833  headers = Arrays.asList(line.toLowerCase().split(","));
834  nameIdx = headers.indexOf(EDGE_HEAD_NAME);
835  idIdx = headers.indexOf(EDGE_HEAD_CONTAINER_ID);
836  } else {
837  String[] row = line.split(","); // NON-NLS
838  String name = row[nameIdx];
839  String id = row[idIdx];
840 
841  ArrayList<String> idList = containersTable.get(name);
842  if (idList == null) {
843  idList = new ArrayList<>();
844  containersTable.put(name, idList);
845  }
846 
847  idList.add(id);
848  }
849  }
850  }
851  }
852 
853  return containersTable;
854  }
855 
859  private void clearContainerTable(){
860  containersTable = null;
861  }
862 }
synchronized List< AbstractFile > findFiles(String fileName)

Copyright © 2012-2018 Basis Technology. Generated on: Fri Mar 22 2019
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.