19 package org.sleuthkit.autopsy.modules.hashdatabase;
 
   21 import java.io.IOException;
 
   22 import java.util.ArrayList;
 
   23 import java.util.Collections;
 
   24 import java.util.HashMap;
 
   25 import java.util.List;
 
   26 import java.util.concurrent.atomic.AtomicLong;
 
   27 import java.util.logging.Level;
 
   28 import org.openide.util.NbBundle;
 
   29 import org.openide.util.NbBundle.Messages;
 
   53     "HashDbIngestModule.noKnownBadHashDbSetMsg=No known bad hash database set.",
 
   54     "HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=Known bad file search will not be executed.",
 
   55     "HashDbIngestModule.noKnownHashDbSetMsg=No known hash database set.",
 
   56     "HashDbIngestModule.knownFileSearchWillNotExecuteWarn=Known file search will not be executed." 
   61     private static final int MAX_COMMENT_SIZE = 500;
 
   65     private final HashLookupModuleSettings 
settings;
 
   66     private List<HashDb> knownBadHashSets = 
new ArrayList<>();
 
   67     private List<HashDb> knownHashSets = 
new ArrayList<>();
 
   69     private static final HashMap<Long, IngestJobTotals> totalsForIngestJobs = 
new HashMap<>();
 
   75         private AtomicLong totalKnownBadCount = 
new AtomicLong(0);
 
   76         private AtomicLong totalCalctime = 
new AtomicLong(0);
 
   77         private AtomicLong totalLookuptime = 
