mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
introduce datamodel._private package and move some interfaces and classes there; create basic generic support for other account types; some renaming for clarity
This commit is contained in:
parent
bcdb16638b
commit
a39419393d
@ -18,6 +18,11 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.Accounts;
|
||||
import org.sleuthkit.autopsy.datamodel._private.FileTypeExtensionFilters;
|
||||
import org.sleuthkit.autopsy.datamodel._private.RecentFiles;
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.Children.Keys;
|
||||
import org.openide.nodes.Node;
|
||||
|
@ -1,98 +0,0 @@
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
import com.google.common.collect.RangeMap;
|
||||
import com.google.common.collect.TreeRangeMap;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVParser;
|
||||
import org.apache.commons.csv.CSVRecord;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
|
||||
public class BINMap {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(BINMap.class.getName());
|
||||
/**
|
||||
* Range Map from a (ranges of) B/IINs to data model object with details of
|
||||
* the B/IIN, ie, bank name, phone, url, visa/amex/mastercard/...,
|
||||
*/
|
||||
@GuardedBy("Accounts.class")
|
||||
private final static RangeMap<Integer, Accounts.IINRange> iinRanges = TreeRangeMap.create();
|
||||
|
||||
/**
|
||||
* Flag for if we have loaded the IINs from the file already.
|
||||
*/
|
||||
@GuardedBy("Accounts.class")
|
||||
private static boolean iinsLoaded = false;
|
||||
|
||||
/**
|
||||
* Load the IIN range information from disk. If the map has already been
|
||||
* initialized, don't load again.
|
||||
*/
|
||||
synchronized private static void loadIINRanges() {
|
||||
if (iinsLoaded == false) {
|
||||
try {
|
||||
InputStreamReader in = new InputStreamReader(Accounts.class.getResourceAsStream("ranges.csv")); //NON-NLS
|
||||
CSVParser rangesParser = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(in);
|
||||
|
||||
//parse each row and add to range map
|
||||
for (CSVRecord record : rangesParser) {
|
||||
|
||||
/**
|
||||
* Because ranges.csv allows both 6 and (the newer) 8 digit
|
||||
* IINs, but we need a consistent length for the range map,
|
||||
* we pad all the numbers out to 8 digits
|
||||
*/
|
||||
String start = StringUtils.rightPad(record.get("iin_start"), 8, "0"); //pad start with 0's //NON-NLS
|
||||
|
||||
//if there is no end listed, use start, since ranges will be closed.
|
||||
String end = StringUtils.defaultIfBlank(record.get("iin_end"), start); //NON-NLS
|
||||
end = StringUtils.rightPad(end, 8, "99"); //pad end with 9's //NON-NLS
|
||||
|
||||
final String numberLength = record.get("number_length"); //NON-NLS
|
||||
|
||||
try {
|
||||
Accounts.IINRange iinRange = new Accounts.IINRange(Integer.parseInt(start),
|
||||
Integer.parseInt(end),
|
||||
StringUtils.isBlank(numberLength) ? null : Integer.valueOf(numberLength),
|
||||
record.get("scheme"), //NON-NLS
|
||||
record.get("brand"), //NON-NLS
|
||||
record.get("type"), //NON-NLS
|
||||
record.get("country"), //NON-NLS
|
||||
record.get("bank_name"), //NON-NLS
|
||||
record.get("bank_url"), //NON-NLS
|
||||
record.get("bank_phone"), //NON-NLS
|
||||
record.get("bank_city")); //NON-NLS
|
||||
|
||||
iinRanges.put(Range.closed(iinRange.getIINstart(), iinRange.getIINend()), iinRange);
|
||||
|
||||
} catch (NumberFormatException numberFormatException) {
|
||||
LOGGER.log(Level.WARNING, "Failed to parse IIN range: " + record.toString(), numberFormatException); //NON-NLS
|
||||
}
|
||||
iinsLoaded = true;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.WARNING, "Failed to load IIN ranges form ranges.csv", ex); //NON-NLS
|
||||
MessageNotifyUtil.Notify.warn("Credit Card Number Discovery", "There was an error loading Bank Identification Number information. Accounts will not have their BINs identified.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an IINInfo object with details about the given IIN
|
||||
*
|
||||
* @param iin the IIN to get details of.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
synchronized static public Accounts.IINInfo getIINInfo(int iin) {
|
||||
loadIINRanges();
|
||||
return iinRanges.get(iin);
|
||||
}
|
||||
|
||||
}
|
@ -185,13 +185,13 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
ss = Sheet.createPropertiesSet();
|
||||
s.put(ss);
|
||||
}
|
||||
final String NO_DESCR = NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.noDesc.text");
|
||||
final String NO_DESCR = NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.noDesc.text");
|
||||
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
fillPropertyMap(map, artifact);
|
||||
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.srcFile.name"),
|
||||
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.srcFile.displayName"),
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.name"),
|
||||
NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.displayName"),
|
||||
NO_DESCR,
|
||||
this.getDisplayName()));
|
||||
|
||||
@ -222,13 +222,13 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
actualMimeType = ""; //NON-NLS
|
||||
}
|
||||
}
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.ext.name"),
|
||||
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.ext.displayName"),
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.name"),
|
||||
NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.displayName"),
|
||||
NO_DESCR,
|
||||
ext));
|
||||
ss.put(new NodeProperty<>(
|
||||
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.mimeType.name"),
|
||||
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.mimeType.displayName"),
|
||||
NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.name"),
|
||||
NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.displayName"),
|
||||
NO_DESCR,
|
||||
actualMimeType));
|
||||
}
|
||||
@ -243,32 +243,32 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
|
||||
if (sourcePath.isEmpty() == false) {
|
||||
ss.put(new NodeProperty<>(
|
||||
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.filePath.name"),
|
||||
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.filePath.displayName"),
|
||||
NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.name"),
|
||||
NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.displayName"),
|
||||
NO_DESCR,
|
||||
sourcePath));
|
||||
}
|
||||
|
||||
if (Arrays.asList(SHOW_FILE_METADATA).contains(artifactTypeId)) {
|
||||
AbstractFile file = associated instanceof AbstractFile ? (AbstractFile) associated : null;
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileModifiedTime.name"),
|
||||
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileModifiedTime.displayName"),
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"),
|
||||
NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"),
|
||||
"",
|
||||
file != null ? ContentUtils.getStringTime(file.getMtime(), file) : ""));
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.name"),
|
||||
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.displayName"),
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.name"),
|
||||
NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.displayName"),
|
||||
"",
|
||||
file != null ? ContentUtils.getStringTime(file.getCtime(), file) : ""));
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.name"),
|
||||
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.displayName"),
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.name"),
|
||||
NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.displayName"),
|
||||
"",
|
||||
file != null ? ContentUtils.getStringTime(file.getAtime(), file) : ""));
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.name"),
|
||||
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.displayName"),
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.name"),
|
||||
NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.displayName"),
|
||||
"",
|
||||
file != null ? ContentUtils.getStringTime(file.getCrtime(), file) : ""));
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.name"),
|
||||
NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.displayName"),
|
||||
ss.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"),
|
||||
NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"),
|
||||
"",
|
||||
associated.getSize()));
|
||||
}
|
||||
@ -287,8 +287,8 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
||||
|
||||
if (dataSourceStr.isEmpty() == false) {
|
||||
ss.put(new NodeProperty<>(
|
||||
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.dataSrc.name"),
|
||||
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.dataSrc.displayName"),
|
||||
NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.name"),
|
||||
NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.displayName"),
|
||||
NO_DESCR,
|
||||
dataSourceStr));
|
||||
}
|
||||
|
@ -118,17 +118,6 @@ FileSize.createSheet.filterType.displayName=Filter Type
|
||||
FileSize.createSheet.filterType.desc=no description
|
||||
FileSize.exception.notSupported.msg=Not supported for this type of Displayable Item\: {0}
|
||||
FileTypeChildren.exception.notSupported.msg=Not supported for this type of Displayable Item\: {0}
|
||||
FileTypeExtensionFilters.tskImgFilter.text=Images
|
||||
FileTypeExtensionFilters.tskVideoFilter.text=Videos
|
||||
FileTypeExtensionFilters.tskAudioFilter.text=Audio
|
||||
FileTypeExtensionFilters.tskArchiveFilter.text=Archives
|
||||
FileTypeExtensionFilters.tskDocumentFilter.text=Documents
|
||||
FileTypeExtensionFilters.tskExecFilter.text=Executable
|
||||
FileTypeExtensionFilters.autDocHtmlFilter.text=HTML
|
||||
FileTypeExtensionFilters.autDocOfficeFilter.text=Office
|
||||
FileTypeExtensionFilters.autoDocPdfFilter.text=PDF
|
||||
FileTypeExtensionFilters.autDocTxtFilter.text=Plain Text
|
||||
FileTypeExtensionFilters.autDocRtfFilter.text=Rich Text
|
||||
FileTypeNode.createSheet.filterType.name=Filter Type
|
||||
FileTypeNode.createSheet.filterType.displayName=Filter Type
|
||||
FileTypeNode.createSheet.filterType.desc=no description
|
||||
|
171
Core/src/org/sleuthkit/autopsy/datamodel/CreditCards.java
Normal file
171
Core/src/org/sleuthkit/autopsy/datamodel/CreditCards.java
Normal file
@ -0,0 +1,171 @@
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
import com.google.common.collect.RangeMap;
|
||||
import com.google.common.collect.TreeRangeMap;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVParser;
|
||||
import org.apache.commons.csv.CSVRecord;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import org.sleuthkit.autopsy.datamodel._private.Accounts;
|
||||
|
||||
public class CreditCards {
|
||||
|
||||
//Interface for objects that provide details about one or more BINs.
|
||||
static public interface BankIdentificationNumber {
|
||||
|
||||
/**
|
||||
* Get the city of the issuer.
|
||||
*
|
||||
* @return the city of the issuer.
|
||||
*/
|
||||
Optional<String> getBankCity();
|
||||
|
||||
/**
|
||||
* Get the name of the issuer.
|
||||
*
|
||||
* @return the name of the issuer.
|
||||
*/
|
||||
Optional<String> getBankName();
|
||||
|
||||
/**
|
||||
* Get the phone number of the issuer.
|
||||
*
|
||||
* @return the phone number of the issuer.
|
||||
*/
|
||||
Optional<String> getBankPhoneNumber();
|
||||
|
||||
/**
|
||||
* Get the URL of the issuer.
|
||||
*
|
||||
* @return the URL of the issuer.
|
||||
*/
|
||||
Optional<String> getBankURL();
|
||||
|
||||
/**
|
||||
* Get the brand of this BIN range.
|
||||
*
|
||||
* @return the brand of this BIN range.
|
||||
*/
|
||||
Optional<String> getBrand();
|
||||
|
||||
/**
|
||||
* Get the type of card (credit vs debit) for this BIN range.
|
||||
*
|
||||
* @return the type of cards in this BIN range.
|
||||
*/
|
||||
Optional<String> getCardType();
|
||||
|
||||
/**
|
||||
* Get the country of the issuer.
|
||||
*
|
||||
* @return the country of the issuer.
|
||||
*/
|
||||
Optional<String> getCountry();
|
||||
|
||||
/**
|
||||
* Get the length of account numbers in this BIN range.
|
||||
*
|
||||
* NOTE: the length is currently unused, and not in the data file for
|
||||
* any ranges. It could be quite helpfull for validation...
|
||||
*
|
||||
* @return the length of account numbers in this BIN range. Or an empty
|
||||
* Optional if the length is unknown.
|
||||
*
|
||||
*/
|
||||
Optional<Integer> getNumberLength();
|
||||
|
||||
/**
|
||||
* Get the scheme this BIN range uses to amex,visa,mastercard, etc
|
||||
*
|
||||
* @return the scheme this BIN range uses.
|
||||
*/
|
||||
Optional<String> getScheme();
|
||||
}
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CreditCards.class.getName());
|
||||
/**
|
||||
* Range Map from a (ranges of) BINs to data model object with details of
|
||||
* the BIN, ie, bank name, phone, url, visa/amex/mastercard/...,
|
||||
*/
|
||||
@GuardedBy("CreditCards.class")
|
||||
private final static RangeMap<Integer, Accounts.BINRange> binRanges = TreeRangeMap.create();
|
||||
|
||||
/**
|
||||
* Flag for if we have loaded the BINs from the file already.
|
||||
*/
|
||||
@GuardedBy("CreditCards.class")
|
||||
private static boolean binsLoaded = false;
|
||||
|
||||
/**
|
||||
* Load the BIN range information from disk. If the map has already been
|
||||
* initialized, don't load again.
|
||||
*/
|
||||
synchronized private static void loadBINRanges() {
|
||||
if (binsLoaded == false) {
|
||||
try {
|
||||
InputStreamReader in = new InputStreamReader(CreditCards.class.getResourceAsStream("ranges.csv")); //NON-NLS
|
||||
CSVParser rangesParser = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(in);
|
||||
|
||||
//parse each row and add to range map
|
||||
for (CSVRecord record : rangesParser) {
|
||||
|
||||
/**
|
||||
* Because ranges.csv allows both 6 and (the newer) 8 digit
|
||||
* BINs, but we need a consistent length for the range map,
|
||||
* we pad all the numbers out to 8 digits
|
||||
*/
|
||||
String start = StringUtils.rightPad(record.get("iin_start"), 8, "0"); //pad start with 0's //NON-NLS
|
||||
|
||||
//if there is no end listed, use start, since ranges will be closed.
|
||||
String end = StringUtils.defaultIfBlank(record.get("iin_end"), start); //NON-NLS
|
||||
end = StringUtils.rightPad(end, 8, "99"); //pad end with 9's //NON-NLS
|
||||
|
||||
final String numberLength = record.get("number_length"); //NON-NLS
|
||||
|
||||
try {
|
||||
Accounts.BINRange binRange = new Accounts.BINRange(Integer.parseInt(start),
|
||||
Integer.parseInt(end),
|
||||
StringUtils.isBlank(numberLength) ? null : Integer.valueOf(numberLength),
|
||||
record.get("scheme"), //NON-NLS
|
||||
record.get("brand"), //NON-NLS
|
||||
record.get("type"), //NON-NLS
|
||||
record.get("country"), //NON-NLS
|
||||
record.get("bank_name"), //NON-NLS
|
||||
record.get("bank_url"), //NON-NLS
|
||||
record.get("bank_phone"), //NON-NLS
|
||||
record.get("bank_city")); //NON-NLS
|
||||
|
||||
binRanges.put(Range.closed(binRange.getBINstart(), binRange.getBINend()), binRange);
|
||||
|
||||
} catch (NumberFormatException numberFormatException) {
|
||||
LOGGER.log(Level.WARNING, "Failed to parse BIN range: " + record.toString(), numberFormatException); //NON-NLS
|
||||
}
|
||||
binsLoaded = true;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.WARNING, "Failed to load BIN ranges form ranges.csv", ex); //NON-NLS
|
||||
MessageNotifyUtil.Notify.warn("Credit Card Number Discovery", "There was an error loading Bank Identification Number information. Accounts will not have their BINs identified.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an BINInfo object with details about the given BIN
|
||||
*
|
||||
* @param bin the BIN to get details of.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
synchronized static public BankIdentificationNumber getBINInfo(int bin) {
|
||||
loadBINRanges();
|
||||
return binRanges.get(bin);
|
||||
}
|
||||
}
|
@ -18,6 +18,9 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem;
|
||||
|
||||
/**
|
||||
* Root node to store the data sources in a case
|
||||
*/
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
|
@ -22,6 +22,7 @@ import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsChildren.De
|
||||
import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsNode;
|
||||
import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootChildren.FileSizeNode;
|
||||
import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootNode;
|
||||
import org.sleuthkit.autopsy.datamodel._private.Accounts;
|
||||
|
||||
/**
|
||||
* Visitor pattern that goes over all nodes in the directory tree. This includes
|
||||
@ -137,6 +138,8 @@ public interface DisplayableItemNodeVisitor<T> {
|
||||
|
||||
T visit(Accounts.BINNode binNode);
|
||||
|
||||
T visit(Accounts.DefaultAccountTypeNode node);
|
||||
|
||||
/**
|
||||
* Visitor with an implementable default behavior for all types. Override
|
||||
* specific visit types to not use the default behavior.
|
||||
@ -378,5 +381,9 @@ public interface DisplayableItemNodeVisitor<T> {
|
||||
public T visit(Accounts.BINNode node) {
|
||||
return defaultVisit(node);
|
||||
}
|
||||
@Override
|
||||
public T visit(Accounts.DefaultAccountTypeNode node) {
|
||||
return defaultVisit(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.FileTypeExtensionFilters;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.FileTypeExtensionFilters;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Arrays;
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.RecentFiles;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
|
@ -28,7 +28,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
import org.openide.nodes.Node;
|
||||
import org.sleuthkit.autopsy.datamodel.RecentFiles.RecentFilesFilter;
|
||||
import org.sleuthkit.autopsy.datamodel._private.RecentFiles.RecentFilesFilter;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.ContentVisitor;
|
||||
|
@ -25,7 +25,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.datamodel.RecentFiles.RecentFilesFilter;
|
||||
import org.sleuthkit.autopsy.datamodel._private.RecentFiles.RecentFilesFilter;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.Accounts;
|
||||
import java.util.Arrays;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle;
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Collections;
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel._private.FileTypeExtensionFilters;
|
||||
import java.util.Arrays;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle;
|
||||
|
@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
package org.sleuthkit.autopsy.datamodel._private;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
import com.google.common.collect.RangeMap;
|
||||
@ -46,7 +46,6 @@ import javax.annotation.concurrent.Immutable;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
@ -55,11 +54,18 @@ import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
|
||||
import org.sleuthkit.autopsy.datamodel.CreditCards;
|
||||
import org.sleuthkit.autopsy.datamodel.DataModelActionsFactory;
|
||||
import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
|
||||
import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
@ -69,10 +75,9 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
* AutopsyVisitableItem for the Accounts section of the tree. All nodes,
|
||||
* factories, and data objects related to accounts are inner classes.
|
||||
*/
|
||||
public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
final public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(Accounts.class.getName());
|
||||
private static final BlackboardArtifact.Type ACCOUNT_TYPE = new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT);
|
||||
@NbBundle.Messages("AccountsRootNode.name=Accounts")
|
||||
final public static String NAME = Bundle.AccountsRootNode_name();
|
||||
|
||||
@ -88,7 +93,7 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
*
|
||||
* @param skCase The SleuthkitCase object to use for db queries.
|
||||
*/
|
||||
Accounts(SleuthkitCase skCase) {
|
||||
public Accounts(SleuthkitCase skCase) {
|
||||
this.skCase = skCase;
|
||||
}
|
||||
|
||||
@ -128,89 +133,17 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
return new ToggleShowRejected();
|
||||
}
|
||||
|
||||
//Interface for objects that provide details about one or more IINs.
|
||||
static public interface IINInfo {
|
||||
|
||||
/**
|
||||
* Get the city of the issuer.
|
||||
*
|
||||
* @return the city of the issuer.
|
||||
*/
|
||||
Optional<String> getBankCity();
|
||||
|
||||
/**
|
||||
* Get the name of the issuer.
|
||||
*
|
||||
* @return the name of the issuer.
|
||||
*/
|
||||
Optional<String> getBankName();
|
||||
|
||||
/**
|
||||
* Get the phone number of the issuer.
|
||||
*
|
||||
* @return the phone number of the issuer.
|
||||
*/
|
||||
Optional<String> getBankPhoneNumber();
|
||||
|
||||
/**
|
||||
* Get the URL of the issuer.
|
||||
*
|
||||
* @return the URL of the issuer.
|
||||
*/
|
||||
Optional<String> getBankURL();
|
||||
|
||||
/**
|
||||
* Get the brand of this IIN range.
|
||||
*
|
||||
* @return the brand of this IIN range.
|
||||
*/
|
||||
Optional<String> getBrand();
|
||||
|
||||
/**
|
||||
* Get the type of card (credit vs debit) for this IIN range.
|
||||
*
|
||||
* @return the type of cards in this IIN range.
|
||||
*/
|
||||
Optional<String> getCardType();
|
||||
|
||||
/**
|
||||
* Get the country of the issuer.
|
||||
*
|
||||
* @return the country of the issuer.
|
||||
*/
|
||||
Optional<String> getCountry();
|
||||
|
||||
/**
|
||||
* Get the length of account numbers in this IIN range.
|
||||
*
|
||||
* NOTE: the length is currently unused, and not in the data file for
|
||||
* any ranges. It could be quite helpfull for validation...
|
||||
*
|
||||
* @return the length of account numbers in this IIN range. Or an empty
|
||||
* Optional if the length is unknown.
|
||||
*
|
||||
*/
|
||||
Optional<Integer> getNumberLength();
|
||||
|
||||
/**
|
||||
* Get the scheme this IIN range uses to, eg amex,visa,mastercard, etc
|
||||
*
|
||||
* @return the scheme this IIN range uses.
|
||||
*/
|
||||
Optional<String> getScheme();
|
||||
}
|
||||
|
||||
/**
|
||||
* Details of a range of Issuer/Bank Identifiaction Number(s) (IIN/BIN) used
|
||||
* by a bank.
|
||||
* Details of a range of Bank Identification Number(s) (BIN) used * by a
|
||||
* bank.
|
||||
*/
|
||||
@Immutable
|
||||
static class IINRange implements IINInfo {
|
||||
public static class BINRange implements CreditCards.BankIdentificationNumber {
|
||||
|
||||
private final int IINStart; //start of IIN range, 8 digits
|
||||
private final int IINEnd; // end (incluse ) of IIN rnage, 8 digits
|
||||
private final int BINStart; //start of BIN range, 8 digits
|
||||
private final int BINEnd; // end (incluse ) of BIN rnage, 8 digits
|
||||
|
||||
private final Integer numberLength; // the length of accounts numbers with this IIN, currently unused
|
||||
private final Integer numberLength; // the length of accounts numbers with this BIN, currently unused
|
||||
|
||||
/**
|
||||
* AMEX, VISA, MASTERCARD, DINERS, DISCOVER, UNIONPAY
|
||||
@ -231,12 +164,12 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param IIN_start the first IIN in the range, must be 8 digits
|
||||
* @param IIN_end the last(inclusive) IIN in the range, must be 8
|
||||
* @param BIN_start the first BIN in the range, must be 8 digits
|
||||
* @param BIN_end the last(inclusive) BIN in the range, must be 8
|
||||
* digits
|
||||
* @param number_length the length of account numbers in this IIN range
|
||||
* @param number_length the length of account numbers in this BIN range
|
||||
* @param scheme amex/visa/mastercard/etc
|
||||
* @param brand the brand of this IIN range
|
||||
* @param brand the brand of this BIN range
|
||||
* @param type credit vs debit
|
||||
* @param country the country of the issuer
|
||||
* @param bank_name the name of the issuer
|
||||
@ -244,9 +177,9 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
* @param bank_phone the phone number of the issuer
|
||||
* @param bank_city the city of the issuer
|
||||
*/
|
||||
IINRange(int IIN_start, int IIN_end, Integer number_length, String scheme, String brand, String type, String country, String bank_name, String bank_url, String bank_phone, String bank_city) {
|
||||
this.IINStart = IIN_start;
|
||||
this.IINEnd = IIN_end;
|
||||
public BINRange(int BIN_start, int BIN_end, Integer number_length, String scheme, String brand, String type, String country, String bank_name, String bank_url, String bank_phone, String bank_city) {
|
||||
this.BINStart = BIN_start;
|
||||
this.BINEnd = BIN_end;
|
||||
|
||||
this.numberLength = number_length;
|
||||
this.scheme = StringUtils.defaultIfBlank(scheme, null);
|
||||
@ -260,21 +193,21 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first IIN in this range
|
||||
* Get the first BIN in this range
|
||||
*
|
||||
* @return the first IIN in this range.
|
||||
* @return the first BIN in this range.
|
||||
*/
|
||||
int getIINstart() {
|
||||
return IINStart;
|
||||
public int getBINstart() {
|
||||
return BINStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last (inclusive) IIN in this range.
|
||||
* Get the last (inclusive) BIN in this range.
|
||||
*
|
||||
* @return the last (inclusive) IIN in this range.
|
||||
* @return the last (inclusive) BIN in this range.
|
||||
*/
|
||||
int getIINend() {
|
||||
return IINEnd;
|
||||
public int getBINend() {
|
||||
return BINEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -354,7 +287,7 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
@NbBundle.Messages({"Accounts.RootNode.displayName=Accounts"})
|
||||
public class AccountsRootNode extends DisplayableItemNode {
|
||||
|
||||
AccountsRootNode() {
|
||||
public AccountsRootNode() {
|
||||
super(Children.create(new AccountTypeFactory(), true), Lookups.singleton(Accounts.this));
|
||||
super.setName(Accounts.NAME);
|
||||
super.setDisplayName(Bundle.Accounts_RootNode_displayName());
|
||||
@ -403,7 +336,8 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
* for the event to have a null oldValue.
|
||||
*/
|
||||
ModuleDataEvent eventData = (ModuleDataEvent) evt.getOldValue();
|
||||
if (null != eventData && ACCOUNT_TYPE.equals(eventData.getBlackboardArtifactType())) {
|
||||
if (null != eventData
|
||||
&& eventData.getBlackboardArtifactType().getTypeID() == ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()) {
|
||||
Accounts.this.update();
|
||||
}
|
||||
} catch (IllegalStateException notUsed) {
|
||||
@ -443,7 +377,8 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
+ " WHERE blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID());
|
||||
ResultSet resultSet = executeQuery.getResultSet()) {
|
||||
while (resultSet.next()) {
|
||||
list.add(resultSet.getString("account_type"));
|
||||
String accountType = resultSet.getString("account_type");
|
||||
list.add(accountType);
|
||||
}
|
||||
} catch (TskCoreException | SQLException ex) {
|
||||
Exceptions.printStackTrace(ex);
|
||||
@ -454,15 +389,18 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
|
||||
@Override
|
||||
protected Node createNodeForKey(String key) {
|
||||
if (key.equals( /**
|
||||
* This is a secret handshake with
|
||||
* org.sleuthkit.autopsy.keywordsearch.TermComponentQuery
|
||||
*/
|
||||
Account.Type.CREDIT_CARD.name())) {
|
||||
return new CreditCardNumberAccountTypeNode(key);
|
||||
} else {
|
||||
try {
|
||||
Account.Type accountType = Account.Type.valueOf(key);
|
||||
switch (accountType) {
|
||||
case CREDIT_CARD:
|
||||
return new CreditCardNumberAccountTypeNode();
|
||||
default:
|
||||
return new DefaultAccountTypeNode(key);
|
||||
}
|
||||
} catch (IllegalArgumentException ex) {
|
||||
LOGGER.log(Level.WARNING, "Unknown account type: " + key);
|
||||
//Flesh out what happens with other account types here.
|
||||
return new AbstractNode(Children.LEAF);
|
||||
return new DefaultAccountTypeNode(key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -484,6 +422,67 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
}
|
||||
}
|
||||
|
||||
private class DefaultAccountFactory extends ChildFactory.Detachable<Long> {
|
||||
|
||||
private final String accountTypeName;
|
||||
|
||||
public DefaultAccountFactory(String accountTypeName) {
|
||||
this.accountTypeName = accountTypeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean createKeys(List<Long> list) {
|
||||
|
||||
String query
|
||||
= "SELECT blackboard_artifacts.artifact_id " //NON-NLS
|
||||
+ " FROM blackboard_artifacts " //NON-NLS
|
||||
+ " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id " //NON-NLS
|
||||
+ " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS
|
||||
+ " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID() //NON-NLS
|
||||
+ " AND blackboard_attributes.value_text = '" + accountTypeName + "'" //NON-NLS
|
||||
+ getRejectedArtifactFilterClause(); //NON-NLS
|
||||
try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
|
||||
ResultSet rs = results.getResultSet();) {
|
||||
while (rs.next()) {
|
||||
list.add(rs.getLong("artifact_id")); //NON-NLS
|
||||
}
|
||||
} catch (TskCoreException | SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error querying for account artifacts.", ex); //NON-NLS
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Node createNodeForKey(Long t) {
|
||||
try {
|
||||
return new BlackboardArtifactNode(skCase.getBlackboardArtifact(t));
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error get black board artifact with id " + t, ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DefaultAccountTypeNode extends DisplayableItemNode {
|
||||
|
||||
private DefaultAccountTypeNode(String accountTypeName) {
|
||||
super(Children.create(new DefaultAccountFactory(accountTypeName), true));
|
||||
super.setName(accountTypeName);
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/credit-cards.png"); //NON-NLS
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeafTypeNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T accept(DisplayableItemNodeVisitor<T> v) {
|
||||
return v.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Node for an account type.
|
||||
*
|
||||
@ -491,9 +490,9 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
*/
|
||||
public class CreditCardNumberAccountTypeNode extends DisplayableItemNode {
|
||||
|
||||
private CreditCardNumberAccountTypeNode(String accountTypeName) {
|
||||
private CreditCardNumberAccountTypeNode() {
|
||||
super(Children.create(new ViewModeFactory(), true));
|
||||
super.setName(accountTypeName);
|
||||
super.setName(Account.Type.CREDIT_CARD.getDisplayName());
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/credit-cards.png"); //NON-NLS
|
||||
}
|
||||
|
||||
@ -874,10 +873,10 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
}
|
||||
|
||||
private String getBinRangeString() {
|
||||
if (bin.getIINStart() == bin.getIINEnd()) {
|
||||
return Integer.toString(bin.getIINStart());
|
||||
if (bin.getBINStart() == bin.getBINEnd()) {
|
||||
return Integer.toString(bin.getBINStart());
|
||||
} else {
|
||||
return bin.getIINStart() + "-" + StringUtils.difference(bin.getIINStart() + "", bin.getIINEnd() + "");
|
||||
return bin.getBINStart() + "-" + StringUtils.difference(bin.getBINStart() + "", bin.getBINEnd() + "");
|
||||
}
|
||||
}
|
||||
|
||||
@ -981,16 +980,16 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
final Integer bin = Integer.valueOf(resultSet.getString("BIN"));
|
||||
long count = resultSet.getLong("count");
|
||||
|
||||
IINRange iinRange = (IINRange) BINMap.getIINInfo(bin);
|
||||
BINRange binRange = (BINRange) CreditCards.getBINInfo(bin);
|
||||
BinResult previousResult = ranges.get(bin);
|
||||
|
||||
if (previousResult != null) {
|
||||
ranges.remove(Range.closed(previousResult.getIINStart(), previousResult.getIINEnd()));
|
||||
ranges.remove(Range.closed(previousResult.getBINStart(), previousResult.getBINEnd()));
|
||||
count += previousResult.getCount();
|
||||
}
|
||||
|
||||
if (iinRange != null) {
|
||||
ranges.put(Range.closed(iinRange.getIINstart(), iinRange.getIINend()), new BinResult(count, iinRange));
|
||||
if (binRange != null) {
|
||||
ranges.put(Range.closed(binRange.getBINstart(), binRange.getBINend()), new BinResult(count, binRange));
|
||||
} else {
|
||||
ranges.put(Range.closed(bin, bin), new BinResult(count, bin, bin));
|
||||
}
|
||||
@ -1014,37 +1013,37 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
* accounts found with the BIN.
|
||||
*/
|
||||
@Immutable
|
||||
static private class BinResult implements IINInfo {
|
||||
static private class BinResult implements CreditCards.BankIdentificationNumber {
|
||||
|
||||
/**
|
||||
* The number of accounts with this BIN
|
||||
*/
|
||||
private final long count;
|
||||
|
||||
private final IINRange iinRange;
|
||||
private final int iinEnd;
|
||||
private final int iinStart;
|
||||
private final BINRange binRange;
|
||||
private final int binEnd;
|
||||
private final int binStart;
|
||||
|
||||
private BinResult(long count, @Nonnull IINRange iinRange) {
|
||||
private BinResult(long count, @Nonnull BINRange binRange) {
|
||||
this.count = count;
|
||||
this.iinRange = iinRange;
|
||||
iinStart = iinRange.getIINstart();
|
||||
iinEnd = iinRange.getIINend();
|
||||
this.binRange = binRange;
|
||||
binStart = binRange.getBINstart();
|
||||
binEnd = binRange.getBINend();
|
||||
}
|
||||
|
||||
private BinResult(long count, int start, int end) {
|
||||
this.count = count;
|
||||
this.iinRange = null;
|
||||
iinStart = start;
|
||||
iinEnd = end;
|
||||
this.binRange = null;
|
||||
binStart = start;
|
||||
binEnd = end;
|
||||
}
|
||||
|
||||
int getIINStart() {
|
||||
return iinStart;
|
||||
int getBINStart() {
|
||||
return binStart;
|
||||
}
|
||||
|
||||
int getIINEnd() {
|
||||
return iinEnd;
|
||||
int getBINEnd() {
|
||||
return binEnd;
|
||||
}
|
||||
|
||||
public long getCount() {
|
||||
@ -1052,52 +1051,52 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
}
|
||||
|
||||
boolean hasDetails() {
|
||||
return iinRange != null;
|
||||
return binRange != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> getNumberLength() {
|
||||
return iinRange.getNumberLength();
|
||||
return binRange.getNumberLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getBankCity() {
|
||||
return iinRange.getBankCity();
|
||||
return binRange.getBankCity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getBankName() {
|
||||
return iinRange.getBankName();
|
||||
return binRange.getBankName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getBankPhoneNumber() {
|
||||
return iinRange.getBankPhoneNumber();
|
||||
return binRange.getBankPhoneNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getBankURL() {
|
||||
return iinRange.getBankURL();
|
||||
return binRange.getBankURL();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getBrand() {
|
||||
return iinRange.getBrand();
|
||||
return binRange.getBrand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getCardType() {
|
||||
return iinRange.getCardType();
|
||||
return binRange.getCardType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getCountry() {
|
||||
return iinRange.getCountry();
|
||||
return binRange.getCountry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getScheme() {
|
||||
return iinRange.getScheme();
|
||||
return binRange.getScheme();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1121,7 +1120,7 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
+ " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id " //NON-NLS
|
||||
+ " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS
|
||||
+ " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CREDIT_CARD_NUMBER.getTypeID() //NON-NLS
|
||||
+ " AND blackboard_attributes.value_text >= \"" + bin.getIINStart() + "\" AND blackboard_attributes.value_text < \"" + (bin.getIINEnd() + 1) + "\"" //NON-NLS
|
||||
+ " AND blackboard_attributes.value_text >= \"" + bin.getBINStart() + "\" AND blackboard_attributes.value_text < \"" + (bin.getBINEnd() + 1) + "\"" //NON-NLS
|
||||
+ getRejectedArtifactFilterClause()
|
||||
+ " ORDER BY blackboard_attributes.value_text"; //NON-NLS
|
||||
try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
|
||||
@ -1187,7 +1186,7 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
}
|
||||
}
|
||||
|
||||
final class ToggleShowRejected extends AbstractAction {
|
||||
private final class ToggleShowRejected extends AbstractAction {
|
||||
|
||||
@NbBundle.Messages("ToggleShowRejected.name=Show Rejcted Results")
|
||||
ToggleShowRejected() {
|
@ -16,14 +16,27 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
package org.sleuthkit.autopsy.datamodel._private;
|
||||
|
||||
import org.sleuthkit.autopsy.datamodel.DataSources;
|
||||
import org.sleuthkit.autopsy.datamodel.DeletedContent;
|
||||
import org.sleuthkit.autopsy.datamodel.EmailExtracted;
|
||||
import org.sleuthkit.autopsy.datamodel.ExtractedContent;
|
||||
import org.sleuthkit.autopsy.datamodel.FileSize;
|
||||
import org.sleuthkit.autopsy.datamodel.HashsetHits;
|
||||
import org.sleuthkit.autopsy.datamodel.InterestingHits;
|
||||
import org.sleuthkit.autopsy.datamodel.KeywordHits;
|
||||
import org.sleuthkit.autopsy.datamodel.Reports;
|
||||
import org.sleuthkit.autopsy.datamodel.Results;
|
||||
import org.sleuthkit.autopsy.datamodel.Tags;
|
||||
import org.sleuthkit.autopsy.datamodel.Views;
|
||||
|
||||
/**
|
||||
* This visitor goes over the AutopsyVisitableItems, which are currently the
|
||||
* nodes in the tree that are structural and not nodes that are from
|
||||
* Sleuthkit-based data model objects.
|
||||
*/
|
||||
interface AutopsyItemVisitor<T> {
|
||||
public interface AutopsyItemVisitor<T> {
|
||||
|
||||
T visit(DataSources i);
|
||||
|
@ -16,13 +16,14 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
package org.sleuthkit.autopsy.datamodel._private;
|
||||
;
|
||||
|
||||
/**
|
||||
* AutopsyVisitableItems are the nodes in the directory tree that are for
|
||||
* structure only. They are not associated with content objects.
|
||||
*/
|
||||
interface AutopsyVisitableItem {
|
||||
public interface AutopsyVisitableItem {
|
||||
|
||||
/**
|
||||
* visitor pattern support
|
@ -0,0 +1,12 @@
|
||||
FileTypeExtensionFilters.tskImgFilter.text=Images
|
||||
FileTypeExtensionFilters.tskVideoFilter.text=Videos
|
||||
FileTypeExtensionFilters.tskAudioFilter.text=Audio
|
||||
FileTypeExtensionFilters.tskArchiveFilter.text=Archives
|
||||
FileTypeExtensionFilters.tskDocumentFilter.text=Documents
|
||||
FileTypeExtensionFilters.tskExecFilter.text=Executable
|
||||
FileTypeExtensionFilters.autDocHtmlFilter.text=HTML
|
||||
FileTypeExtensionFilters.autDocOfficeFilter.text=Office
|
||||
FileTypeExtensionFilters.autoDocPdfFilter.text=PDF
|
||||
FileTypeExtensionFilters.autDocTxtFilter.text=Plain Text
|
||||
FileTypeExtensionFilters.autDocRtfFilter.text=Rich Text
|
||||
|
@ -16,20 +16,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
package org.sleuthkit.autopsy.datamodel._private;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.datamodel.FileTypeExtensions;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
|
||||
/**
|
||||
* Filters database results by file extension.
|
||||
*/
|
||||
class FileTypeExtensionFilters implements AutopsyVisitableItem {
|
||||
public class FileTypeExtensionFilters implements AutopsyVisitableItem {
|
||||
|
||||
private SleuthkitCase skCase;
|
||||
private final SleuthkitCase skCase;
|
||||
|
||||
// root node filters
|
||||
public enum RootFilter implements AutopsyVisitableItem, SearchFilterInterface {
|
||||
@ -53,10 +53,10 @@ class FileTypeExtensionFilters implements AutopsyVisitableItem {
|
||||
NbBundle.getMessage(FileTypeExtensionFilters.class, "FileTypeExtensionFilters.tskExecFilter.text"),
|
||||
Arrays.asList(".exe", ".dll", ".bat", ".cmd", ".com")); //NON-NLS
|
||||
|
||||
private int id;
|
||||
private String name;
|
||||
private String displayName;
|
||||
private List<String> filter;
|
||||
private final int id;
|
||||
private final String name;
|
||||
private final String displayName;
|
||||
private final List<String> filter;
|
||||
|
||||
private RootFilter(int id, String name, String displayName, List<String> filter) {
|
||||
this.id = id;
|
||||
@ -110,10 +110,10 @@ class FileTypeExtensionFilters implements AutopsyVisitableItem {
|
||||
NbBundle.getMessage(FileTypeExtensionFilters.class, "FileTypeExtensionFilters.autDocRtfFilter.text"),
|
||||
Arrays.asList(".rtf")); //NON-NLS
|
||||
|
||||
private int id;
|
||||
private String name;
|
||||
private String displayName;
|
||||
private List<String> filter;
|
||||
private final int id;
|
||||
private final String name;
|
||||
private final String displayName;
|
||||
private final List<String> filter;
|
||||
|
||||
private DocumentFilter(int id, String name, String displayName, List<String> filter) {
|
||||
this.id = id;
|
||||
@ -157,10 +157,10 @@ class FileTypeExtensionFilters implements AutopsyVisitableItem {
|
||||
ExecutableFilter_CMD(3, "ExecutableFilter_CMD", ".cmd", Arrays.asList(".cmd")), //NON-NLS
|
||||
ExecutableFilter_COM(4, "ExecutableFilter_COM", ".com", Arrays.asList(".com")); //NON-NLS
|
||||
|
||||
private int id;
|
||||
private String name;
|
||||
private String displayName;
|
||||
private List<String> filter;
|
||||
private final int id;
|
||||
private final String name;
|
||||
private final String displayName;
|
||||
private final List<String> filter;
|
||||
|
||||
private ExecutableFilter(int id, String name, String displayName, List<String> filter) {
|
||||
this.id = id;
|
||||
@ -208,7 +208,7 @@ class FileTypeExtensionFilters implements AutopsyVisitableItem {
|
||||
return this.skCase;
|
||||
}
|
||||
|
||||
interface SearchFilterInterface {
|
||||
public interface SearchFilterInterface {
|
||||
|
||||
public String getName();
|
||||
|
@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
package org.sleuthkit.autopsy.datamodel._private;
|
||||
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
@ -25,7 +25,7 @@ import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
* Recent files node support NOTE: As of june '15 we do not display this in the
|
||||
* tree. It can be added back when we have filtering in the results area.
|
||||
*/
|
||||
class RecentFiles implements AutopsyVisitableItem {
|
||||
public class RecentFiles implements AutopsyVisitableItem {
|
||||
|
||||
SleuthkitCase skCase;
|
||||
|
@ -37,7 +37,7 @@ import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datamodel.AbstractAbstractFileNode.AbstractFilePropertyType;
|
||||
import org.sleuthkit.autopsy.datamodel.AbstractFsContentNode;
|
||||
import org.sleuthkit.autopsy.datamodel.Accounts;
|
||||
import org.sleuthkit.autopsy.datamodel._private.Accounts;
|
||||
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
|
||||
import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsChildren.DeletedContentNode;
|
||||
import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsNode;
|
||||
|
@ -57,7 +57,7 @@ import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
|
||||
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import org.sleuthkit.autopsy.datamodel.Accounts;
|
||||
import org.sleuthkit.autopsy.datamodel._private.Accounts;
|
||||
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
|
||||
import org.sleuthkit.autopsy.datamodel.DataSources;
|
||||
import org.sleuthkit.autopsy.datamodel.DataSourcesNode;
|
||||
|
@ -140,7 +140,7 @@ public class ExtractedContentViewer implements DataContentViewer {
|
||||
*/
|
||||
for (BlackboardArtifact artifact : artifacts) {
|
||||
try {
|
||||
BlackboardAttribute solrIDAttr = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SOLR_DOCUMENT_ID));
|
||||
BlackboardAttribute solrIDAttr = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID));
|
||||
if (solrIDAttr != null) {
|
||||
String valueString = solrIDAttr.getValueString();
|
||||
if (StringUtils.isNotBlank(valueString)) {
|
||||
|
@ -34,8 +34,7 @@ import org.apache.solr.client.solrj.SolrQuery;
|
||||
import org.apache.solr.client.solrj.response.TermsResponse.Term;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.Version;
|
||||
import org.sleuthkit.autopsy.datamodel.Accounts;
|
||||
import org.sleuthkit.autopsy.datamodel.BINMap;
|
||||
import org.sleuthkit.autopsy.datamodel.CreditCards;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
@ -214,26 +213,26 @@ final class TermComponentQuery implements KeywordSearchQuery {
|
||||
}
|
||||
|
||||
String ccn = newArtifact.getAttribute(CREDIT_CARD_NUMBER).getValueString();
|
||||
final int iin = Integer.parseInt(ccn.substring(0, 8));
|
||||
final int bin = Integer.parseInt(ccn.substring(0, 8));
|
||||
|
||||
Accounts.IINInfo iinInfo = BINMap.getIINInfo(iin);
|
||||
CreditCards.BankIdentificationNumber binInfo = CreditCards.getBINInfo(bin);
|
||||
|
||||
if (iinInfo != null) {
|
||||
iinInfo.getScheme().ifPresent(scheme
|
||||
if (binInfo != null) {
|
||||
binInfo.getScheme().ifPresent(scheme
|
||||
-> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_CREDIT_CARD_SCHEME, scheme));
|
||||
iinInfo.getCardType().ifPresent(cardType
|
||||
binInfo.getCardType().ifPresent(cardType
|
||||
-> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_PAYMENT_CARD_TYPE, cardType));
|
||||
iinInfo.getBrand().ifPresent(brand
|
||||
binInfo.getBrand().ifPresent(brand
|
||||
-> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_BRAND, brand));
|
||||
iinInfo.getBankName().ifPresent(bankName
|
||||
binInfo.getBankName().ifPresent(bankName
|
||||
-> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_BANK_NAME, bankName));
|
||||
iinInfo.getBankPhoneNumber().ifPresent(phoneNumber
|
||||
binInfo.getBankPhoneNumber().ifPresent(phoneNumber
|
||||
-> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, phoneNumber));
|
||||
iinInfo.getBankURL().ifPresent(url
|
||||
binInfo.getBankURL().ifPresent(url
|
||||
-> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_URL, url));
|
||||
iinInfo.getCountry().ifPresent(country
|
||||
binInfo.getCountry().ifPresent(country
|
||||
-> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_COUNTRY, country));
|
||||
iinInfo.getBankCity().ifPresent(city
|
||||
binInfo.getBankCity().ifPresent(city
|
||||
-> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_CITY, city));
|
||||
}
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user