Autopsy  4.16.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
TableReportGenerator.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2013-2020 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
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.report.infrastructure;
20 
22 import com.google.common.collect.ListMultimap;
23 import com.google.common.collect.Lists;
24 import com.google.common.collect.Multimaps;
25 import java.sql.ResultSet;
26 import java.sql.SQLException;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.Comparator;
32 import java.util.HashMap;
33 import java.util.HashSet;
34 import java.util.Iterator;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Objects;
38 import java.util.Set;
39 import java.util.TreeSet;
40 import java.util.logging.Level;
41 import org.openide.util.NbBundle;
42 import org.openide.util.NbBundle.Messages;
51 import org.sleuthkit.datamodel.AbstractFile;
52 import org.sleuthkit.datamodel.Account;
53 import org.sleuthkit.datamodel.BlackboardArtifact;
54 import org.sleuthkit.datamodel.BlackboardArtifactTag;
55 import org.sleuthkit.datamodel.BlackboardAttribute;
56 import org.sleuthkit.datamodel.BlackboardAttribute.Type;
57 import org.sleuthkit.datamodel.Content;
58 import org.sleuthkit.datamodel.ContentTag;
59 import org.sleuthkit.datamodel.SleuthkitCase;
60 import org.sleuthkit.datamodel.TagName;
61 import org.sleuthkit.datamodel.TskCoreException;
62 import org.sleuthkit.datamodel.TskData;
63 
64 class TableReportGenerator {
65 
66  private List<BlackboardArtifact.Type> artifactTypes = new ArrayList<>();
67  private HashSet<String> tagNamesFilter = new HashSet<>();
68 
69  private final Set<Content> images = new HashSet<>();
70  private final ReportProgressPanel progressPanel;
71  private final TableReportModule tableReport;
72  private final TableReportSettings settings;
73  private final Map<Integer, List<Column>> columnHeaderMap;
74  private static final Logger logger = Logger.getLogger(TableReportGenerator.class.getName());
75 
76  private final List<String> errorList;
77 
78  TableReportGenerator(TableReportSettings settings, ReportProgressPanel progressPanel, TableReportModule tableReport) {
79 
80  this.progressPanel = progressPanel;
81  this.tableReport = tableReport;
82  this.columnHeaderMap = new HashMap<>();
83  errorList = new ArrayList<>();
84  this.settings = settings;
85  }
86 
87  private void getAllExistingTags() throws NoCurrentCaseException, TskCoreException {
88  List<String> tagNames = new ArrayList<>();
89 
90  // get all tag names from this case
91  List<TagName> tagNamesInUse = Case.getCurrentCaseThrows().getServices().getTagsManager().getTagNamesInUse();
92 
93  String notableString = "";
94  for (TagName tagName : tagNamesInUse) {
95  notableString = tagName.getKnownStatus() == TskData.FileKnown.BAD ? TagsManager.getNotableTagLabel() : "";
96  tagNames.add(tagName.getDisplayName() + notableString);
97  }
98  tagNamesFilter = new HashSet<>(tagNames);
99  }
100 
101  @SuppressWarnings("deprecation")
102  private void getAllExistingArtiactTypes() throws NoCurrentCaseException, TskCoreException {
103  // get all possible artifact types
104  ArrayList<BlackboardArtifact.Type> doNotReport = new ArrayList<>();
105  doNotReport.add(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID(),
106  BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getLabel(),
107  BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getDisplayName()));
108  doNotReport.add(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getTypeID(),
109  BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getLabel(),
110  BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getDisplayName())); // output is too unstructured for table review
111  doNotReport.add(new BlackboardArtifact.Type(
112  BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT.getTypeID(),
113  BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT.getLabel(),
114  BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT.getDisplayName()));
115  doNotReport.add(new BlackboardArtifact.Type(
116  BlackboardArtifact.ARTIFACT_TYPE.TSK_TL_EVENT.getTypeID(),
117  BlackboardArtifact.ARTIFACT_TYPE.TSK_TL_EVENT.getLabel(),
118  BlackboardArtifact.ARTIFACT_TYPE.TSK_TL_EVENT.getDisplayName()));
119 
120  Case.getCurrentCaseThrows().getSleuthkitCase().getArtifactTypes().forEach(artifactTypes::add);
121  artifactTypes.removeAll(doNotReport);
122  }
123 
124  protected void execute() {
125 
126  progressPanel.start();
127  progressPanel.updateStatusLabel(NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.readingTagsArtifacts.text"));
128 
129  if (settings.useStoredTagsAndArtifactsLists()) {
130  // Get the artifact types selected by the user.
131  artifactTypes = settings.getArtifactSelections();
132 
133  // Get the tag names selected by the user and make a tag names filter.
134  tagNamesFilter = new HashSet<>(settings.getTagSelections());
135  } else {
136  try {
137  // If report type is "all tagged results", then read all possible tab names from database.
138  // Otherwise do not load tag names, i.e. run "all results" report
139  if (settings.getSelectedReportOption() == TableReportSettings.TableReportOption.ALL_TAGGED_RESULTS) {
140  getAllExistingTags();
141  }
142 
143  // get all possible artifact types
144  getAllExistingArtiactTypes();
145  } catch (NoCurrentCaseException | TskCoreException ex) {
146  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetAllTagsArtifacts"));
147  logger.log(Level.SEVERE, "Failed get all possible tag names and artifact types", ex); //NON-NLS
148  return;
149  }
150  }
151 
152  // Start the progress indicators for each active TableReportModule.
153  progressPanel.setIndeterminate(false);
154  progressPanel.setMaximumProgress(this.artifactTypes.size() + 2); // +2 for content and blackboard artifact tags
155 
156  // report on the blackboard results
157  if (progressPanel.getStatus() != ReportProgressPanel.ReportStatus.CANCELED) {
158  makeBlackboardArtifactTables();
159  }
160 
161  // report on the tagged files and artifacts
162  if (progressPanel.getStatus() != ReportProgressPanel.ReportStatus.CANCELED) {
163  makeContentTagsTables();
164  }
165 
166  if (progressPanel.getStatus() != ReportProgressPanel.ReportStatus.CANCELED) {
167  makeBlackboardArtifactTagsTables();
168  }
169 
170  if (progressPanel.getStatus() != ReportProgressPanel.ReportStatus.CANCELED) {
171  // report on the tagged images
172  makeThumbnailTable();
173  }
174  }
175 
179  private void makeBlackboardArtifactTables() {
180  // Make a comment string describing the tag names filter in effect.
181  String comment = "";
182  if (!tagNamesFilter.isEmpty()) {
183  comment += NbBundle.getMessage(this.getClass(), "ReportGenerator.artifactTable.taggedResults.text");
184  comment += makeCommaSeparatedList(tagNamesFilter);
185  }
186 
187  // Add a table to the report for every enabled blackboard artifact type.
188  for (BlackboardArtifact.Type type : artifactTypes) {
189  // Check for cancellaton.
190 
191  if (progressPanel.getStatus() == ReportProgressPanel.ReportStatus.CANCELED) {
192  return;
193  }
194 
195  progressPanel.updateStatusLabel(
196  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processing",
197  type.getDisplayName()));
198 
199  // Keyword hits and hashset hit artifacts get special handling.
200  if (type.getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
201  writeKeywordHits(tableReport, comment, tagNamesFilter);
202  continue;
203  } else if (type.getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) {
204  writeHashsetHits(tableReport, comment, tagNamesFilter);
205  continue;
206  }
207 
208  List<ArtifactData> artifactList = getFilteredArtifacts(type, tagNamesFilter);
209 
210  if (artifactList.isEmpty()) {
211  continue;
212  }
213 
214  /*
215  * TSK_ACCOUNT artifacts get grouped by their TSK_ACCOUNT_TYPE
216  * attribute, and then handed off to the standard method for writing
217  * tables.
218  */
219  if (type.getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()) {
220  //Group account artifacts by their account type
221  ListMultimap<String, ArtifactData> groupedArtifacts = Multimaps.index(artifactList,
222  artifactData -> {
223  try {
224  return artifactData.getArtifact().getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE)).getValueString();
225  } catch (TskCoreException ex) {
226  logger.log(Level.SEVERE, "Unable to get value of TSK_ACCOUNT_TYPE attribute. Defaulting to \"unknown\"", ex);
227  return "unknown";
228  }
229  });
230  for (String accountTypeStr : groupedArtifacts.keySet()) {
231  /*
232  * If the report is a HTMLReport, the data type name
233  * eventualy makes it to useDataTypeIcon which expects but
234  * does not require a artifact name, so we make a synthetic
235  * compund name by appending a ":" and the account type.
236  */
237  String accountDisplayname = accountTypeStr;
238  if (accountTypeStr != null) {
239  try {
240  Account.Type acctType = Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager().getAccountType(accountTypeStr);
241  if (acctType != null) {
242  accountDisplayname = acctType.getDisplayName();
243  }
244  } catch (TskCoreException | NoCurrentCaseException ex) {
245  logger.log(Level.SEVERE, "Unable to get display name for account type " + accountTypeStr, ex);
246  }
247  }
248 
249  final String compundDataTypeName = BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getDisplayName() + ": " + accountDisplayname;
250  writeTableForDataType(new ArrayList<>(groupedArtifacts.get(accountTypeStr)), type, compundDataTypeName, comment);
251  }
252  } else {
253  //all other artifact types are sent to writeTableForDataType directly
254  writeTableForDataType(artifactList, type, type.getDisplayName(), comment);
255  }
256  }
257  }
258 
269  private void writeTableForDataType(List<ArtifactData> artifactList, BlackboardArtifact.Type type, String tableName, String comment) {
270  /*
271  * Make a sorted set of all of the attribute types that are on any of
272  * the given artifacts.
273  */
274  Set<BlackboardAttribute.Type> attrTypeSet = new TreeSet<>(Comparator.comparing(BlackboardAttribute.Type::getDisplayName));
275  for (ArtifactData data : artifactList) {
276  List<BlackboardAttribute> attributes = data.getAttributes();
277  for (BlackboardAttribute attribute : attributes) {
278  attrTypeSet.add(attribute.getAttributeType());
279  }
280  }
281  /*
282  * Get the columns appropriate for the artifact type. This is used to
283  * get the data that will be in the cells below based on type, and
284  * display the column headers.
285  */
286  List<Column> columns = getArtifactTableColumns(type.getTypeID(), attrTypeSet);
287  if (columns.isEmpty()) {
288  return;
289  }
290  columnHeaderMap.put(type.getTypeID(), columns);
291 
292  /*
293  * The artifact list is sorted now, as getting the row data is dependent
294  * on having the columns, which is necessary for sorting.
295  */
296  Collections.sort(artifactList);
297 
298  tableReport.startDataType(tableName, comment);
299  tableReport.startTable(Lists.transform(columns, Column::getColumnHeader));
300 
301  for (ArtifactData artifactData : artifactList) {
302  // Get the row data for this artifact, and has the
303  // module add it.
304  List<String> rowData = artifactData.getRow();
305  if (rowData.isEmpty()) {
306  return;
307  }
308 
309  tableReport.addRow(rowData);
310  }
311  // Finish up this data type
312  progressPanel.increment();
313  tableReport.endTable();
314  tableReport.endDataType();
315  }
316 
320  @Messages({"ReportGenerator.tagTable.header.userName=User Name"})
321  @SuppressWarnings("deprecation")
322  private void makeContentTagsTables() {
323 
324  // Get the content tags.
325  List<ContentTag> tags;
326  try {
327  tags = Case.getCurrentCaseThrows().getServices().getTagsManager().getAllContentTags();
328  } catch (TskCoreException | NoCurrentCaseException ex) {
329  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetContentTags"));
330  logger.log(Level.SEVERE, "failed to get content tags", ex); //NON-NLS
331  return;
332  }
333 
334  // Tell the modules reporting on content tags is beginning.
335  // @@@ This casting is a tricky little workaround to allow the HTML report module to slip in a content hyperlink.
336  // @@@ Alos Using the obsolete ARTIFACT_TYPE.TSK_TAG_FILE is also an expedient hack.
337  progressPanel.updateStatusLabel(
338  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processing",
339  BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getDisplayName()));
340  ArrayList<String> columnHeaders = new ArrayList<>(Arrays.asList(
341  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.tag"),
342  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.file"),
343  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.comment"),
344  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.userName"),
345  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.timeModified"),
346  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.timeChanged"),
347  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.timeAccessed"),
348  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.timeCreated"),
349  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.size"),
350  NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.hash")));
351 
352  StringBuilder comment = new StringBuilder();
353  if (!tagNamesFilter.isEmpty()) {
354  comment.append(
355  NbBundle.getMessage(this.getClass(), "ReportGenerator.makeContTagTab.taggedFiles.msg"));
356  comment.append(makeCommaSeparatedList(tagNamesFilter));
357  }
358  if (tableReport instanceof HTMLReport) {
359  HTMLReport htmlReportModule = (HTMLReport) tableReport;
360  htmlReportModule.startDataType(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getDisplayName(), comment.toString());
361  htmlReportModule.startContentTagsTable(columnHeaders);
362  } else {
363  tableReport.startDataType(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getDisplayName(), comment.toString());
364  tableReport.startTable(columnHeaders);
365  }
366 
367  // Give the modules the rows for the content tags.
368  for (ContentTag tag : tags) {
369  try {
370  if(shouldFilterFromReport(tag.getContent())) {
371  continue;
372  }
373  } catch (TskCoreException ex) {
374  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetContentTags"));
375  logger.log(Level.SEVERE, "Failed to access content data from the case database.", ex); //NON-NLS
376  return;
377  }
378 
379  // skip tags that we are not reporting on
380  String notableString = tag.getName().getKnownStatus() == TskData.FileKnown.BAD ? TagsManager.getNotableTagLabel() : "";
381  if (passesTagNamesFilter(tag.getName().getDisplayName() + notableString) == false) {
382  continue;
383  }
384 
385  String fileName;
386  try {
387  fileName = tag.getContent().getUniquePath();
388  } catch (TskCoreException ex) {
389  fileName = tag.getContent().getName();
390  }
391 
392  ArrayList<String> rowData = new ArrayList<>(Arrays.asList(tag.getName().getDisplayName() + notableString, fileName, tag.getComment(), tag.getUserName()));
393  Content content = tag.getContent();
394  if (content instanceof AbstractFile) {
395  AbstractFile file = (AbstractFile) content;
396 
397  // Add metadata about the file to HTML output
398  rowData.add(file.getMtimeAsDate());
399  rowData.add(file.getCtimeAsDate());
400  rowData.add(file.getAtimeAsDate());
401  rowData.add(file.getCrtimeAsDate());
402  rowData.add(Long.toString(file.getSize()));
403  rowData.add(file.getMd5Hash());
404  }
405  // @@@ This casting is a tricky little workaround to allow the HTML report module to slip in a content hyperlink.
406  if (tableReport instanceof HTMLReport) {
407  HTMLReport htmlReportModule = (HTMLReport) tableReport;
408  htmlReportModule.addRowWithTaggedContentHyperlink(rowData, tag);
409  } else {
410  tableReport.addRow(rowData);
411  }
412 
413  // see if it is for an image so that we later report on it
414  checkIfTagHasImage(tag);
415  }
416 
417  // The the modules content tags reporting is ended.
418  progressPanel.increment();
419  tableReport.endTable();
420  tableReport.endDataType();
421  }
422 
426  @SuppressWarnings("deprecation")
427  @Messages({
428  "ReportGenerator.errList.failedGetBBArtifactTags=Failed to get result tags."
429  })
430  private void makeBlackboardArtifactTagsTables() {
431 
432  List<BlackboardArtifactTag> tags;
433  try {
434  tags = Case.getCurrentCaseThrows().getServices().getTagsManager().getAllBlackboardArtifactTags();
435  } catch (TskCoreException | NoCurrentCaseException ex) {
436  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetBBArtifactTags"));
437  logger.log(Level.SEVERE, "failed to get blackboard artifact tags", ex); //NON-NLS
438  return;
439  }
440 
441  // Tell the modules reporting on blackboard artifact tags data type is beginning.
442  // @@@ Using the obsolete ARTIFACT_TYPE.TSK_TAG_ARTIFACT is an expedient hack.
443  progressPanel.updateStatusLabel(
444  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processing",
445  BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getDisplayName()));
446  StringBuilder comment = new StringBuilder();
447  if (!tagNamesFilter.isEmpty()) {
448  comment.append(
449  NbBundle.getMessage(this.getClass(), "ReportGenerator.makeBbArtTagTab.taggedRes.msg"));
450  comment.append(makeCommaSeparatedList(tagNamesFilter));
451  }
452  tableReport.startDataType(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getDisplayName(), comment.toString());
453  tableReport.startTable(new ArrayList<>(Arrays.asList(
454  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.resultType"),
455  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.tag"),
456  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.comment"),
457  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.srcFile"),
458  NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.userName"))));
459 
460  // Give the modules the rows for the content tags.
461  for (BlackboardArtifactTag tag : tags) {
462  try {
463  if(shouldFilterFromReport(tag.getContent())) {
464  continue;
465  }
466  } catch (TskCoreException ex) {
467  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetBBArtifactTags"));
468  logger.log(Level.SEVERE, "Failed to access content data from the case database.", ex); //NON-NLS
469  return;
470  }
471 
472  String notableString = tag.getName().getKnownStatus() == TskData.FileKnown.BAD ? TagsManager.getNotableTagLabel() : "";
473  if (passesTagNamesFilter(tag.getName().getDisplayName() + notableString) == false) {
474  continue;
475  }
476 
477  List<String> row;
478  row = new ArrayList<>(Arrays.asList(tag.getArtifact().getArtifactTypeName(), tag.getName().getDisplayName() + notableString,
479  tag.getComment(), tag.getContent().getName(), tag.getUserName()));
480  tableReport.addRow(row);
481 
482  // check if the tag is an image that we should later make a thumbnail for
483  checkIfTagHasImage(tag);
484  }
485 
486  // The the modules blackboard artifact tags reporting is ended.
487  progressPanel.increment();
488  tableReport.endTable();
489  tableReport.endDataType();
490  }
491 
499  private boolean passesTagNamesFilter(String tagName) {
500  return tagNamesFilter.isEmpty() || tagNamesFilter.contains(tagName);
501  }
502 
506  private void makeThumbnailTable() {
507  progressPanel.updateStatusLabel(
508  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.createdThumb.text"));
509 
510  if (tableReport instanceof HTMLReport) {
511  HTMLReport htmlModule = (HTMLReport) tableReport;
512  htmlModule.startDataType(
513  NbBundle.getMessage(this.getClass(), "ReportGenerator.thumbnailTable.name"),
514  NbBundle.getMessage(this.getClass(), "ReportGenerator.thumbnailTable.desc"));
515  List<String> emptyHeaders = new ArrayList<>();
516  for (int i = 0; i < HTMLReport.THUMBNAIL_COLUMNS; i++) {
517  emptyHeaders.add("");
518  }
519  htmlModule.startTable(emptyHeaders);
520 
521  htmlModule.addThumbnailRows(images);
522 
523  htmlModule.endTable();
524  htmlModule.endDataType();
525  }
526 
527  }
528 
535  private void checkIfTagHasImage(BlackboardArtifactTag artifactTag) {
536  AbstractFile file;
537  try {
538  file = Case.getCurrentCaseThrows().getSleuthkitCase().getAbstractFileById(artifactTag.getArtifact().getObjectID());
539  } catch (TskCoreException | NoCurrentCaseException ex) {
540  errorList.add(
541  NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.errGetContentFromBBArtifact"));
542  logger.log(Level.WARNING, "Error while getting content from a blackboard artifact to report on.", ex); //NON-NLS
543  return;
544  }
545 
546  if (file != null) {
547  checkIfFileIsImage(file);
548  }
549  }
550 
558  private void checkIfTagHasImage(ContentTag contentTag) {
559  Content c = contentTag.getContent();
560  if (c instanceof AbstractFile == false) {
561  return;
562  }
563  checkIfFileIsImage((AbstractFile) c);
564  }
565 
571  private void checkIfFileIsImage(AbstractFile file) {
572 
573  if (file.isDir()
574  || file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS
575  || file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS) {
576  return;
577  }
578 
579  if (ImageUtils.thumbnailSupported(file)) {
580  images.add(file);
581  }
582  }
583 
592  private String makeCommaSeparatedList(Collection<String> items) {
593  String list = "";
594  for (Iterator<String> iterator = items.iterator(); iterator.hasNext();) {
595  list += iterator.next() + (iterator.hasNext() ? ", " : "");
596  }
597  return list;
598  }
599 
605  @SuppressWarnings("deprecation")
606  @NbBundle.Messages({"ReportGenerator.errList.noOpenCase=No open case available."})
607  private void writeKeywordHits(TableReportModule tableModule, String comment, HashSet<String> tagNamesFilter) {
608 
609  // Query for keyword lists-only so that we can tell modules what lists
610  // will exist for their index.
611  // @@@ There is a bug in here. We should use the tags in the below code
612  // so that we only report the lists that we will later provide with real
613  // hits. If no keyord hits are tagged, then we make the page for nothing.
614  String orderByClause;
615  Case openCase;
616  try {
617  openCase = Case.getCurrentCaseThrows();
618  } catch (NoCurrentCaseException ex) {
619  errorList.add(Bundle.ReportGenerator_errList_noOpenCase());
620  logger.log(Level.SEVERE, "Exception while getting open case: ", ex); //NON-NLS
621  return;
622  }
623 
624  // Get a list of all selected tag IDs
625  String tagIDList = "";
626  if (!tagNamesFilter.isEmpty()) {
627  try {
628  Map<String, TagName> tagNamesMap = Case.getCurrentCaseThrows().getServices().getTagsManager().getDisplayNamesToTagNamesMap();
629  for (String tagDisplayName : tagNamesFilter) {
630  if (tagNamesMap.containsKey(tagDisplayName)) {
631  if (!tagIDList.isEmpty()) {
632  tagIDList += ",";
633  }
634  tagIDList += tagNamesMap.get(tagDisplayName).getId();
635  } else {
636  // If the tag name ends with "(Notable)", try stripping that off
637  if (tagDisplayName.endsWith(getNotableTagLabel())) {
638  String editedDisplayName = tagDisplayName.substring(0, tagDisplayName.length() - getNotableTagLabel().length());
639  if (tagNamesMap.containsKey(editedDisplayName)) {
640  if (!tagIDList.isEmpty()) {
641  tagIDList += ",";
642  }
643  tagIDList += tagNamesMap.get(editedDisplayName).getId();
644  }
645  }
646  }
647  }
648  } catch (NoCurrentCaseException | TskCoreException ex) {
649  logger.log(Level.SEVERE, "Exception while getting tag info - proceeding without tag filter: ", ex); //NON-NLS
650  tagIDList = "";
651  }
652  }
653 
654  // Check if there are any ad-hoc results
655  String adHocCountQuery = "SELECT COUNT(*) FROM "
656  + //NON-NLS
657  "(SELECT art.artifact_id FROM blackboard_artifacts AS art, blackboard_attributes AS att1 ";//NON-NLS
658  if (!tagIDList.isEmpty()) {
659  adHocCountQuery += ", blackboard_artifact_tags as tag "; //NON-NLS
660  }
661  adHocCountQuery += "WHERE (att1.artifact_id = art.artifact_id) AND (art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + ") "; // NON-NLS
662  if (!tagIDList.isEmpty()) {
663  adHocCountQuery += " AND (art.artifact_id = tag.artifact_id) AND (tag.tag_name_id IN (" + tagIDList + ")) "; //NON-NLS
664  }
665  adHocCountQuery += "EXCEPT "
666  + // NON-NLS
667  "SELECT art.artifact_id FROM blackboard_artifacts AS art, blackboard_attributes AS att1 WHERE (att1.artifact_id = art.artifact_id) AND (art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + ") AND (att1.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + ")) AS adHocHits"; //NON-NLS
668 
669  int adHocCount = 0;
670  try (SleuthkitCase.CaseDbQuery dbQuery = openCase.getSleuthkitCase().executeQuery(adHocCountQuery)) {
671  ResultSet adHocCountResultSet = dbQuery.getResultSet();
672  if (adHocCountResultSet.next()) {
673  adHocCount = adHocCountResultSet.getInt(1); //NON-NLS
674  } else {
675  throw new TskCoreException("Error counting ad hoc keywords");
676  }
677  } catch (TskCoreException | SQLException ex) {
678  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedQueryKWLists"));
679  logger.log(Level.SEVERE, "Failed to count ad hoc searches with query " + adHocCountQuery, ex); //NON-NLS
680  return;
681  }
682 
683  // Create the query to get the keyword list names
684  if (openCase.getCaseType() == Case.CaseType.MULTI_USER_CASE) {
685  orderByClause = "ORDER BY convert_to(list, 'SQL_ASCII') ASC NULLS FIRST"; //NON-NLS
686  } else {
687  orderByClause = "ORDER BY list ASC"; //NON-NLS
688  }
689  String keywordListQuery
690  = "SELECT att.value_text AS list "
691  + //NON-NLS
692  "FROM blackboard_attributes AS att, blackboard_artifacts AS art "; // NON-NLS
693  if (!tagIDList.isEmpty()) {
694  keywordListQuery += ", blackboard_artifact_tags as tag "; //NON-NLS
695  }
696  keywordListQuery += "WHERE att.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + " "
697  + //NON-NLS
698  "AND art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + " "
699  + //NON-NLS
700  "AND att.artifact_id = art.artifact_id ";
701  if (!tagIDList.isEmpty()) {
702  keywordListQuery += "AND (art.artifact_id = tag.artifact_id) "
703  + //NON-NLS
704  "AND (tag.tag_name_id IN (" + tagIDList + ")) "; //NON-NLS
705  }
706  if (adHocCount > 0) {
707  keywordListQuery += " UNION SELECT \'\' AS list ";
708  }
709  keywordListQuery = "SELECT * FROM ( " + keywordListQuery + " ) kwListNames ";
710  keywordListQuery += "GROUP BY list " + orderByClause; //NON-NLS
711 
712  // Make the table of contents links for each list type
713  try (SleuthkitCase.CaseDbQuery dbQuery = openCase.getSleuthkitCase().executeQuery(keywordListQuery)) {
714  ResultSet listsRs = dbQuery.getResultSet();
715  List<String> lists = new ArrayList<>();
716  while (listsRs.next()) {
717  String list = listsRs.getString("list"); //NON-NLS
718  if (list.isEmpty()) {
719  list = NbBundle.getMessage(this.getClass(), "ReportGenerator.writeKwHits.userSrchs");
720  }
721  lists.add(list);
722  }
723 
724  // Make keyword data type and give them set index
725  tableModule.startDataType(BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName(), comment);
726  tableModule.addSetIndex(lists);
727  progressPanel.updateStatusLabel(
728  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processing",
729  BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName()));
730  } catch (TskCoreException | SQLException ex) {
731  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedQueryKWLists"));
732  logger.log(Level.SEVERE, "Failed to query keyword lists with query " + keywordListQuery, ex); //NON-NLS
733  return;
734  }
735 
736  // Query for keywords, grouped by list
737  if (openCase.getCaseType() == Case.CaseType.MULTI_USER_CASE) {
738  orderByClause = "ORDER BY convert_to(list, 'SQL_ASCII') ASC NULLS FIRST, " //NON-NLS
739  + "convert_to(keyword, 'SQL_ASCII') ASC NULLS FIRST, " //NON-NLS
740  + "convert_to(parent_path, 'SQL_ASCII') ASC NULLS FIRST, " //NON-NLS
741  + "convert_to(name, 'SQL_ASCII') ASC NULLS FIRST, " //NON-NLS
742  + "convert_to(preview, 'SQL_ASCII') ASC NULLS FIRST"; //NON-NLS
743  } else {
744  orderByClause = "ORDER BY list ASC, keyword ASC, parent_path ASC, name ASC, preview ASC"; //NON-NLS
745  }
746 
747  // Query for keywords that are part of a list
748  String keywordListsQuery
749  = "SELECT art.artifact_id AS artifact_id, art.obj_id AS obj_id, att1.value_text AS keyword, att2.value_text AS preview, att3.value_text AS list, f.name AS name, f.parent_path AS parent_path "
750  + //NON-NLS
751  "FROM blackboard_artifacts AS art, blackboard_attributes AS att1, blackboard_attributes AS att2, blackboard_attributes AS att3, tsk_files AS f "
752  + //NON-NLS
753  "WHERE (att1.artifact_id = art.artifact_id) "
754  + //NON-NLS
755  "AND (att2.artifact_id = art.artifact_id) "
756  + //NON-NLS
757  "AND (att3.artifact_id = art.artifact_id) "
758  + //NON-NLS
759  "AND (f.obj_id = art.obj_id) "
760  + //NON-NLS
761  "AND (att1.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID() + ") "
762  + //NON-NLS
763  "AND (att2.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID() + ") "
764  + //NON-NLS
765  "AND (att3.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + ") "
766  + //NON-NLS
767  "AND (art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + ") ";
768 
769  // Query for keywords that are not part of a list
770  String keywordAdHocQuery
771  = "SELECT art.artifact_id AS artifact_id, art.obj_id AS obj_id, att1.value_text AS keyword, att2.value_text AS preview, \'\' AS list, f.name AS name, f.parent_path AS parent_path "
772  + // NON-NLS
773  "FROM blackboard_artifacts AS art, blackboard_attributes AS att1, blackboard_attributes AS att2, tsk_files AS f "
774  + // NON-NLS
775  "WHERE "
776  + // NON-NLS
777  " (art.artifact_id IN (SELECT art.artifact_id FROM blackboard_artifacts AS art, blackboard_attributes AS att1 WHERE (att1.artifact_id = art.artifact_id) AND (art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + ") "
778  + // NON-NLS
779  "EXCEPT "
780  + // NON-NLS
781  "SELECT art.artifact_id FROM blackboard_artifacts AS art, blackboard_attributes AS att1 WHERE (att1.artifact_id = art.artifact_id) AND (art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + ") AND (att1.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + "))) "
782  + //NON-NLS
783  "AND (att1.artifact_id = art.artifact_id) "
784  + //NON-NLS
785  "AND (att2.artifact_id = art.artifact_id) "
786  + //NON-NLS
787  "AND (f.obj_id = art.obj_id) "
788  + //NON-NLS
789  "AND (att1.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID() + ") "
790  + // NON-NLS
791  "AND (att2.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID() + ") "
792  + // NON-NLS
793  "AND (art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + ") "; // NON-NLS
794 
795  String keywordsQuery = "SELECT * FROM ( " + keywordListsQuery + " UNION " + keywordAdHocQuery + " ) kwHits " + orderByClause;
796 
797  try (SleuthkitCase.CaseDbQuery dbQuery = openCase.getSleuthkitCase().executeQuery(keywordsQuery)) {
798  ResultSet resultSet = dbQuery.getResultSet();
799 
800  String currentKeyword = "";
801  String currentList = "";
802  while (resultSet.next()) {
803  // Check to see if all the TableReportModules have been canceled
804  if (progressPanel.getStatus() == ReportProgressPanel.ReportStatus.CANCELED) {
805  break;
806  }
807 
808  // Get any tags that associated with this artifact and apply the tag filter.
809  HashSet<String> uniqueTagNames = getUniqueTagNames(resultSet.getLong("artifact_id")); //NON-NLS
810  if (failsTagFilter(uniqueTagNames, tagNamesFilter)) {
811  continue;
812  }
813  String tagsList = makeCommaSeparatedList(uniqueTagNames);
814 
815  Long objId = resultSet.getLong("obj_id"); //NON-NLS
816  String keyword = resultSet.getString("keyword"); //NON-NLS
817  String preview = resultSet.getString("preview"); //NON-NLS
818  String list = resultSet.getString("list"); //NON-NLS
819  String uniquePath = "";
820 
821  try {
822  AbstractFile f = openCase.getSleuthkitCase().getAbstractFileById(objId);
823  if (f != null) {
824  uniquePath = openCase.getSleuthkitCase().getAbstractFileById(objId).getUniquePath();
825  if(shouldFilterFromReport(f)) {
826  continue;
827  }
828  }
829  } catch (TskCoreException ex) {
830  errorList.add(
831  NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetAbstractFileByID"));
832  logger.log(Level.WARNING, "Failed to get Abstract File by ID.", ex); //NON-NLS
833  }
834 
835  // If the lists aren't the same, we've started a new list
836  if ((!list.equals(currentList) && !list.isEmpty()) || (list.isEmpty() && !currentList.equals(
837  NbBundle.getMessage(this.getClass(), "ReportGenerator.writeKwHits.userSrchs")))) {
838  if (!currentList.isEmpty()) {
839  tableModule.endTable();
840  tableModule.endSet();
841  }
842  currentList = list.isEmpty() ? NbBundle
843  .getMessage(this.getClass(), "ReportGenerator.writeKwHits.userSrchs") : list;
844  currentKeyword = ""; // reset the current keyword because it's a new list
845  tableModule.startSet(currentList);
846  progressPanel.updateStatusLabel(
847  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processingList",
848  BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName(), currentList));
849  }
850  if (!keyword.equals(currentKeyword)) {
851  // End the previous table if one exists.
852  if (!currentKeyword.equals("")) {
853  tableModule.endTable();
854  }
855 
856  // Prepare for a new table.
857  currentKeyword = keyword;
858  tableModule.addSetElement(currentKeyword);
859  List<String> columnHeaderNames = new ArrayList<>();
860  columnHeaderNames.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.preview"));
861  columnHeaderNames.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile"));
862  columnHeaderNames.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tags"));
863  tableModule.startTable(columnHeaderNames);
864  }
865 
866  tableModule.addRow(Arrays.asList(new String[]{preview, uniquePath, tagsList}));
867  }
868 
869  // End the previous table if one exists.
870  if (!currentKeyword.isEmpty()) {
871  tableModule.endTable();
872  }
873 
874  // Finish the current data type
875  progressPanel.increment();
876  tableModule.endDataType();
877  } catch (TskCoreException | SQLException ex) {
878  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedQueryKWs"));
879  logger.log(Level.SEVERE, "Failed to query keywords with query " + keywordsQuery, ex); //NON-NLS
880  }
881  }
882 
888  @SuppressWarnings("deprecation")
889  private void writeHashsetHits(TableReportModule tableModule, String comment, HashSet<String> tagNamesFilter) {
890  String orderByClause;
891  Case openCase;
892  try {
893  openCase = Case.getCurrentCaseThrows();
894  } catch (NoCurrentCaseException ex) {
895  errorList.add(Bundle.ReportGenerator_errList_noOpenCase());
896  logger.log(Level.SEVERE, "Exception while getting open case: ", ex); //NON-NLS
897  return;
898  }
899  if (openCase.getCaseType() == Case.CaseType.MULTI_USER_CASE) {
900  orderByClause = "ORDER BY convert_to(att.value_text, 'SQL_ASCII') ASC NULLS FIRST"; //NON-NLS
901  } else {
902  orderByClause = "ORDER BY att.value_text ASC"; //NON-NLS
903  }
904  String hashsetsQuery
905  = "SELECT att.value_text AS list "
906  + //NON-NLS
907  "FROM blackboard_attributes AS att, blackboard_artifacts AS art "
908  + //NON-NLS
909  "WHERE att.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + " "
910  + //NON-NLS
911  "AND art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() + " "
912  + //NON-NLS
913  "AND att.artifact_id = art.artifact_id "
914  + //NON-NLS
915  "GROUP BY list " + orderByClause; //NON-NLS
916 
917  try (SleuthkitCase.CaseDbQuery dbQuery = openCase.getSleuthkitCase().executeQuery(hashsetsQuery)) {
918  // Query for hashsets
919  ResultSet listsRs = dbQuery.getResultSet();
920  List<String> lists = new ArrayList<>();
921  while (listsRs.next()) {
922  lists.add(listsRs.getString("list")); //NON-NLS
923  }
924 
925  tableModule.startDataType(BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName(), comment);
926  tableModule.addSetIndex(lists);
927  progressPanel.updateStatusLabel(
928  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processing",
929  BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName()));
930  } catch (TskCoreException | SQLException ex) {
931  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedQueryHashsetLists"));
932  logger.log(Level.SEVERE, "Failed to query hashset lists: ", ex); //NON-NLS
933  return;
934  }
935 
936  if (openCase.getCaseType() == Case.CaseType.MULTI_USER_CASE) {
937  orderByClause = "ORDER BY convert_to(att.value_text, 'SQL_ASCII') ASC NULLS FIRST, " //NON-NLS
938  + "convert_to(f.parent_path, 'SQL_ASCII') ASC NULLS FIRST, " //NON-NLS
939  + "convert_to(f.name, 'SQL_ASCII') ASC NULLS FIRST, " //NON-NLS
940  + "size ASC NULLS FIRST"; //NON-NLS
941  } else {
942  orderByClause = "ORDER BY att.value_text ASC, f.parent_path ASC, f.name ASC, size ASC"; //NON-NLS
943  }
944  String hashsetHitsQuery
945  = "SELECT art.artifact_id, art.obj_id, att.value_text AS setname, f.name AS name, f.size AS size, f.parent_path AS parent_path "
946  + //NON-NLS
947  "FROM blackboard_artifacts AS art, blackboard_attributes AS att, tsk_files AS f "
948  + //NON-NLS
949  "WHERE (att.artifact_id = art.artifact_id) "
950  + //NON-NLS
951  "AND (f.obj_id = art.obj_id) "
952  + //NON-NLS
953  "AND (att.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + ") "
954  + //NON-NLS
955  "AND (art.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() + ") "
956  + //NON-NLS
957  orderByClause; //NON-NLS
958 
959  try (SleuthkitCase.CaseDbQuery dbQuery = openCase.getSleuthkitCase().executeQuery(hashsetHitsQuery)) {
960  // Query for hashset hits
961  ResultSet resultSet = dbQuery.getResultSet();
962  String currentSet = "";
963  while (resultSet.next()) {
964  // Check to see if all the TableReportModules have been canceled
965  if (progressPanel.getStatus() == ReportProgressPanel.ReportStatus.CANCELED) {
966  break;
967  }
968 
969  // Get any tags that associated with this artifact and apply the tag filter.
970  HashSet<String> uniqueTagNames = getUniqueTagNames(resultSet.getLong("artifact_id")); //NON-NLS
971  if (failsTagFilter(uniqueTagNames, tagNamesFilter)) {
972  continue;
973  }
974  String tagsList = makeCommaSeparatedList(uniqueTagNames);
975 
976  Long objId = resultSet.getLong("obj_id"); //NON-NLS
977  String set = resultSet.getString("setname"); //NON-NLS
978  String size = resultSet.getString("size"); //NON-NLS
979  String uniquePath = "";
980 
981  try {
982  AbstractFile f = openCase.getSleuthkitCase().getAbstractFileById(objId);
983  if (f != null) {
984  uniquePath = openCase.getSleuthkitCase().getAbstractFileById(objId).getUniquePath();
985  if(shouldFilterFromReport(f)) {
986  continue;
987  }
988  }
989  } catch (TskCoreException ex) {
990  errorList.add(
991  NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetAbstractFileFromID"));
992  logger.log(Level.WARNING, "Failed to get Abstract File from ID.", ex); //NON-NLS
993  return;
994  }
995 
996  // If the sets aren't the same, we've started a new set
997  if (!set.equals(currentSet)) {
998  if (!currentSet.isEmpty()) {
999  tableModule.endTable();
1000  tableModule.endSet();
1001  }
1002  currentSet = set;
1003  tableModule.startSet(currentSet);
1004  List<String> columnHeaderNames = new ArrayList<>();
1005  columnHeaderNames.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.file"));
1006  columnHeaderNames.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.size"));
1007  columnHeaderNames.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tags"));
1008  tableModule.startTable(columnHeaderNames);
1009  progressPanel.updateStatusLabel(
1010  NbBundle.getMessage(this.getClass(), "ReportGenerator.progress.processingList",
1011  BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName(), currentSet));
1012  }
1013 
1014  // Add a row for this hit to every module
1015  tableModule.addRow(Arrays.asList(new String[]{uniquePath, size, tagsList}));
1016  }
1017 
1018  // Finish the current data type
1019  progressPanel.increment();
1020  tableModule.endDataType();
1021  } catch (TskCoreException | SQLException ex) {
1022  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedQueryHashsetHits"));
1023  logger.log(Level.SEVERE, "Failed to query hashsets hits: ", ex); //NON-NLS
1024  }
1025  }
1026 
1030  List<String> getErrorList() {
1031  return errorList;
1032  }
1033 
1038  private class ArtifactData implements Comparable<ArtifactData> {
1039 
1040  private BlackboardArtifact artifact;
1041  private List<BlackboardAttribute> attributes;
1042  private HashSet<String> tags;
1043  private List<String> rowData = null;
1044  private Content content;
1045 
1046  ArtifactData(BlackboardArtifact artifact, List<BlackboardAttribute> attrs, HashSet<String> tags) {
1047  this.artifact = artifact;
1048  this.attributes = attrs;
1049  this.tags = tags;
1050  try {
1051  this.content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID());
1052  } catch (TskCoreException | NoCurrentCaseException ex) {
1053  logger.log(Level.SEVERE, "Could not get content from database", ex);
1054  }
1055  }
1056 
1057  public BlackboardArtifact getArtifact() {
1058  return artifact;
1059  }
1060 
1061  public List<BlackboardAttribute> getAttributes() {
1062  return attributes;
1063  }
1064 
1065  public HashSet<String> getTags() {
1066  return tags;
1067  }
1068 
1069  public long getArtifactID() {
1070  return artifact.getArtifactID();
1071  }
1072 
1073  public long getObjectID() {
1074  return artifact.getObjectID();
1075  }
1076 
1080  public Content getContent() {
1081  return content;
1082  }
1083 
1093  @Override
1094  public int compareTo(ArtifactData otherArtifactData) {
1095  List<String> thisRow = getRow();
1096  List<String> otherRow = otherArtifactData.getRow();
1097  for (int i = 0; i < thisRow.size(); i++) {
1098  int compare = thisRow.get(i).compareTo(otherRow.get(i));
1099  if (compare != 0) {
1100  return compare;
1101  }
1102  }
1103  return ((Long) this.getArtifactID()).compareTo(otherArtifactData.getArtifactID());
1104  }
1105 
1113  public List<String> getRow() {
1114  if (rowData == null) {
1115  try {
1116  rowData = getOrderedRowDataAsStrings();
1117  // If else is done so that row data is not set before
1118  // columns are added to the hash map.
1119  if (rowData.size() > 0) {
1120  // replace null values if attribute was not defined
1121  for (int i = 0; i < rowData.size(); i++) {
1122  if (rowData.get(i) == null) {
1123  rowData.set(i, "");
1124  }
1125  }
1126  } else {
1127  rowData = null;
1128  return new ArrayList<>();
1129  }
1130  } catch (TskCoreException ex) {
1131  errorList.add(
1132  NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.coreExceptionWhileGenRptRow"));
1133  logger.log(Level.WARNING, "Core exception while generating row data for artifact report.", ex); //NON-NLS
1134  rowData = Collections.<String>emptyList();
1135  }
1136  }
1137  return rowData;
1138  }
1139 
1149  private List<String> getOrderedRowDataAsStrings() throws TskCoreException {
1150 
1151  List<String> orderedRowData = new ArrayList<>();
1152  if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID() == getArtifact().getArtifactTypeID()) {
1153  if (content != null && content instanceof AbstractFile) {
1154  AbstractFile file = (AbstractFile) content;
1155  orderedRowData.add(file.getName());
1156  orderedRowData.add(file.getNameExtension());
1157  String mimeType = file.getMIMEType();
1158  if (mimeType == null) {
1159  orderedRowData.add("");
1160  } else {
1161  orderedRowData.add(mimeType);
1162  }
1163  orderedRowData.add(file.getUniquePath());
1164  } else {
1165  // Make empty rows to make sure the formatting is correct
1166  orderedRowData.add(null);
1167  orderedRowData.add(null);
1168  orderedRowData.add(null);
1169  orderedRowData.add(null);
1170  }
1171  orderedRowData.add(makeCommaSeparatedList(getTags()));
1172 
1173  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() == getArtifact().getArtifactTypeID()) {
1174  String[] attributeDataArray = new String[5];
1175  // Array is used so that order of the attributes is maintained.
1176  for (BlackboardAttribute attr : attributes) {
1177  if (attr.getAttributeType().equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME))) {
1178  attributeDataArray[0] = attr.getDisplayString();
1179  } else if (attr.getAttributeType().equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY))) {
1180  attributeDataArray[1] = attr.getDisplayString();
1181  } else if (attr.getAttributeType().equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT))) {
1182  attributeDataArray[3] = attr.getDisplayString();
1183  } else if (attr.getAttributeType().equals(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION))) {
1184  attributeDataArray[4] = attr.getDisplayString();
1185  }
1186  }
1187 
1188  attributeDataArray[2] = content.getUniquePath();
1189  orderedRowData.addAll(Arrays.asList(attributeDataArray));
1190 
1191  HashSet<String> allTags = getTags();
1192  try {
1193  List<ContentTag> contentTags = Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(content);
1194  for (ContentTag ct : contentTags) {
1195  String notableString = ct.getName().getKnownStatus() == TskData.FileKnown.BAD ? TagsManager.getNotableTagLabel() : "";
1196  allTags.add(ct.getName().getDisplayName() + notableString);
1197  }
1198  } catch (TskCoreException | NoCurrentCaseException ex) {
1199  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetContentTags"));
1200  logger.log(Level.SEVERE, "Failed to get content tags", ex); //NON-NLS
1201  }
1202  orderedRowData.add(makeCommaSeparatedList(allTags));
1203 
1204  } else if (columnHeaderMap.containsKey(this.artifact.getArtifactTypeID())) {
1205 
1206  for (Column currColumn : columnHeaderMap.get(this.artifact.getArtifactTypeID())) {
1207  String cellData = currColumn.getCellData(this);
1208  orderedRowData.add(cellData);
1209  }
1210  }
1211 
1212  return orderedRowData;
1213  }
1214 
1215  }
1216 
1226  private List<ArtifactData> getFilteredArtifacts(BlackboardArtifact.Type type, HashSet<String> tagNamesFilter) {
1227  List<ArtifactData> artifacts = new ArrayList<>();
1228  try {
1229  for (BlackboardArtifact artifact : Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardArtifacts(type.getTypeID())) {
1230  if(shouldFilterFromReport(artifact)) {
1231  continue;
1232  }
1233 
1234  List<BlackboardArtifactTag> tags = Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact);
1235  HashSet<String> uniqueTagNames = new HashSet<>();
1236  for (BlackboardArtifactTag tag : tags) {
1237  String notableString = tag.getName().getKnownStatus() == TskData.FileKnown.BAD ? TagsManager.getNotableTagLabel() : "";
1238  uniqueTagNames.add(tag.getName().getDisplayName() + notableString);
1239  }
1240  if (failsTagFilter(uniqueTagNames, tagNamesFilter)) {
1241  continue;
1242  }
1243  try {
1244  artifacts.add(new ArtifactData(artifact, Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardAttributes(artifact), uniqueTagNames));
1245  } catch (TskCoreException ex) {
1246  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetBBAttribs"));
1247  logger.log(Level.SEVERE, "Failed to get Blackboard Attributes when generating report.", ex); //NON-NLS
1248  }
1249  }
1250  } catch (TskCoreException | NoCurrentCaseException ex) {
1251  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetBBArtifacts"));
1252  logger.log(Level.SEVERE, "Failed to get Blackboard Artifacts when generating report.", ex); //NON-NLS
1253  }
1254  return artifacts;
1255  }
1256 
1257  private Boolean failsTagFilter(HashSet<String> tagNames, HashSet<String> tagsNamesFilter) {
1258  if (null == tagsNamesFilter || tagsNamesFilter.isEmpty()) {
1259  return false;
1260  }
1261 
1262  HashSet<String> filteredTagNames = new HashSet<>(tagNames);
1263  filteredTagNames.retainAll(tagsNamesFilter);
1264  return filteredTagNames.isEmpty();
1265  }
1266 
1277  @Messages({"ReportGenerator.artTableColHdr.comment=Comment"})
1278  @SuppressWarnings("deprecation")
1279  private List<Column> getArtifactTableColumns(int artifactTypeId, Set<BlackboardAttribute.Type> attributeTypeSet) {
1280  ArrayList<Column> columns = new ArrayList<>();
1281 
1282  // Long switch statement to retain ordering of attribute types that are
1283  // attached to pre-defined artifact types.
1284  if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID() == artifactTypeId) {
1285  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.url"),
1286  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)));
1287 
1288  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.title"),
1289  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE)));
1290 
1291  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateCreated"),
1292  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED)));
1293 
1294  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1295  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1296 
1297  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID() == artifactTypeId) {
1298  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.url"),
1299  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)));
1300 
1301  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1302  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1303 
1304  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1305  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1306 
1307  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.value"),
1308  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE)));
1309 
1310  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1311  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1312 
1313  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID() == artifactTypeId) {
1314  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.url"),
1315  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)));
1316 
1317  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateAccessed"),
1318  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED)));
1319 
1320  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.referrer"),
1321  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REFERRER)));
1322 
1323  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.title"),
1324  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE)));
1325 
1326  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1327  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1328 
1329  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.urlDomainDecoded"),
1330  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL_DECODED)));
1331 
1332  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == artifactTypeId) {
1333  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dest"),
1334  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)));
1335 
1336  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.sourceUrl"),
1337  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)));
1338 
1339  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateAccessed"),
1340  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED)));
1341 
1342  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1343  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1344 
1345  attributeTypeSet.remove(new Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID));
1346  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == artifactTypeId) {
1347  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.path"),
1348  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)));
1349 
1350  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1351  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1352 
1353  attributeTypeSet.remove(new Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID));
1354  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID() == artifactTypeId) {
1355  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.progName"),
1356  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1357 
1358  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.instDateTime"),
1359  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1360 
1361  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() == artifactTypeId) {
1362  columns.add(new HeaderOnlyColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.preview")));
1363 
1364  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() == artifactTypeId) {
1365  columns.add(new SourceFileColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.file")));
1366 
1367  columns.add(new HeaderOnlyColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.size")));
1368 
1369  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID() == artifactTypeId) {
1370  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.devMake"),
1371  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE)));
1372 
1373  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.devModel"),
1374  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL)));
1375 
1376  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.deviceId"),
1377  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID)));
1378 
1379  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1380  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1381 
1382  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID() == artifactTypeId) {
1383  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.text"),
1384  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT)));
1385 
1386  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.domain"),
1387  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN)));
1388 
1389  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateAccessed"),
1390  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED)));
1391 
1392  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.progName"),
1393  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1394 
1395  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID() == artifactTypeId) {
1396  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTaken"),
1397  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED)));
1398 
1399  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.devManufacturer"),
1400  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE)));
1401 
1402  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.devModel"),
1403  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL)));
1404 
1405  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitude"),
1406  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE)));
1407 
1408  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitude"),
1409  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE)));
1410 
1411  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.altitude"),
1412  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE)));
1413 
1414  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID() == artifactTypeId) {
1415  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.personName"),
1416  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1417 
1418  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.phoneNumber"),
1419  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)));
1420 
1421  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.phoneNumHome"),
1422  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_HOME)));
1423 
1424  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.phoneNumOffice"),
1425  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_OFFICE)));
1426 
1427  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.phoneNumMobile"),
1428  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_MOBILE)));
1429 
1430  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.email"),
1431  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL)));
1432 
1433  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == artifactTypeId) {
1434  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.msgType"),
1435  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE)));
1436 
1437  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.direction"),
1438  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION)));
1439 
1440  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.readStatus"),
1441  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_READ_STATUS)));
1442 
1443  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1444  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1445 
1446  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.fromPhoneNum"),
1447  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)));
1448 
1449  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.fromEmail"),
1450  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM)));
1451 
1452  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.toPhoneNum"),
1453  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)));
1454 
1455  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.toEmail"),
1456  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO)));
1457 
1458  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.subject"),
1459  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT)));
1460 
1461  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.text"),
1462  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT)));
1463 
1464  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() == artifactTypeId) {
1465  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.personName"),
1466  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1467 
1468  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.fromPhoneNum"),
1469  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)));
1470 
1471  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.toPhoneNum"),
1472  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)));
1473 
1474  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1475  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START)));
1476 
1477  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.direction"),
1478  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION)));
1479 
1480  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_CALENDAR_ENTRY.getTypeID() == artifactTypeId) {
1481  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.calendarEntryType"),
1482  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CALENDAR_ENTRY_TYPE)));
1483 
1484  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.description"),
1485  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION)));
1486 
1487  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.startDateTime"),
1488  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START)));
1489 
1490  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.endDateTime"),
1491  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END)));
1492 
1493  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.location"),
1494  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION)));
1495 
1496  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_SPEED_DIAL_ENTRY.getTypeID() == artifactTypeId) {
1497  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.shortCut"),
1498  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SHORTCUT)));
1499 
1500  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.personName"),
1501  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME_PERSON)));
1502 
1503  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.phoneNumber"),
1504  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)));
1505 
1506  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING.getTypeID() == artifactTypeId) {
1507  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.deviceName"),
1508  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_NAME)));
1509 
1510  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.deviceAddress"),
1511  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID)));
1512 
1513  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1514  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1515 
1516  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT.getTypeID() == artifactTypeId) {
1517  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitude"),
1518  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE)));
1519 
1520  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitude"),
1521  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE)));
1522 
1523  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1524  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1525 
1526  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID() == artifactTypeId) {
1527  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitude"),
1528  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE)));
1529 
1530  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitude"),
1531  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE)));
1532 
1533  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.altitude"),
1534  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE)));
1535 
1536  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1537  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1538 
1539  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.locationAddress"),
1540  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION)));
1541 
1542  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1543  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1544 
1545  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION.getTypeID() == artifactTypeId) {
1546  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitude"),
1547  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE)));
1548 
1549  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitude"),
1550  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE)));
1551 
1552  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.altitude"),
1553  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE)));
1554 
1555  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1556  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1557 
1558  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.locationAddress"),
1559  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION)));
1560 
1561  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1562  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1563 
1564  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_SEARCH.getTypeID() == artifactTypeId) {
1565  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitude"),
1566  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE)));
1567 
1568  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitude"),
1569  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE)));
1570 
1571  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.altitude"),
1572  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE)));
1573 
1574  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1575  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1576 
1577  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.locationAddress"),
1578  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION)));
1579 
1580  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1581  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1582 
1583  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_SERVICE_ACCOUNT.getTypeID() == artifactTypeId) {
1584  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.category"),
1585  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY)));
1586 
1587  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.userId"),
1588  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_ID)));
1589 
1590  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.password"),
1591  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PASSWORD)));
1592 
1593  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.personName"),
1594  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1595 
1596  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.appName"),
1597  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1598 
1599  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.url"),
1600  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)));
1601 
1602  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.appPath"),
1603  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)));
1604 
1605  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.description"),
1606  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION)));
1607 
1608  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.replytoAddress"),
1609  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_REPLYTO)));
1610 
1611  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.mailServer"),
1612  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SERVER_NAME)));
1613 
1614  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED.getTypeID() == artifactTypeId
1615  || BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED.getTypeID() == artifactTypeId) {
1616  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1617  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1618 
1619  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID() == artifactTypeId) {
1620  columns.add(new HeaderOnlyColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.file")));
1621 
1622  columns.add(new HeaderOnlyColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.extension.text")));
1623 
1624  columns.add(new HeaderOnlyColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.mimeType.text")));
1625 
1626  columns.add(new HeaderOnlyColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.path")));
1627 
1628  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO.getTypeID() == artifactTypeId) {
1629  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.processorArchitecture.text"),
1630  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE)));
1631 
1632  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.osName.text"),
1633  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1634 
1635  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.osInstallDate.text"),
1636  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1637 
1638  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == artifactTypeId) {
1639  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskEmailTo"),
1640  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO)));
1641 
1642  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskEmailFrom"),
1643  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM)));
1644 
1645  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskSubject"),
1646  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT)));
1647 
1648  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskDateTimeSent"),
1649  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT)));
1650 
1651  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskDateTimeRcvd"),
1652  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD)));
1653 
1654  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskPath"),
1655  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)));
1656 
1657  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskEmailCc"),
1658  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC)));
1659 
1660  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskEmailBcc"),
1661  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_BCC)));
1662 
1663  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskMsgId"),
1664  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MSG_ID)));
1665 
1666  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() == artifactTypeId) {
1667  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskSetName"),
1668  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME)));
1669 
1670  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskInterestingFilesCategory"),
1671  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY)));
1672 
1673  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskPath"),
1674  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)));
1675 
1676  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.comment"),
1677  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT)));
1678 
1679  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.description"),
1680  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION)));
1681 
1682  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID() == artifactTypeId) {
1683  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskGpsRouteCategory"),
1684  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY)));
1685 
1686  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1687  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1688 
1689  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitudeEnd"),
1690  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END)));
1691 
1692  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitudeEnd"),
1693  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END)));
1694 
1695  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.latitudeStart"),
1696  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START)));
1697 
1698  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.longitudeStart"),
1699  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START)));
1700 
1701  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.name"),
1702  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)));
1703 
1704  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.location"),
1705  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION)));
1706 
1707  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1708  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1709 
1710  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID() == artifactTypeId) {
1711  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tskSetName"),
1712  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME)));
1713 
1714  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.associatedArtifact"),
1715  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT)));
1716 
1717  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1718  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1719 
1720  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == artifactTypeId) {
1721  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.program"),
1722  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
1723 
1724  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.associatedArtifact"),
1725  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT)));
1726 
1727  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.dateTime"),
1728  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)));
1729 
1730  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.count"),
1731  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COUNT)));
1732 
1733  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_ACCOUNT.getTypeID() == artifactTypeId) {
1734  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.userName"),
1735  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME)));
1736 
1737  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.userId"),
1738  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_ID)));
1739 
1740  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_REMOTE_DRIVE.getTypeID() == artifactTypeId) {
1741  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.localPath"),
1742  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCAL_PATH)));
1743 
1744  columns.add(new AttributeColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.remotePath"),
1745  new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REMOTE_PATH)));
1746  } else if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()) {
1747  columns.add(new StatusColumn());
1748  attributeTypeSet.remove(new Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE));
1749  attributeTypeSet.remove(new Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
1750  attributeTypeSet.remove(new Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME));
1751  attributeTypeSet.remove(new Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID));
1752  } else if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID()) {
1753  attributeTypeSet.remove(new Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID));
1754  } else {
1755  // This is the case that it is a custom type. The reason an else is
1756  // necessary is to make sure that the source file column is added
1757  for (BlackboardAttribute.Type type : attributeTypeSet) {
1758  columns.add(new AttributeColumn(type.getDisplayName(), type));
1759  }
1760  columns.add(new SourceFileColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")));
1761  columns.add(new TaggedResultsColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tags")));
1762 
1763  // Short circuits to guarantee that the attribute types aren't added
1764  // twice.
1765  return columns;
1766  }
1767  // If it is an attribute column, it removes the attribute type of that
1768  // column from the set, so types are not reported more than once.
1769  for (Column column : columns) {
1770  attributeTypeSet = column.removeTypeFromSet(attributeTypeSet);
1771  }
1772  // Now uses the remaining types in the set to construct columns
1773  for (BlackboardAttribute.Type type : attributeTypeSet) {
1774  columns.add(new AttributeColumn(type.getDisplayName(), type));
1775  }
1776  // Source file column is added here for ordering purposes.
1777  if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()
1778  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()
1779  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()
1780  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
1781  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID()
1782  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()
1783  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()
1784  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()
1785  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID()
1786  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID()
1787  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()
1788  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID()
1789  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALENDAR_ENTRY.getTypeID()
1790  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_SPEED_DIAL_ENTRY.getTypeID()
1791  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING.getTypeID()
1792  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT.getTypeID()
1793  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID()
1794  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION.getTypeID()
1795  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_SEARCH.getTypeID()
1796  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_SERVICE_ACCOUNT.getTypeID()
1797  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED.getTypeID()
1798  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED.getTypeID()
1799  || artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO.getTypeID()) {
1800  columns.add(new SourceFileColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.srcFile")));
1801  }
1802  columns.add(new TaggedResultsColumn(NbBundle.getMessage(this.getClass(), "ReportGenerator.artTableColHdr.tags")));
1803 
1804  return columns;
1805  }
1806 
1814  private String getFileUniquePath(Content content) {
1815  try {
1816  if (content != null) {
1817  return content.getUniquePath();
1818  } else {
1819  return "";
1820  }
1821  } catch (TskCoreException ex) {
1822  errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedGetAbstractFileByID"));
1823  logger.log(Level.WARNING, "Failed to get Abstract File by ID.", ex); //NON-NLS
1824  }
1825  return "";
1826 
1827  }
1828 
1832  private boolean shouldFilterFromReport(Content content) throws TskCoreException {
1833  if(this.settings.getSelectedDataSources() == null) {
1834  return false;
1835  }
1836 
1837  long dataSourceId = content.getDataSource().getId();
1838  return !this.settings.getSelectedDataSources().contains(dataSourceId);
1839  }
1840 
1850  @SuppressWarnings("deprecation")
1851  private HashSet<String> getUniqueTagNames(long artifactId) throws TskCoreException {
1852  HashSet<String> uniqueTagNames = new HashSet<>();
1853 
1854  String query = "SELECT display_name, artifact_id, knownStatus FROM tag_names AS tn, blackboard_artifact_tags AS bat "
1855  + //NON-NLS
1856  "WHERE tn.tag_name_id = bat.tag_name_id AND bat.artifact_id = " + artifactId; //NON-NLS
1857 
1858  try (SleuthkitCase.CaseDbQuery dbQuery = Case.getCurrentCaseThrows().getSleuthkitCase().executeQuery(query)) {
1859  ResultSet tagNameRows = dbQuery.getResultSet();
1860  while (tagNameRows.next()) {
1861  String notableString = tagNameRows.getInt("knownStatus") == TskData.FileKnown.BAD.ordinal() ? getNotableTagLabel() : "";
1862  uniqueTagNames.add(tagNameRows.getString("display_name") + notableString); //NON-NLS
1863  }
1864  } catch (TskCoreException | SQLException | NoCurrentCaseException ex) {
1865  throw new TskCoreException("Error getting tag names for artifact: ", ex);
1866  }
1867 
1868  return uniqueTagNames;
1869 
1870  }
1871 
1872  private interface Column {
1873 
1874  String getColumnHeader();
1875 
1876  String getCellData(ArtifactData artData);
1877 
1878  Set<BlackboardAttribute.Type> removeTypeFromSet(Set<BlackboardAttribute.Type> types);
1879  }
1880 
1881  private class StatusColumn implements Column {
1882 
1883  @NbBundle.Messages("TableReportGenerator.StatusColumn.Header=Review Status")
1884  @Override
1885  public String getColumnHeader() {
1886  return Bundle.TableReportGenerator_StatusColumn_Header();
1887  }
1888 
1889  @Override
1890  public String getCellData(ArtifactData artData) {
1891  return artData.getArtifact().getReviewStatus().getDisplayName();
1892  }
1893 
1894  @Override
1895  public Set<BlackboardAttribute.Type> removeTypeFromSet(Set<BlackboardAttribute.Type> types) {
1896  // This column doesn't have a type, so nothing to remove
1897  return types;
1898  }
1899 
1900  }
1901 
1902  private class AttributeColumn implements Column {
1903 
1904  private final String columnHeader;
1905  private final BlackboardAttribute.Type attributeType;
1906 
1913  AttributeColumn(String columnHeader, BlackboardAttribute.Type attributeType) {
1914  this.columnHeader = Objects.requireNonNull(columnHeader);
1916  }
1917 
1918  @Override
1919  public String getColumnHeader() {
1920  return this.columnHeader;
1921  }
1922 
1923  @Override
1924  public String getCellData(ArtifactData artData) {
1925  List<BlackboardAttribute> attributes = artData.getAttributes();
1926  for (BlackboardAttribute attribute : attributes) {
1927  if (attribute.getAttributeType().equals(this.attributeType)) {
1928  if (attribute.getAttributeType().getValueType() != BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
1929  return attribute.getDisplayString();
1930  } else {
1931  return ContentUtils.getStringTime(attribute.getValueLong(), artData.getContent());
1932  }
1933  }
1934  }
1935  return "";
1936  }
1937 
1938  @Override
1939  public Set<BlackboardAttribute.Type> removeTypeFromSet(Set<BlackboardAttribute.Type> types) {
1940  types.remove(this.attributeType);
1941  return types;
1942  }
1943  }
1944 
1945  private class SourceFileColumn implements Column {
1946 
1947  private final String columnHeader;
1948 
1949  SourceFileColumn(String columnHeader) {
1950  this.columnHeader = columnHeader;
1951  }
1952 
1953  @Override
1954  public String getColumnHeader() {
1955  return this.columnHeader;
1956  }
1957 
1958  @Override
1959  public String getCellData(ArtifactData artData) {
1960  return getFileUniquePath(artData.getContent());
1961  }
1962 
1963  @Override
1964  public Set<BlackboardAttribute.Type> removeTypeFromSet(Set<BlackboardAttribute.Type> types) {
1965  // This column doesn't have a type, so nothing to remove
1966  return types;
1967  }
1968  }
1969 
1970  private class TaggedResultsColumn implements Column {
1971 
1972  private final String columnHeader;
1973 
1974  TaggedResultsColumn(String columnHeader) {
1975  this.columnHeader = columnHeader;
1976  }
1977 
1978  @Override
1979  public String getColumnHeader() {
1980  return this.columnHeader;
1981  }
1982 
1983  @Override
1984  public String getCellData(ArtifactData artData) {
1985  return makeCommaSeparatedList(artData.getTags());
1986  }
1987 
1988  @Override
1989  public Set<BlackboardAttribute.Type> removeTypeFromSet(Set<BlackboardAttribute.Type> types) {
1990  // This column doesn't have a type, so nothing to remove
1991  return types;
1992  }
1993  }
1994 
1995  private class HeaderOnlyColumn implements Column {
1996 
1997  private final String columnHeader;
1998 
1999  HeaderOnlyColumn(String columnHeader) {
2000  this.columnHeader = columnHeader;
2001  }
2002 
2003  @Override
2004  public String getColumnHeader() {
2005  return columnHeader;
2006  }
2007 
2008  @Override
2009  public String getCellData(ArtifactData artData) {
2010  throw new UnsupportedOperationException("Cannot get cell data of unspecified column");
2011  }
2012 
2013  @Override
2014  public Set<BlackboardAttribute.Type> removeTypeFromSet(Set<BlackboardAttribute.Type> types) {
2015  // This column doesn't have a type, so nothing to remove
2016  return types;
2017  }
2018  }
2019 }
Set< BlackboardAttribute.Type > removeTypeFromSet(Set< BlackboardAttribute.Type > types)
static String getStringTime(long epochSeconds, TimeZone tzone)
Set< BlackboardAttribute.Type > removeTypeFromSet(Set< BlackboardAttribute.Type > types)
List< ContentTag > getContentTagsByContent(Content content)
Set< BlackboardAttribute.Type > removeTypeFromSet(Set< BlackboardAttribute.Type > types)
Set< BlackboardAttribute.Type > removeTypeFromSet(Set< BlackboardAttribute.Type > types)
Set< BlackboardAttribute.Type > removeTypeFromSet(Set< BlackboardAttribute.Type > types)
Set< BlackboardAttribute.Type > removeTypeFromSet(Set< BlackboardAttribute.Type > types)

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