new AtomicLong(0);
 
   84             totalsForIngestJobs.put(ingestJobId, totals);
 
   90         this.settings = settings;
 
   95         jobId = context.getJobId();
 
   96         if (!hashDbManager.verifyAllDatabasesLoadedCorrectly()) {
 
   97             throw new IngestModuleException(
"Could not load all hash databases");
 
  104             getTotalsForIngestJobs(jobId);
 
  107             if (knownBadHashSets.isEmpty()) {
 
  110                         Bundle.HashDbIngestModule_noKnownBadHashDbSetMsg(),
 
  111                         Bundle.HashDbIngestModule_knownBadFileSearchWillNotExecuteWarn()));
 
  114             if (knownHashSets.isEmpty()) {
 
  117                         Bundle.HashDbIngestModule_noKnownHashDbSetMsg(),
 
  118                         Bundle.HashDbIngestModule_knownFileSearchWillNotExecuteWarn()));
 
  130         enabledHashSets.clear();
 
  131         for (
HashDb db : allHashSets) {
 
  132             if (settings.isHashSetEnabled(db.getHashSetName())) {
 
  135                         enabledHashSets.add(db);
 
  138                     logger.log(Level.WARNING, 
"Error getting index status for " + db.getHashSetName() + 
" hash database", ex); 
 
  165         if ((knownHashSets.isEmpty()) && (knownBadHashSets.isEmpty()) && (!settings.shouldCalculateHashes())) {
 
  175         if (md5Hash == null || md5Hash.isEmpty()) {
 
  177                 long calcstart = System.currentTimeMillis();
 
  179                 long delta = (System.currentTimeMillis() - calcstart);
 
  182             } 
catch (IOException ex) {
 
  183                 logger.log(Level.WARNING, 
"Error calculating hash of file " + name, ex); 
 
  186                         NbBundle.getMessage(this.getClass(),
 
  187                                 "HashDbIngestModule.fileReadErrorMsg",
 
  189                         NbBundle.getMessage(this.getClass(),
 
  190                                 "HashDbIngestModule.calcHashValueErr",
 
  197         boolean foundBad = 
false;
 
  199         for (
HashDb db : knownBadHashSets) {
 
  201                 long lookupstart = System.currentTimeMillis();
 
  203                 if (null != hashInfo) {
 
  210                         logger.log(Level.WARNING, 
"Couldn't set known bad state for file " + name + 
" - see sleuthkit log for details", ex); 
 
  213                                 NbBundle.getMessage(this.getClass(),
 
  214                                         "HashDbIngestModule.hashLookupErrorMsg",
 
  216                                 NbBundle.getMessage(this.getClass(),
 
  217                                         "HashDbIngestModule.settingKnownBadStateErr",
 
  221                     String hashSetName = db.getHashSetName();
 
  224                     ArrayList<String> comments = hashInfo.
getComments();
 
  226                     for (String c : comments) {
 
  231                         if (comment.length() > MAX_COMMENT_SIZE) {
 
  232                             comment = comment.substring(0, MAX_COMMENT_SIZE) + 
"...";
 
  237                     postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages());
 
  239                 long delta = (System.currentTimeMillis() - lookupstart);
 
  243                 logger.log(Level.WARNING, 
"Couldn't lookup known bad hash for file " + name + 
" - see sleuthkit log for details", ex); 
 
  246                         NbBundle.getMessage(this.getClass(),
 
  247                                 "HashDbIngestModule.hashLookupErrorMsg",
 
  249                         NbBundle.getMessage(this.getClass(),
 
  250                                 "HashDbIngestModule.lookingUpKnownBadHashValueErr",
 
  260             for (
HashDb db : knownHashSets) {
 
  262                     long lookupstart = System.currentTimeMillis();
 
  263                     if (db.lookupMD5Quick(file)) {
 
  268                             logger.log(Level.WARNING, 
"Couldn't set known state for file " + name + 
" - see sleuthkit log for details", ex); 
 
  272                     long delta = (System.currentTimeMillis() - lookupstart);
 
  276                     logger.log(Level.WARNING, 
"Couldn't lookup known hash for file " + name + 
" - see sleuthkit log for details", ex); 
 
  279                             NbBundle.getMessage(this.getClass(),
 
  280                                     "HashDbIngestModule.hashLookupErrorMsg",
 
  282                             NbBundle.getMessage(this.getClass(),
 
  283                                     "HashDbIngestModule.lookingUpKnownHashValueErr",
 
  293     @Messages({
"HashDbIngestModule.indexError.message=Failed to index hashset hit artifact for keyword search."})
 
  296             String MODULE_NAME = NbBundle.getMessage(
HashDbIngestModule.class, 
"HashDbIngestModule.moduleName");
 
  312                 logger.log(Level.SEVERE, 
"Unable to index blackboard artifact " + badFile.
getArtifactID(), ex); 
 
  314                         Bundle.HashDbIngestModule_indexError_message(), badFile.
getDisplayName());
 
  317             if (showInboxMessage) {
 
  318                 StringBuilder detailsSb = 
new StringBuilder();
 
  320                 detailsSb.append(
"<table border='0' cellpadding='4' width='280'>"); 
 
  322                 detailsSb.append(
"<tr>"); 
 
  323                 detailsSb.append(
"<th>") 
 
  324                         .append(NbBundle.getMessage(
this.getClass(), 
"HashDbIngestModule.postToBB.fileName"))
 
  326                 detailsSb.append(
"<td>") 
 
  327                         .append(abstractFile.
getName())
 
  329                 detailsSb.append(
"</tr>"); 
 
  331                 detailsSb.append(
"<tr>"); 
 
  332                 detailsSb.append(
"<th>") 
 
  333                         .append(NbBundle.getMessage(
this.getClass(), 
"HashDbIngestModule.postToBB.md5Hash"))
 
  335                 detailsSb.append(
"<td>").append(md5Hash).append(
"</td>"); 
 
  336                 detailsSb.append(
"</tr>"); 
 
  338                 detailsSb.append(
"<tr>"); 
 
  339                 detailsSb.append(
"<th>") 
 
  340                         .append(NbBundle.getMessage(
this.getClass(), 
"HashDbIngestModule.postToBB.hashsetName"))
 
  342                 detailsSb.append(
"<td>").append(hashSetName).append(
"</td>"); 
 
  343                 detailsSb.append(
"</tr>"); 
 
  345                 detailsSb.append(
"</table>"); 
 
  348                         NbBundle.getMessage(this.getClass(),
 
  349                                 "HashDbIngestModule.postToBB.knownBadMsg",
 
  351                         detailsSb.toString(),
 
  352                         abstractFile.
getName() + md5Hash,
 
  357             logger.log(Level.WARNING, 
"Error creating blackboard artifact", ex); 
 
  362             List<HashDb> knownBadHashSets, List<HashDb> knownHashSets) {
 
  364         totalsForIngestJobs.remove(jobId);
 
  366         if ((!knownBadHashSets.isEmpty()) || (!knownHashSets.isEmpty())) {
 
  367             StringBuilder detailsSb = 
new StringBuilder();
 
  369             detailsSb.append(
"<table border='0' cellpadding='4' width='280'>"); 
 
  371             detailsSb.append(
"<tr><td>") 
 
  372                     .append(NbBundle.getMessage(
HashDbIngestModule.class, 
"HashDbIngestModule.complete.knownBadsFound"))
 
  374             detailsSb.append(
"<td>").append(jobTotals.
totalKnownBadCount.get()).append(
"</td></tr>"); 
 
  376             detailsSb.append(
"<tr><td>") 
 
  377                     .append(NbBundle.getMessage(
HashDbIngestModule.class, 
"HashDbIngestModule.complete.totalCalcTime"))
 
  378                     .append(
"</td><td>").append(jobTotals.
totalCalctime.get()).append(
"</td></tr>\n"); 
 
  379             detailsSb.append(
"<tr><td>") 
 
  380                     .append(NbBundle.getMessage(
HashDbIngestModule.class, 
"HashDbIngestModule.complete.totalLookupTime"))
 
  381                     .append(
"</td><td>").append(jobTotals.
totalLookuptime.get()).append(
"</td></tr>\n"); 
 
  382             detailsSb.append(
"</table>"); 
 
  384             detailsSb.append(
"<p>") 
 
  385                     .append(NbBundle.getMessage(
HashDbIngestModule.class, 
"HashDbIngestModule.complete.databasesUsed"))
 
  386                     .append(
"</p>\n<ul>"); 
 
  387             for (
HashDb db : knownBadHashSets) {
 
  388                 detailsSb.append(
"<li>").append(db.getHashSetName()).append(
"</li>\n"); 
 
  391             detailsSb.append(
"</ul>"); 
 
  397                             "HashDbIngestModule.complete.hashLookupResults"),
 
  398                     detailsSb.toString()));
 
  405             postSummary(jobId, knownBadHashSets, knownHashSets);
 
static String calculateMd5(AbstractFile file)
 
synchronized long decrementAndGet(long jobId)
 
ProcessResult process(AbstractFile file)
 
static IngestMessage createDataMessage(String source, String subject, String detailsHtml, String uniqueKey, BlackboardArtifact data)
 
final HashLookupModuleSettings settings
 
static IngestMessage createErrorMessage(String source, String subject, String detailsHtml)
 
AtomicLong totalKnownBadCount
 
TskData.TSK_DB_FILES_TYPE_ENUM getType()
 
AtomicLong totalLookuptime
 
void startUp(org.sleuthkit.autopsy.ingest.IngestJobContext context)
 
synchronized long incrementAndGet(long jobId)
 
static IngestMessage createMessage(MessageType messageType, String source, String subject, String detailsHtml)
 
static synchronized IngestJobTotals getTotalsForIngestJobs(long ingestJobId)
 
void updateEnabledHashSets(List< HashDb > allHashSets, List< HashDb > enabledHashSets)
 
void postHashSetHitToBlackboard(AbstractFile abstractFile, String md5Hash, String hashSetName, String comment, boolean showInboxMessage)
 
synchronized List< HashDb > getKnownBadFileHashSets()
 
void addAttribute(BlackboardAttribute attr)
 
static synchronized HashDbManager getInstance()
 
void postMessage(final IngestMessage message)
 
void fireModuleDataEvent(ModuleDataEvent moduleDataEvent)
 
ArrayList< String > getComments()
 
SleuthkitCase getSleuthkitCase()
 
Blackboard getBlackboard()
 
static synchronized void postSummary(long jobId, List< HashDb > knownBadHashSets, List< HashDb > knownHashSets)
 
BlackboardArtifact newArtifact(int artifactTypeID)
 
static void error(String title, String message)
 
synchronized void indexArtifact(BlackboardArtifact artifact)
 
boolean setKnown(AbstractFile file, FileKnown fileKnown)
 
static Case getCurrentCase()
 
synchronized static Logger getLogger(String name)
 
static IngestMessage createWarningMessage(String source, String subject, String detailsHtml)
 
synchronized List< HashDb > getKnownFileHashSets()
 
static synchronized IngestServices getInstance()