Autopsy  4.15.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ExtractIE.java
Go to the documentation of this file.
1 /*
2  *
3  * Autopsy Forensic Browser
4  *
5  * Copyright 2011-2019 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.BufferedReader;
26 import org.openide.util.NbBundle;
29 import java.io.File;
30 import java.io.FileInputStream;
31 import java.io.FileNotFoundException;
32 import java.io.IOException;
33 import java.io.InputStreamReader;
34 import java.text.ParseException;
35 import java.text.SimpleDateFormat;
36 import java.util.ArrayList;
37 import java.util.List;
38 import java.util.logging.Level;
40 import java.util.Collection;
41 import java.util.Scanner;
42 import java.util.stream.Collectors;
43 import org.openide.modules.InstalledFileLocator;
44 import org.openide.util.NbBundle.Messages;
50 import org.sleuthkit.datamodel.BlackboardArtifact;
51 import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
52 import org.sleuthkit.datamodel.BlackboardAttribute;
53 import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
54 import org.sleuthkit.datamodel.Content;
59 import org.sleuthkit.datamodel.*;
60 
65 class ExtractIE extends Extract {
66 
67  private static final Logger logger = Logger.getLogger(ExtractIE.class.getName());
68  private final IngestServices services = IngestServices.getInstance();
69  private final String moduleTempResultsDir;
70  private String PASCO_LIB_PATH;
71  private final String JAVA_PATH;
72  private static final String RESOURCE_URL_PREFIX = "res://";
73  private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
74  private Content dataSource;
75  private IngestJobContext context;
76 
77  @Messages({
78  "Progress_Message_IE_History=IE History",
79  "Progress_Message_IE_Bookmarks=IE Bookmarks",
80  "Progress_Message_IE_Cookies=IE Cookies",
81  "Progress_Message_IE_Downloads=IE Downloads",
82  "Progress_Message_IE_FormHistory=IE Form History",
83  "Progress_Message_IE_AutoFill=IE Auto Fill",
84  "Progress_Message_IE_Logins=IE Logins",
85  })
86 
87  ExtractIE() throws NoCurrentCaseException {
88  moduleName = NbBundle.getMessage(ExtractIE.class, "ExtractIE.moduleName.text");
89  moduleTempResultsDir = RAImageIngestModule.getRATempPath(Case.getCurrentCaseThrows(), "IE") + File.separator + "results"; //NON-NLS
90  JAVA_PATH = PlatformUtil.getJavaPath();
91  }
92 
93  @Override
94  public void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
95  this.dataSource = dataSource;
96  this.context = context;
97  dataFound = false;
98 
99  progressBar.progress(Bundle.Progress_Message_IE_Bookmarks());
100  this.getBookmark();
101 
102  progressBar.progress(Bundle.Progress_Message_IE_Cookies());
103  this.getCookie();
104 
105  progressBar.progress(Bundle.Progress_Message_IE_History());
106  this.getHistory();
107  }
108 
112  private void getBookmark() {
113  org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager();
114  List<AbstractFile> favoritesFiles;
115  try {
116  favoritesFiles = fileManager.findFiles(dataSource, "%.url", "Favorites"); //NON-NLS
117  } catch (TskCoreException ex) {
118  logger.log(Level.WARNING, "Error fetching 'url' files for Internet Explorer bookmarks.", ex); //NON-NLS
119  this.addErrorMessage(
120  NbBundle.getMessage(this.getClass(), "ExtractIE.getBookmark.errMsg.errGettingBookmarks",
121  this.getName()));
122  return;
123  }
124 
125  if (favoritesFiles.isEmpty()) {
126  logger.log(Level.INFO, "Didn't find any IE bookmark files."); //NON-NLS
127  return;
128  }
129 
130  dataFound = true;
131  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
132  for (AbstractFile fav : favoritesFiles) {
133  if (fav.getSize() == 0) {
134  continue;
135  }
136 
137  if (context.dataSourceIngestIsCancelled()) {
138  break;
139  }
140 
141  String url = getURLFromIEBookmarkFile(fav);
142 
143  String name = fav.getName();
144  Long datetime = fav.getCrtime();
145  String Tempdate = datetime.toString();
146  datetime = Long.valueOf(Tempdate);
147  String domain = extractDomain(url);
148 
149  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
150  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
151  RecentActivityExtracterModuleFactory.getModuleName(), url));
152  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE,
153  RecentActivityExtracterModuleFactory.getModuleName(), name));
154  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
155  RecentActivityExtracterModuleFactory.getModuleName(), datetime));
156  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
157  RecentActivityExtracterModuleFactory.getModuleName(),
158  NbBundle.getMessage(this.getClass(), "ExtractIE.moduleName.text")));
159  if (domain != null && domain.isEmpty() == false) {
160  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
161  RecentActivityExtracterModuleFactory.getModuleName(), domain));
162  }
163 
164  BlackboardArtifact bbart = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_BOOKMARK, fav, bbattributes);
165  if (bbart != null) {
166  bbartifacts.add(bbart);
167  }
168  }
169 
170  postArtifacts(bbartifacts);
171  }
172 
173  private String getURLFromIEBookmarkFile(AbstractFile fav) {
174  BufferedReader reader = new BufferedReader(new InputStreamReader(new ReadContentInputStream(fav)));
175  String line, url = "";
176  try {
177  line = reader.readLine();
178  while (null != line) {
179  // The actual shortcut line we are interested in is of the
180  // form URL=http://path/to/website
181  if (line.startsWith("URL")) { //NON-NLS
182  url = line.substring(line.indexOf("=") + 1);
183  break;
184  }
185  line = reader.readLine();
186  }
187  } catch (IOException ex) {
188  logger.log(Level.WARNING, "Failed to read from content: " + fav.getName(), ex); //NON-NLS
189  this.addErrorMessage(
190  NbBundle.getMessage(this.getClass(), "ExtractIE.getURLFromIEBmkFile.errMsg", this.getName(),
191  fav.getName()));
192  } catch (IndexOutOfBoundsException ex) {
193  logger.log(Level.WARNING, "Failed while getting URL of IE bookmark. Unexpected format of the bookmark file: " + fav.getName(), ex); //NON-NLS
194  this.addErrorMessage(
195  NbBundle.getMessage(this.getClass(), "ExtractIE.getURLFromIEBmkFile.errMsg2", this.getName(),
196  fav.getName()));
197  } finally {
198  try {
199  reader.close();
200  } catch (IOException ex) {
201  logger.log(Level.WARNING, "Failed to close reader.", ex); //NON-NLS
202  }
203  }
204 
205  return url;
206  }
207 
211  private void getCookie() {
212  org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager();
213  List<AbstractFile> cookiesFiles;
214  try {
215  cookiesFiles = fileManager.findFiles(dataSource, "%.txt", "Cookies"); //NON-NLS
216  } catch (TskCoreException ex) {
217  logger.log(Level.WARNING, "Error getting cookie files for IE"); //NON-NLS
218  this.addErrorMessage(
219  NbBundle.getMessage(this.getClass(), "ExtractIE.getCookie.errMsg.errGettingFile", this.getName()));
220  return;
221  }
222 
223  if (cookiesFiles.isEmpty()) {
224  logger.log(Level.INFO, "Didn't find any IE cookies files."); //NON-NLS
225  return;
226  }
227 
228  dataFound = true;
229  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
230  for (AbstractFile cookiesFile : cookiesFiles) {
231  if (context.dataSourceIngestIsCancelled()) {
232  break;
233  }
234  if (cookiesFile.getSize() == 0) {
235  continue;
236  }
237 
238  byte[] t = new byte[(int) cookiesFile.getSize()];
239  try {
240  final int bytesRead = cookiesFile.read(t, 0, cookiesFile.getSize());
241  } catch (TskCoreException ex) {
242  logger.log(Level.WARNING, "Error reading bytes of Internet Explorer cookie.", ex); //NON-NLS
243  this.addErrorMessage(
244  NbBundle.getMessage(this.getClass(), "ExtractIE.getCookie.errMsg.errReadingIECookie",
245  this.getName(), cookiesFile.getName()));
246  continue;
247  }
248  String cookieString = new String(t);
249  String[] values = cookieString.split("\n");
250  String url = values.length > 2 ? values[2] : "";
251  String value = values.length > 1 ? values[1] : "";
252  String name = values.length > 0 ? values[0] : "";
253  Long datetime = cookiesFile.getCrtime();
254  String tempDate = datetime.toString();
255  datetime = Long.valueOf(tempDate);
256  String domain = extractDomain(url);
257 
258  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
259  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
260  RecentActivityExtracterModuleFactory.getModuleName(), url));
261  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME,
262  RecentActivityExtracterModuleFactory.getModuleName(), datetime));
263  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
264  RecentActivityExtracterModuleFactory.getModuleName(), (name != null) ? name : ""));
265  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE,
266  RecentActivityExtracterModuleFactory.getModuleName(), value));
267  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
268  RecentActivityExtracterModuleFactory.getModuleName(),
269  NbBundle.getMessage(this.getClass(), "ExtractIE.moduleName.text")));
270  if (domain != null && domain.isEmpty() == false) {
271  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
272  RecentActivityExtracterModuleFactory.getModuleName(), domain));
273  }
274  BlackboardArtifact bbart = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_COOKIE, cookiesFile, bbattributes);
275  if (bbart != null) {
276  bbartifacts.add(bbart);
277  }
278  }
279 
280  postArtifacts(bbartifacts);
281  }
282 
286  private void getHistory() {
287  logger.log(Level.INFO, "Pasco results path: {0}", moduleTempResultsDir); //NON-NLS
288  boolean foundHistory = false;
289 
290  final File pascoRoot = InstalledFileLocator.getDefault().locate("pasco2", ExtractIE.class.getPackage().getName(), false); //NON-NLS
291  if (pascoRoot == null) {
292  this.addErrorMessage(
293  NbBundle.getMessage(this.getClass(), "ExtractIE.getHistory.errMsg.unableToGetHist", this.getName()));
294  logger.log(Level.SEVERE, "Error finding pasco program "); //NON-NLS
295  return;
296  }
297 
298  final String pascoHome = pascoRoot.getAbsolutePath();
299  logger.log(Level.INFO, "Pasco2 home: {0}", pascoHome); //NON-NLS
300 
301  PASCO_LIB_PATH = pascoHome + File.separator + "pasco2.jar" + File.pathSeparator //NON-NLS
302  + pascoHome + File.separator + "*";
303 
304  File resultsDir = new File(moduleTempResultsDir);
305  resultsDir.mkdirs();
306 
307  // get index.dat files
308  FileManager fileManager = currentCase.getServices().getFileManager();
309  List<AbstractFile> indexFiles;
310  try {
311  indexFiles = fileManager.findFiles(dataSource, "index.dat"); //NON-NLS
312  } catch (TskCoreException ex) {
313  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "ExtractIE.getHistory.errMsg.errGettingHistFiles",
314  this.getName()));
315  logger.log(Level.WARNING, "Error fetching 'index.data' files for Internet Explorer history."); //NON-NLS
316  return;
317  }
318 
319  if (indexFiles.isEmpty()) {
320  String msg = NbBundle.getMessage(this.getClass(), "ExtractIE.getHistory.errMsg.noHistFiles");
321  logger.log(Level.INFO, msg);
322  return;
323  }
324 
325  dataFound = true;
326  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
327  String temps;
328  String indexFileName;
329  for (AbstractFile indexFile : indexFiles) {
330  // Since each result represent an index.dat file,
331  // just create these files with the following notation:
332  // index<Number>.dat (i.e. index0.dat, index1.dat,..., indexN.dat)
333  // where <Number> is the obj_id of the file.
334  // Write each index.dat file to a temp directory.
335  //BlackboardArtifact bbart = fsc.newArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY);
336  indexFileName = "index" + Integer.toString((int) indexFile.getId()) + ".dat"; //NON-NLS
337  //indexFileName = "index" + Long.toString(bbart.getArtifactID()) + ".dat";
338  temps = RAImageIngestModule.getRATempPath(currentCase, "IE") + File.separator + indexFileName; //NON-NLS
339  File datFile = new File(temps);
340  if (context.dataSourceIngestIsCancelled()) {
341  break;
342  }
343  try {
344  ContentUtils.writeToFile(indexFile, datFile, context::dataSourceIngestIsCancelled);
345  } catch (IOException e) {
346  logger.log(Level.WARNING, "Error while trying to write index.dat file " + datFile.getAbsolutePath(), e); //NON-NLS
347  this.addErrorMessage(
348  NbBundle.getMessage(this.getClass(), "ExtractIE.getHistory.errMsg.errWriteFile", this.getName(),
349  datFile.getAbsolutePath()));
350  continue;
351  }
352 
353  String filename = "pasco2Result." + indexFile.getId() + ".txt"; //NON-NLS
354  boolean bPascProcSuccess = executePasco(temps, filename);
355  if (context.dataSourceIngestIsCancelled()) {
356  return;
357  }
358 
359  //At this point pasco2 proccessed the index files.
360  //Now fetch the results, parse them and the delete the files.
361  if (bPascProcSuccess) {
362  // Don't add TSK_OS_ACCOUNT artifacts to the ModuleDataEvent
363  bbartifacts.addAll(parsePascoOutput(indexFile, filename).stream()
364  .filter(bbart -> bbart.getArtifactTypeID() == ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID())
365  .collect(Collectors.toList()));
366  if (context.dataSourceIngestIsCancelled()) {
367  return;
368  }
369  foundHistory = true;
370 
371  //Delete index<n>.dat file since it was succcessfully by Pasco
372  datFile.delete();
373  } else {
374  logger.log(Level.WARNING, "pasco execution failed on: {0}", filename); //NON-NLS
375  this.addErrorMessage(
376  NbBundle.getMessage(this.getClass(), "ExtractIE.getHistory.errMsg.errProcHist", this.getName()));
377  }
378  }
379 
380  postArtifacts(bbartifacts);
381  }
382 
391  private boolean executePasco(String indexFilePath, String outputFileName) {
392  boolean success = true;
393  try {
394  final String outputFileFullPath = moduleTempResultsDir + File.separator + outputFileName;
395  final String errFileFullPath = moduleTempResultsDir + File.separator + outputFileName + ".err"; //NON-NLS
396  logger.log(Level.INFO, "Writing pasco results to: {0}", outputFileFullPath); //NON-NLS
397  List<String> commandLine = new ArrayList<>();
398  commandLine.add(JAVA_PATH);
399  commandLine.add("-cp"); //NON-NLS
400  commandLine.add(PASCO_LIB_PATH);
401  commandLine.add("isi.pasco2.Main"); //NON-NLS
402  commandLine.add("-T"); //NON-NLS
403  commandLine.add("history"); //NON-NLS
404  commandLine.add(indexFilePath);
405  ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
406  processBuilder.redirectOutput(new File(outputFileFullPath));
407  processBuilder.redirectError(new File(errFileFullPath));
408  /*
409  * NOTE on Pasco return codes: There is no documentation for Pasco.
410  * Looking at the Pasco source code I see that when something goes
411  * wrong Pasco returns a negative number as a return code. However,
412  * we should still attempt to parse the Pasco output even if that
413  * happens. I have seen many situations where Pasco output file
414  * contains a lot of useful data and only the last entry is
415  * corrupted.
416  */
417  ExecUtil.execute(processBuilder, new DataSourceIngestModuleProcessTerminator(context));
418  // @@@ Investigate use of history versus cache as type.
419  } catch (IOException ex) {
420  success = false;
421  logger.log(Level.SEVERE, "Unable to execute Pasco to process Internet Explorer web history.", ex); //NON-NLS
422  }
423  return success;
424  }
425 
435  private Collection<BlackboardArtifact> parsePascoOutput(AbstractFile origFile, String pascoOutputFileName) {
436 
437  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
438  String fnAbs = moduleTempResultsDir + File.separator + pascoOutputFileName;
439 
440  File file = new File(fnAbs);
441  if (file.exists() == false) {
442  this.addErrorMessage(
443  NbBundle.getMessage(this.getClass(), "ExtractIE.parsePascoOutput.errMsg.notFound", this.getName(),
444  file.getName()));
445  logger.log(Level.WARNING, "Pasco Output not found: {0}", file.getPath()); //NON-NLS
446  return bbartifacts;
447  }
448 
449  // Make sure the file the is not empty or the Scanner will
450  // throw a "No Line found" Exception
451  if (file.length() == 0) {
452  return bbartifacts;
453  }
454 
455  Scanner fileScanner;
456  try {
457  fileScanner = new Scanner(new FileInputStream(file.toString()));
458  } catch (FileNotFoundException ex) {
459  this.addErrorMessage(
460  NbBundle.getMessage(this.getClass(), "ExtractIE.parsePascoOutput.errMsg.errParsing", this.getName(),
461  file.getName()));
462  logger.log(Level.WARNING, "Unable to find the Pasco file at " + file.getPath(), ex); //NON-NLS
463  return bbartifacts;
464  }
465  while (fileScanner.hasNext()) {
466 
467  if (context.dataSourceIngestIsCancelled()) {
468  return bbartifacts;
469  }
470 
471  String line = fileScanner.nextLine();
472  if (!line.startsWith("URL")) { //NON-NLS
473  continue;
474  }
475 
476  String[] lineBuff = line.split("\\t"); //NON-NLS
477 
478  if (lineBuff.length < 4) {
479  logger.log(Level.INFO, "Found unrecognized IE history format."); //NON-NLS
480  continue;
481  }
482 
483  String actime = lineBuff[3];
484  Long ftime = (long) 0;
485  String user = "";
486  String realurl = null;
487  String domain;
488 
489  /*
490  * We've seen two types of lines: URL http://XYZ.com .... URL
491  * Visited: Joe@http://XYZ.com ....
492  */
493  if (lineBuff[1].contains("@")) {
494  String url[] = lineBuff[1].split("@", 2);
495 
496  /*
497  * Verify the left portion of the URL is valid.
498  */
499  domain = extractDomain(url[0]);
500 
501  if (domain != null && domain.isEmpty() == false) {
502  /*
503  * Use the entire input for the URL.
504  */
505  realurl = lineBuff[1].trim();
506  } else {
507  /*
508  * Use the left portion of the input for the user, and the
509  * right portion for the host.
510  */
511  user = url[0];
512  user = user.replace("Visited:", ""); //NON-NLS
513  user = user.replace(":Host:", ""); //NON-NLS
514  user = user.replaceAll("(:)(.*?)(:)", "");
515  user = user.trim();
516  realurl = url[1];
517  realurl = realurl.replace("Visited:", ""); //NON-NLS
518  realurl = realurl.replaceAll(":(.*?):", "");
519  realurl = realurl.replace(":Host:", ""); //NON-NLS
520  realurl = realurl.trim();
521  domain = extractDomain(realurl);
522  }
523  } else {
524  /*
525  * Use the entire input for the URL.
526  */
527  realurl = lineBuff[1].trim();
528  domain = extractDomain(realurl);
529  }
530 
531  if (!actime.isEmpty()) {
532  try {
533  Long epochtime = dateFormatter.parse(actime).getTime();
534  ftime = epochtime / 1000;
535  } catch (ParseException e) {
536  this.addErrorMessage(
537  NbBundle.getMessage(this.getClass(), "ExtractIE.parsePascoOutput.errMsg.errParsingEntry",
538  this.getName()));
539  logger.log(Level.WARNING, String.format("Error parsing Pasco results, may have partial processing of corrupt file (id=%d)", origFile.getId()), e); //NON-NLS
540  }
541  }
542 
543  try {
544  BlackboardArtifact bbart = origFile.newArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY);
545  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
546  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,
547  RecentActivityExtracterModuleFactory.getModuleName(), realurl));
548  //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", EscapeUtil.decodeURL(realurl)));
549 
550  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
551  RecentActivityExtracterModuleFactory.getModuleName(), ftime));
552  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER,
553  RecentActivityExtracterModuleFactory.getModuleName(), ""));
554  // @@@ NOte that other browser modules are adding TITLE in hre for the title
555  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME,
556  RecentActivityExtracterModuleFactory.getModuleName(),
557  NbBundle.getMessage(this.getClass(),
558  "ExtractIE.moduleName.text")));
559  if (domain != null && domain.isEmpty() == false) {
560  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN,
561  RecentActivityExtracterModuleFactory.getModuleName(), domain));
562  }
563  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
564  RecentActivityExtracterModuleFactory.getModuleName(), user));
565  bbart.addAttributes(bbattributes);
566 
567  bbartifacts.add(bbart);
568  } catch (TskCoreException ex) {
569  logger.log(Level.SEVERE, "Error writing Internet Explorer web history artifact to the blackboard. Pasco results will be incomplete", ex); //NON-NLS
570  }
571  }
572  fileScanner.close();
573  return bbartifacts;
574  }
575 
584  private String extractDomain(String url) {
585  if (url == null || url.isEmpty()) {
586  return url;
587  }
588 
589  if (url.toLowerCase().startsWith(RESOURCE_URL_PREFIX)) {
590  /*
591  * Ignore URLs that begin with the matched text.
592  */
593  return null;
594  }
595 
596  return NetworkUtils.extractDomain(url);
597  }
598 }
synchronized List< AbstractFile > findFiles(String fileName)

Copyright © 2012-2020 Basis Technology. Generated on: Mon Jul 6 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.