19 package org.sleuthkit.autopsy.modules.hashdatabase;
 
   21 import java.beans.PropertyChangeEvent;
 
   22 import java.beans.PropertyChangeListener;
 
   23 import java.beans.PropertyChangeSupport;
 
   25 import java.io.IOException;
 
   26 import java.util.ArrayList;
 
   27 import java.util.HashSet;
 
   28 import java.util.List;
 
   29 import java.util.Objects;
 
   31 import java.util.concurrent.ExecutionException;
 
   32 import java.util.logging.Level;
 
   33 import javax.swing.JFileChooser;
 
   34 import javax.swing.JOptionPane;
 
   35 import javax.swing.SwingWorker;
 
   36 import javax.swing.filechooser.FileNameExtensionFilter;
 
   37 import org.apache.commons.io.FilenameUtils;
 
   38 import org.netbeans.api.progress.ProgressHandle;
 
   39 import org.openide.util.NbBundle;
 
   40 import org.openide.util.NbBundle.Messages;
 
   41 import org.openide.windows.WindowManager;
 
   68     private List<HashDb> 
hashSets = 
new ArrayList<>();
 
   71     PropertyChangeSupport changeSupport = 
new PropertyChangeSupport(
HashDbManager.class);
 
   82         DB_ADDED, DB_DELETED, DB_INDEXED
 
   91         if (instance == null) {
 
   98         changeSupport.addPropertyChangeListener(listener);
 
  102         changeSupport.removePropertyChangeListener(listener);
 
  105     synchronized boolean verifyAllDatabasesLoadedCorrectly(){
 
  118     static String getHashDatabaseFileExtension() {
 
  131             super(message, exception);
 
  156         hashDb = this.addExistingHashDatabaseNoSave(hashSetName, path, searchDuringIngest, sendIngestMessages, knownFilesType);
 
  164             if (!
new File(path).exists()) {
 
  165                 throw new HashDbManagerException(NbBundle.getMessage(
HashDbManager.class, 
"HashDbManager.hashDbDoesNotExistExceptionMsg", path));
 
  168             if (hashSetPaths.contains(path)) {
 
  169                 throw new HashDbManagerException(NbBundle.getMessage(
HashDbManager.class, 
"HashDbManager.hashDbAlreadyAddedExceptionMsg", path));
 
  172             if (hashSetNames.contains(hashSetName)) {
 
  173                 throw new HashDbManagerException(NbBundle.getMessage(
HashDbManager.class, 
"HashDbManager.duplicateHashSetNameExceptionMsg", hashSetName));
 
  176             hashDb = 
addHashDatabase(SleuthkitJNI.openHashDatabase(path), hashSetName, searchDuringIngest, sendIngestMessages, knownFilesType);
 
  177         } 
catch (TskCoreException ex) {
 
  178             throw new HashDbManagerException(ex.getMessage());
 
  201     public synchronized HashDb addNewHashDatabase(String hashSetName, String path, 
boolean searchDuringIngest, 
boolean sendIngestMessages,
 
  216             File file = 
new File(path);
 
  218                 throw new HashDbManagerException(NbBundle.getMessage(
HashDbManager.class, 
"HashDbManager.hashDbFileExistsExceptionMsg", path));
 
  220             if (!FilenameUtils.getExtension(file.getName()).equalsIgnoreCase(HASH_DATABASE_FILE_EXTENSON)) {
 
  221                 throw new HashDbManagerException(NbBundle.getMessage(
HashDbManager.class, 
"HashDbManager.illegalHashDbFileNameExtensionMsg",
 
  222                         getHashDatabaseFileExtension()));
 
  225             if (hashSetPaths.contains(path)) {
 
  226                 throw new HashDbManagerException(NbBundle.getMessage(
HashDbManager.class, 
"HashDbManager.hashDbAlreadyAddedExceptionMsg", path));
 
  229             if (hashSetNames.contains(hashSetName)) {
 
  230                 throw new HashDbManagerException(NbBundle.getMessage(
HashDbManager.class, 
"HashDbManager.duplicateHashSetNameExceptionMsg", hashSetName));
 
  233             hashDb = 
addHashDatabase(SleuthkitJNI.createHashDatabase(path), hashSetName, searchDuringIngest, sendIngestMessages, knownFilesType);
 
  234         } 
catch (TskCoreException ex) {
 
  235             throw new HashDbManagerException(ex.getMessage());
 
  240     private SleuthkitHashSet 
addHashDatabase(
int handle, String hashSetName, 
boolean searchDuringIngest, 
boolean sendIngestMessages, 
HashDb.
KnownFilesType knownFilesType) throws TskCoreException {
 
  242         SleuthkitHashSet hashDb = 
new SleuthkitHashSet(handle, hashSetName, searchDuringIngest, sendIngestMessages, knownFilesType);
 
  246         String databasePath = hashDb.getDatabasePath();
 
  247         String indexPath = hashDb.getIndexPath();
 
  251         hashSetNames.add(hashDb.getHashSetName());
 
  252         if (!databasePath.equals(
"None")) { 
 
  253             hashSetPaths.add(databasePath);
 
  255         if (!indexPath.equals(
"None")) { 
 
  256             hashSetPaths.add(indexPath);
 
  260         hashSets.add(hashDb);
 
  264             changeSupport.firePropertyChange(
SetEvt.
DB_ADDED.toString(), null, hashSetName);
 
  265         } 
catch (Exception e) {
 
  266             logger.log(Level.SEVERE, 
"HashDbManager listener threw exception", e); 
 
  268                     NbBundle.getMessage(
this.getClass(), 
"HashDbManager.moduleErr"),
 
  269                     NbBundle.getMessage(
this.getClass(), 
"HashDbManager.moduleErrorListeningToUpdatesMsg"),
 
  275     CentralRepoHashSet addExistingCentralRepoHashSet(String hashSetName, String version, 
int referenceSetID, 
 
  277             boolean readOnly) 
throws TskCoreException{
 
  280             throw new TskCoreException(
"Could not load central repository hash set " + hashSetName + 
" - central repository is not enabled");
 
  283         CentralRepoHashSet db = 
new CentralRepoHashSet(hashSetName, version, referenceSetID, searchDuringIngest,
 
  284             sendIngestMessages, knownFilesType, readOnly);
 
  287             throw new TskCoreException(
"Error finding hash set " + hashSetName + 
" in central repository");
 
  295             changeSupport.firePropertyChange(SetEvt.DB_ADDED.toString(), null, hashSetName);
 
  296         } 
catch (Exception e) {
 
  297             logger.log(Level.SEVERE, 
"HashDbManager listener threw exception", e); 
 
  298             MessageNotifyUtil.Notify.show(
 
  299                     NbBundle.getMessage(
this.getClass(), 
"HashDbManager.moduleErr"),
 
  300                     NbBundle.getMessage(
this.getClass(), 
"HashDbManager.moduleErrorListeningToUpdatesMsg"),
 
  301                     MessageNotifyUtil.MessageType.ERROR);
 
  307     synchronized void indexHashDatabase(SleuthkitHashSet hashDb) {
 
  308         hashDb.addPropertyChangeListener(
this);
 
  309         HashDbIndexer creator = 
new HashDbIndexer(hashDb);
 
  315         if (event.getPropertyName().equals(SleuthkitHashSet.Event.INDEXING_DONE.name())) {
 
  316             SleuthkitHashSet hashDb = (SleuthkitHashSet) event.getNewValue();
 
  317             if (null != hashDb) {
 
  319                     String indexPath = hashDb.getIndexPath();
 
  320                     if (!indexPath.equals(
"None")) { 
 
  321                         hashSetPaths.add(indexPath);
 
  323                 } 
catch (TskCoreException ex) {
 
  324                     Logger.
getLogger(
HashDbManager.class.getName()).log(Level.SEVERE, 
"Error getting index path of " + hashDb.getHashSetName() + 
" hash set after indexing", ex); 
 
  346         if (ingestIsRunning) {
 
  347             throw new HashDbManagerException(NbBundle.getMessage(
this.getClass(), 
"HashDbManager.ingestRunningExceptionMsg"));
 
  353         String hashSetName = hashDb.getHashSetName();
 
  354         hashSetNames.remove(hashSetName);
 
  355         hashSets.remove(hashDb);
 
  360         if(hashDb instanceof SleuthkitHashSet){
 
  361             SleuthkitHashSet hashDatabase = (SleuthkitHashSet)hashDb;
 
  363                 if(hashDatabase.hasIndex()){
 
  364                     hashSetPaths.remove(hashDatabase.getIndexPath());
 
  366             } 
catch (TskCoreException ex) {
 
  367                 Logger.
getLogger(
HashDbManager.class.getName()).log(Level.SEVERE, 
"Error getting index path of " + hashDatabase.getHashSetName() + 
" hash set when removing the hash set", ex); 
 
  371                 if (!hashDatabase.hasIndexOnly()) {
 
  372                     hashSetPaths.remove(hashDatabase.getDatabasePath());
 
  374             } 
catch (TskCoreException ex) {
 
  375                 Logger.
getLogger(
HashDbManager.class.getName()).log(Level.SEVERE, 
"Error getting hash set path of " + hashDatabase.getHashSetName() + 
" hash set when removing the hash set", ex); 
 
  379                 hashDatabase.close();
 
  380             } 
catch (TskCoreException ex) {
 
  381                 Logger.
getLogger(
HashDbManager.class.getName()).log(Level.SEVERE, 
"Error closing " + hashDb.getHashSetName() + 
" hash set when removing the hash set", ex); 
 
  387             changeSupport.firePropertyChange(
SetEvt.
DB_DELETED.toString(), null, hashSetName);
 
  388         } 
catch (Exception e) {
 
  389             logger.log(Level.SEVERE, 
"HashDbManager listener threw exception", e); 
 
  391                     NbBundle.getMessage(
this.getClass(), 
"HashDbManager.moduleErr"),
 
  392                     NbBundle.getMessage(
this.getClass(), 
"HashDbManager.moduleErrorListeningToUpdatesMsg"),
 
  397     void save() throws HashDbManagerException {
 
  399             if (!HashLookupSettings.writeSettings(
new HashLookupSettings(HashLookupSettings.convertHashSetList(
this.hashSets)))) {
 
  400                 throw new HashDbManagerException(NbBundle.getMessage(
this.getClass(), 
"HashDbManager.saveErrorExceptionMsg"));
 
  402         } 
catch (HashLookupSettings.HashLookupSettingsException ex) {
 
  403             throw new HashDbManagerException(NbBundle.getMessage(
this.getClass(), 
"HashDbManager.saveErrorExceptionMsg"));
 
  417         } 
catch (TskCoreException ex){
 
  421         List<HashDb> hashDbs = 
new ArrayList<>();
 
  422         hashDbs.addAll(this.hashSets);
 
  432         List<HashDb> hashDbs = 
new ArrayList<>();
 
  435         } 
catch (TskCoreException ex){
 
  450         List<HashDb> hashDbs = 
new ArrayList<>();
 
  453         } 
catch (TskCoreException ex){
 
  472         ArrayList<HashDb> updateableDbs = 
new ArrayList<>();
 
  475         } 
catch (TskCoreException ex){
 
  478         for (
HashDb db : hashDbs) {
 
  480                 if (db.isUpdateable()) {
 
  481                     updateableDbs.add(db);
 
  483             } 
catch (TskCoreException ex) {
 
  484                 Logger.
getLogger(
HashDbManager.class.getName()).log(Level.SEVERE, 
"Error checking updateable status of " + db.getHashSetName() + 
" hash set", ex); 
 
  487         return updateableDbs;
 
  491         List<HashDbInfo> crHashSets = 
new ArrayList<>();
 
  501                     crHashSets.add(
new HashDbInfo(globalSet.getSetName(), globalSet.getVersion(),
 
  502                         globalSet.getGlobalSetID(), 
convertFileKnown(globalSet.getFileKnownStatus()), globalSet.isReadOnly(), 
false, sendIngestMessages));
 
  512         if(fileKnown.equals(TskData.FileKnown.BAD)){
 
  524         hashSetNames.clear();
 
  525         hashSetPaths.clear();
 
  531         for (
HashDb database : hashDatabases) {
 
  532             if(database instanceof SleuthkitHashSet){
 
  534                     ((SleuthkitHashSet)database).close();
 
  535                 } 
catch (TskCoreException ex) {
 
  540         hashDatabases.clear();
 
  545             HashLookupSettings settings = HashLookupSettings.readSettings();
 
  547         } 
catch (HashLookupSettings.HashLookupSettingsException ex) {
 
  558     @Messages({
"# {0} - hash set name", 
"HashDbManager.noDbPath.message=Couldn't get valid hash set path for: {0}",
 
  559             "HashDbManager.centralRepoLoadError.message=Error loading central repository hash sets"})
 
  561         allDatabasesLoadedCorrectly = 
true;
 
  562         List<HashDbInfo> hashDbInfoList = settings.getHashDbInfo();
 
  563         for (HashDbInfo hashDbInfo : hashDbInfoList) {
 
  565                 if(hashDbInfo.isFileDatabaseType()){
 
  566                     String dbPath = this.
getValidFilePath(hashDbInfo.getHashSetName(), hashDbInfo.getPath());
 
  567                     if (dbPath != null) {
 
  568                         addHashDatabase(SleuthkitJNI.openHashDatabase(dbPath), hashDbInfo.getHashSetName(), hashDbInfo.getSearchDuringIngest(), hashDbInfo.getSendIngestMessages(), hashDbInfo.getKnownFilesType());
 
  570                         logger.log(Level.WARNING, Bundle.HashDbManager_noDbPath_message(hashDbInfo.getHashSetName()));
 
  571                         allDatabasesLoadedCorrectly = 
false;
 
  575                         addExistingCentralRepoHashSet(hashDbInfo.getHashSetName(), hashDbInfo.getVersion(), 
 
  576                                 hashDbInfo.getReferenceSetID(), 
 
  577                                 hashDbInfo.getSearchDuringIngest(), hashDbInfo.getSendIngestMessages(), 
 
  578                                 hashDbInfo.getKnownFilesType(), hashDbInfo.isReadOnly());
 
  581             } 
catch (TskCoreException ex) {
 
  583                 JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
 
  584                         NbBundle.getMessage(this.getClass(),
 
  585                                 "HashDbManager.unableToOpenHashDbMsg", hashDbInfo.getHashSetName()),
 
  586                         NbBundle.getMessage(
this.getClass(), 
"HashDbManager.openHashDbErr"),
 
  587                         JOptionPane.ERROR_MESSAGE);
 
  588                 allDatabasesLoadedCorrectly = 
false;
 
  595             } 
catch (TskCoreException ex){
 
  598                 JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
 
  599                         Bundle.HashDbManager_centralRepoLoadError_message(),
 
  600                         NbBundle.getMessage(this.getClass(), 
"HashDbManager.openHashDbErr"),
 
  601                         JOptionPane.ERROR_MESSAGE);
 
  602                 allDatabasesLoadedCorrectly = 
false;
 
  615                 HashLookupSettings.writeSettings(
new HashLookupSettings(HashLookupSettings.convertHashSetList(
this.hashSets)));
 
  616                 allDatabasesLoadedCorrectly = 
true;
 
  617             } 
catch (HashLookupSettings.HashLookupSettingsException ex) {
 
  618                 allDatabasesLoadedCorrectly = 
false;
 
  619                 logger.log(Level.SEVERE, 
"Could not overwrite hash set settings.", ex);
 
  627             for(HashDbInfo hashDbInfo : crHashDbInfoList) {
 
  629                     addExistingCentralRepoHashSet(hashDbInfo.getHashSetName(), hashDbInfo.getVersion(), 
 
  630                                 hashDbInfo.getReferenceSetID(), 
 
  631                                 hashDbInfo.getSearchDuringIngest(), hashDbInfo.getSendIngestMessages(), hashDbInfo.getKnownFilesType(),
 
  632                                 hashDbInfo.isReadOnly());   
 
  639         for(
HashDb db:this.hashSets){
 
  640             if(dbInfo.matches(db)){
 
  649         File database = 
new File(configuredPath);
 
  650         if (database.exists()) {
 
  651             return configuredPath;
 
  655         String newPath = null;
 
  657                 JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(),
 
  658                 NbBundle.getMessage(this.getClass(), 
"HashDbManager.dlgMsg.dbNotFoundAtLoc",
 
  659                         hashSetName, configuredPath),
 
  660                 NbBundle.getMessage(this.getClass(), 
"HashDbManager.dlgTitle.MissingDb"),
 
  661                 JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
 
  663             if (null != newPath && !newPath.isEmpty()) {
 
  664                 database = 
new File(newPath);
 
  665                 if (!database.exists()) {
 
  674         String filePath = null;
 
  675         JFileChooser fc = 
new JFileChooser();
 
  676         fc.setDragEnabled(
false);
 
  677         fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
 
  678         String[] EXTENSION = 
new String[]{
"txt", 
"idx", 
"hash", 
"Hash", 
"kdb"}; 
 
  679         FileNameExtensionFilter filter = 
new FileNameExtensionFilter(
 
  680                 NbBundle.getMessage(
this.getClass(), 
"HashDbManager.fileNameExtensionFilter.title"), EXTENSION);
 
  681         fc.setFileFilter(filter);
 
  682         fc.setMultiSelectionEnabled(
false);
 
  683         if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
 
  684             File f = fc.getSelectedFile();
 
  686                 filePath = f.getCanonicalPath();
 
  687             } 
catch (IOException ex) {
 
  707                 this.displayName = displayName;
 
  711                 return this.displayName;
 
  725         abstract String getDisplayName();
 
  733         abstract 
void setSearchDuringIngest(
boolean useForIngest);
 
  737         abstract 
void setSendIngestMessages(
boolean showInboxMessages);
 
  746         public abstract 
boolean isUpdateable() throws TskCoreException;
 
  756         public abstract 
void addHashes(Content content) throws TskCoreException;
 
  758         public abstract 
void addHashes(Content content, String comment) throws TskCoreException;
 
  760         public abstract 
void addHashes(List<HashEntry> hashes) throws TskCoreException;
 
  762         public abstract 
boolean lookupMD5Quick(Content content) throws TskCoreException;
 
  764         public abstract HashHitInfo 
lookupMD5(Content content) throws TskCoreException;
 
  772         abstract 
boolean isValid() throws TskCoreException;
 
  774         public abstract String 
getIndexPath() throws TskCoreException;
 
  776         public abstract 
boolean hasIndexOnly() throws TskCoreException;
 
  778         public abstract 
void firePropertyChange(String propertyName, Object oldValue, Object newValue);
 
  793     class SleuthkitHashSet extends 
HashDb{
 
  795         private static final long serialVersionUID = 1L;
 
  796         private final int handle;
 
  797         private final String hashSetName;
 
  798         private boolean searchDuringIngest;
 
  799         private boolean sendIngestMessages;
 
  801         private boolean indexing;
 
  802         private final PropertyChangeSupport propertyChangeSupport = 
new PropertyChangeSupport(
this);
 
  804         private SleuthkitHashSet(
int handle, String hashSetName, 
boolean useForIngest, 
boolean sendHitMessages, 
KnownFilesType knownFilesType) {
 
  805             this.handle = handle;
 
  806             this.hashSetName = hashSetName;
 
  807             this.searchDuringIngest = useForIngest;
 
  808             this.sendIngestMessages = sendHitMessages;
 
  809             this.knownFilesType = knownFilesType;
 
  810             this.indexing = 
false;
 
  821             propertyChangeSupport.addPropertyChangeListener(pcl);
 
  831             propertyChangeSupport.removePropertyChangeListener(pcl);
 
  844         String getDisplayName(){
 
  850             return SleuthkitJNI.getHashDatabasePath(handle);
 
  853         public void setIndexing(
boolean indexing){
 
  854             this.indexing = indexing; 
 
  859             return SleuthkitJNI.getHashDatabaseIndexPath(handle);
 
  864             return knownFilesType;
 
  869             return searchDuringIngest;
 
  873         void setSearchDuringIngest(
boolean useForIngest) {
 
  874             this.searchDuringIngest = useForIngest;
 
  879             return sendIngestMessages;
 
  883         void setSendIngestMessages(
boolean showInboxMessages) {
 
  884             this.sendIngestMessages = showInboxMessages;
 
  896             return SleuthkitJNI.isUpdateableHashDatabase(this.handle);
 
  908         public void addHashes(Content content) 
throws TskCoreException {
 
  923         public void addHashes(Content content, String comment) 
throws TskCoreException {
 
  925             assert content instanceof AbstractFile;
 
  926             if (content instanceof AbstractFile) {
 
  927                 AbstractFile file = (AbstractFile) content;
 
  928                 if (null != file.getMd5Hash()) {
 
  929                     SleuthkitJNI.addToHashDatabase(null, file.getMd5Hash(), null, null, comment, handle);
 
  942         public void addHashes(List<HashEntry> hashes) 
throws TskCoreException {
 
  943             SleuthkitJNI.addToHashDatabase(hashes, handle);
 
  956         public boolean lookupMD5Quick(Content content) 
throws TskCoreException {
 
  957             boolean result = 
false;
 
  958             assert content instanceof AbstractFile;
 
  959             if (content instanceof AbstractFile) {
 
  960                 AbstractFile file = (AbstractFile) content;
 
  961                 if (null != file.getMd5Hash()) {
 
  962                     result = SleuthkitJNI.lookupInHashDatabase(file.getMd5Hash(), handle);
 
  978         public HashHitInfo 
lookupMD5(Content content) 
throws TskCoreException {
 
  979             HashHitInfo result = null;
 
  981             assert content instanceof AbstractFile;
 
  982             if (content instanceof AbstractFile) {
 
  983                 AbstractFile file = (AbstractFile) content;
 
  984                 if (null != file.getMd5Hash()) {
 
  985                     result = SleuthkitJNI.lookupInHashDatabaseVerbose(file.getMd5Hash(), handle);
 
  998         boolean isValid() throws TskCoreException {
 
 1002         boolean hasIndex() throws TskCoreException {
 
 1003             return SleuthkitJNI.hashDatabaseHasLookupIndex(handle);
 
 1007         public boolean hasIndexOnly() throws TskCoreException {
 
 1008             return SleuthkitJNI.hashDatabaseIsIndexOnly(handle);
 
 1011         boolean canBeReIndexed() throws TskCoreException {
 
 1012             return SleuthkitJNI.hashDatabaseCanBeReindexed(handle);
 
 1015         boolean isIndexing() {
 
 1020         public void firePropertyChange(String propertyName, Object oldValue, Object newValue){
 
 1021             this.propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
 
 1024         private void close() throws TskCoreException {
 
 1025             SleuthkitJNI.closeHashDatabase(handle);
 
 1035         public int hashCode() {
 
 1037             code = 47 * code + Integer.hashCode(handle);
 
 1038             code = 47 * code + Objects.hashCode(this.hashSetName);
 
 1039             code = 47 * code + Objects.hashCode(this.propertyChangeSupport);
 
 1040             code = 47 * code + Objects.hashCode(this.knownFilesType);
 
 1045         public boolean equals(Object obj) {
 
 1049             if (getClass() != obj.getClass()) {
 
 1052             final SleuthkitHashSet other = (SleuthkitHashSet) obj;
 
 1053             if (!Objects.equals(
this.hashSetName, other.hashSetName)) {
 
 1056             if (this.knownFilesType != other.knownFilesType) {
 
 1067     class CentralRepoHashSet 
extends HashDb{
 
 1069         private static final long serialVersionUID = 1L;
 
 1070         private final String hashSetName;
 
 1071         private boolean searchDuringIngest;
 
 1072         private boolean sendIngestMessages;
 
 1073         private final HashDb.KnownFilesType knownFilesType;  
 
 1074         private final int referenceSetID;
 
 1075         private final String version;
 
 1076         private String orgName;
 
 1077         private final boolean readOnly;
 
 1078         private final PropertyChangeSupport propertyChangeSupport = 
new PropertyChangeSupport(
this);
 
 1080         @Messages({
"HashDbManager.CentralRepoHashDb.orgError=Error loading organization"})
 
 1081         private CentralRepoHashSet(String hashSetName, String version, 
int referenceSetID, 
 
 1082                 boolean useForIngest, 
boolean sendHitMessages, HashDb.KnownFilesType knownFilesType, 
 
 1084                 throws TskCoreException{
 
 1085             this.hashSetName = hashSetName;
 
 1086             this.version = version;
 
 1087             this.referenceSetID = referenceSetID;
 
 1088             this.searchDuringIngest = useForIngest;
 
 1089             this.sendIngestMessages = sendHitMessages;
 
 1090             this.knownFilesType = knownFilesType;
 
 1091             this.readOnly = readOnly;
 
 1094                 orgName = EamDb.getInstance().getReferenceSetOrganization(referenceSetID).getName();
 
 1095             } 
catch (EamDbException ex){
 
 1096                 Logger.getLogger(SleuthkitHashSet.class.getName()).log(Level.SEVERE, 
"Error looking up central repository organization for reference set " + referenceSetID, ex); 
 
 1097                 orgName = Bundle.HashDbManager_CentralRepoHashDb_orgError();
 
 1109             propertyChangeSupport.addPropertyChangeListener(pcl);
 
 1119             propertyChangeSupport.removePropertyChangeListener(pcl);
 
 1133         public String getDisplayName(){
 
 1134             if(! getVersion().isEmpty()){
 
 1141         String getVersion(){
 
 1145         String getOrgName(){
 
 1149         int getReferenceSetID(){
 
 1150             return referenceSetID;
 
 1165             return knownFilesType;
 
 1170             return searchDuringIngest;
 
 1174         void setSearchDuringIngest(
boolean useForIngest) {
 
 1175             this.searchDuringIngest = useForIngest;
 
 1180             return sendIngestMessages;
 
 1184         void setSendIngestMessages(
boolean showInboxMessages) {
 
 1185             this.sendIngestMessages = showInboxMessages;
 
 1196         public boolean isUpdateable() throws TskCoreException {
 
 1197             return (! readOnly);
 
 1209         public void addHashes(Content content) 
throws TskCoreException {
 
 1224         public void addHashes(Content content, String comment) 
throws TskCoreException {
 
 1226             assert content instanceof AbstractFile;
 
 1227             if (content instanceof AbstractFile) {
 
 1228                 AbstractFile file = (AbstractFile) content;
 
 1229                 if (null != file.getMd5Hash()) {
 
 1230                     TskData.FileKnown type;
 
 1231                     if(knownFilesType.equals(HashDb.KnownFilesType.KNOWN_BAD)){
 
 1232                         type = TskData.FileKnown.BAD;
 
 1234                         type = TskData.FileKnown.KNOWN;
 
 1238                         EamGlobalFileInstance fileInstance = 
new EamGlobalFileInstance(referenceSetID, file.getMd5Hash(),
 
 1240                         EamDb.getInstance().addReferenceInstance(fileInstance,EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID));
 
 1241                     } 
catch (EamDbException ex){
 
 1242                         throw new TskCoreException(
"Error adding hashes to " + getDisplayName(), ex);
 
 1256         public void addHashes(List<HashEntry> hashes) 
throws TskCoreException {
 
 1257             Set<EamGlobalFileInstance> globalFileInstances = 
new HashSet<>();
 
 1258             for(HashEntry hashEntry:hashes){
 
 1259                 TskData.FileKnown type;
 
 1260                 if(knownFilesType.equals(HashDb.KnownFilesType.KNOWN_BAD)){
 
 1261                     type = TskData.FileKnown.BAD;
 
 1263                     type = TskData.FileKnown.KNOWN;
 
 1266                     globalFileInstances.add(
new EamGlobalFileInstance(referenceSetID, hashEntry.getMd5Hash(), type, hashEntry.getComment()));
 
 1267                 } 
catch (EamDbException ex){
 
 1268                     throw new TskCoreException(
"Error adding hashes to " + getDisplayName(), ex);
 
 1273                 EamDb.getInstance().bulkInsertReferenceTypeEntries(globalFileInstances, 
 
 1274                         EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID));
 
 1275             } 
catch (EamDbException ex){
 
 1276                 throw new TskCoreException(
"Error adding hashes to " + getDisplayName(), ex);
 
 1290         public boolean lookupMD5Quick(Content content) 
throws TskCoreException {
 
 1292             assert content instanceof AbstractFile;
 
 1293             if (content instanceof AbstractFile) {
 
 1294                 AbstractFile file = (AbstractFile) content;
 
 1295                 if (null != file.getMd5Hash()) {
 
 1297                         return EamDb.getInstance().isFileHashInReferenceSet(file.getMd5Hash(), this.referenceSetID);
 
 1298                     } 
catch (EamDbException ex){
 
 1299                         Logger.getLogger(SleuthkitHashSet.class.getName()).log(Level.SEVERE, 
"Error performing central reposiotry hash lookup for hash " 
 1300                                 + file.getMd5Hash() + 
" in reference set " + referenceSetID, ex); 
 
 1301                         throw new TskCoreException(
"Error performing central reposiotry hash lookup", ex);
 
 1318         public HashHitInfo 
lookupMD5(Content content) 
throws TskCoreException {
 
 1319             HashHitInfo result = null;
 
 1321             assert content instanceof AbstractFile;
 
 1322             if (content instanceof AbstractFile) {
 
 1323                 AbstractFile file = (AbstractFile) content;
 
 1324                 if (null != file.getMd5Hash()) {
 
 1326                         if(EamDb.getInstance().isFileHashInReferenceSet(file.getMd5Hash(), this.referenceSetID)){
 
 1328                             result = 
new HashHitInfo(file.getMd5Hash(), 
"", 
"");
 
 1330                     } 
catch (EamDbException ex){
 
 1331                         Logger.getLogger(SleuthkitHashSet.class.getName()).log(Level.SEVERE, 
"Error performing central reposiotry hash lookup for hash " 
 1332                                 + file.getMd5Hash() + 
" in reference set " + referenceSetID, ex); 
 
 1333                         throw new TskCoreException(
"Error performing central reposiotry hash lookup", ex);
 
 1347             if(! EamDb.isEnabled()) {
 
 1351                 return EamDb.getInstance().referenceSetIsValid(this.referenceSetID, this.hashSetName, this.version);
 
 1352             } 
catch (EamDbException ex){
 
 1353                 Logger.getLogger(CentralRepoHashSet.class.getName()).log(Level.SEVERE, 
"Error validating hash set " + hashSetName, ex); 
 
 1359         public void firePropertyChange(String propertyName, Object oldValue, Object newValue){
 
 1360             this.propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
 
 1365             return getDisplayName();
 
 1370         public int hashCode() {
 
 1372             code = 47 * code + Objects.hashCode(this.hashSetName);
 
 1373             code = 47 * code + Objects.hashCode(this.version);
 
 1374             code = 47 * code + Integer.hashCode(this.referenceSetID);
 
 1375             code = 47 * code + Objects.hashCode(this.knownFilesType);
 
 1380         public boolean equals(Object obj) {
 
 1384             if (getClass() != obj.getClass()) {
 
 1387             final CentralRepoHashSet other = (CentralRepoHashSet) obj;
 
 1388             if (!Objects.equals(
this.hashSetName, other.hashSetName)) {
 
 1391             if (!Objects.equals(
this.version, other.version)) {
 
 1394             if (this.knownFilesType != other.knownFilesType) {
 
 1406         private ProgressHandle progress = null;
 
 1407         private SleuthkitHashSet hashDb = null;
 
 1410             this.hashDb = hashDb;
 
 1415             hashDb.setIndexing(
true);
 
 1416             progress = ProgressHandle.createHandle(
 
 1417                     NbBundle.getMessage(
this.getClass(), 
"HashDbManager.progress.indexingHashSet", hashDb.getHashSetName()));
 
 1419             progress.switchToIndeterminate();
 
 1421                 SleuthkitJNI.createLookupIndexForHashDatabase(hashDb.getHandle());
 
 1422             } 
catch (TskCoreException ex) {
 
 1424                 JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
 
 1425                         NbBundle.getMessage(this.getClass(),
 
 1426                                 "HashDbManager.dlgMsg.errorIndexingHashSet",
 
 1427                                 hashDb.getHashSetName()),
 
 1428                         NbBundle.getMessage(
this.getClass(), 
"HashDbManager.hashDbIndexingErr"),
 
 1429                         JOptionPane.ERROR_MESSAGE);
 
 1436             hashDb.setIndexing(
false);
 
 1442             } 
catch (InterruptedException | ExecutionException ex) {
 
 1443                 logger.log(Level.SEVERE, 
"Error creating index", ex); 
 
 1445                         NbBundle.getMessage(
this.getClass(), 
"HashDbManager.errCreatingIndex.title"),
 
 1446                         NbBundle.getMessage(
this.getClass(), 
"HashDbManager.errCreatingIndex.msg", ex.getMessage()),
 
 1449             catch (java.util.concurrent.CancellationException ex) {
 
 1453                 hashDb.firePropertyChange(SleuthkitHashSet.Event.INDEXING_DONE.toString(), null, hashDb);
 
 1455             } 
catch (Exception e) {
 
 1456                 logger.log(Level.SEVERE, 
"HashDbManager listener threw exception", e); 
 
 1458                         NbBundle.getMessage(
this.getClass(), 
"HashDbManager.moduleErr"),
 
 1459                         NbBundle.getMessage(
this.getClass(), 
"HashDbManager.moduleErrorListeningToUpdatesMsg"),
 
CorrelationAttribute.Type getCorrelationTypeById(int typeId)
 
abstract boolean getSendIngestMessages()
 
Set< String > hashSetPaths
 
abstract String getIndexPath()
 
void configureSettings(HashLookupSettings settings)
 
static final Logger logger
 
static final String HASH_DATABASE_FILE_EXTENSON
 
void loadHashsetsConfiguration()
 
static synchronized IngestManager getInstance()
 
static boolean runningWithGUI
 
synchronized void addPropertyChangeListener(PropertyChangeListener listener)
 
HashDbManagerException(String message)
 
static final int FILES_TYPE_ID
 
abstract String getHashSetName()
 
List< HashDbInfo > getCentralRepoHashSetsFromDatabase()
 
boolean isIngestRunning()
 
static final long serialVersionUID
 
List< HashDb > getUpdateableHashSets(List< HashDb > hashDbs)
 
abstract String toString()
 
synchronized HashDb addNewHashDatabaseNoSave(String hashSetName, String path, boolean searchDuringIngest, boolean sendIngestMessages, HashDb.KnownFilesType knownFilesType)
 
HashDbManagerException(String message, Throwable exception)
 
synchronized void removeHashDatabase(HashDb hashDb)
 
KnownFilesType(String displayName)
 
boolean allDatabasesLoadedCorrectly
 
abstract void firePropertyChange(String propertyName, Object oldValue, Object newValue)
 
synchronized List< HashDb > getKnownBadFileHashSets()
 
static EamDb getInstance()
 
boolean hashDbInfoIsNew(HashDbInfo dbInfo)
 
synchronized void removeHashDatabaseNoSave(HashDb hashDb)
 
static HashDbManager instance
 
Set< String > hashSetNames
 
static synchronized HashDbManager getInstance()
 
String getValidFilePath(String hashSetName, String configuredPath)
 
static HashDb.KnownFilesType convertFileKnown(TskData.FileKnown fileKnown)
 
abstract HashDb.KnownFilesType getKnownFilesType()
 
List< EamGlobalSet > getAllReferenceSets(CorrelationAttribute.Type correlationType)
 
synchronized HashDb addNewHashDatabase(String hashSetName, String path, boolean searchDuringIngest, boolean sendIngestMessages, HashDb.KnownFilesType knownFilesType)
 
synchronized void removePropertyChangeListener(PropertyChangeListener listener)
 
static boolean isEnabled()
 
abstract HashHitInfo lookupMD5(Content content)
 
synchronized List< HashDb > getUpdateableHashSets()
 
synchronized List< HashDb > getAllHashSets()
 
abstract boolean isUpdateable()
 
abstract boolean lookupMD5Quick(Content content)
 
abstract String getDatabasePath()
 
void propertyChange(PropertyChangeEvent event)
 
void closeHashDatabases(List< HashDb > hashDatabases)
 
synchronized void loadLastSavedConfiguration()
 
abstract void addPropertyChangeListener(PropertyChangeListener pcl)
 
synchronized static Logger getLogger(String name)
 
static void show(String title, String message, MessageType type, ActionListener actionListener)
 
abstract boolean hasIndexOnly()
 
SleuthkitHashSet addHashDatabase(int handle, String hashSetName, boolean searchDuringIngest, boolean sendIngestMessages, HashDb.KnownFilesType knownFilesType)
 
abstract boolean getSearchDuringIngest()
 
void updateHashSetsFromCentralRepository()
 
synchronized List< HashDb > getKnownFileHashSets()
 
synchronized HashDb addExistingHashDatabase(String hashSetName, String path, boolean searchDuringIngest, boolean sendIngestMessages, HashDb.KnownFilesType knownFilesType)
 
abstract void addHashes(Content content)
 
abstract void removePropertyChangeListener(PropertyChangeListener pcl)