19 package com.basistech.df.cybertriage.autopsy.malwarescan;
 
   31 import java.security.MessageDigest;
 
   32 import java.security.NoSuchAlgorithmException;
 
   33 import java.text.MessageFormat;
 
   34 import java.util.ArrayList;
 
   35 import java.util.Collections;
 
   36 import java.util.HashMap;
 
   37 import java.util.HexFormat;
 
   38 import java.util.List;
 
   40 import java.util.Optional;
 
   42 import java.util.logging.Level;
 
   43 import java.util.stream.Collectors;
 
   44 import java.util.stream.Stream;
 
   45 import org.apache.commons.collections4.CollectionUtils;
 
   46 import org.apache.commons.collections4.MapUtils;
 
   47 import org.apache.commons.lang3.StringUtils;
 
   48 import org.apache.curator.shaded.com.google.common.collect.Lists;
 
   49 import org.openide.util.NbBundle.Messages;
 
   73 class MalwareScanIngestModule 
implements FileIngestModule {
 
   75     private static final SharedProcessing sharedProcessing = 
new SharedProcessing();
 
   76     private boolean uploadFiles;
 
   77     private boolean queryFiles;
 
   79     MalwareScanIngestModule(MalwareScanIngestSettings settings) {
 
   80         uploadFiles = settings.shouldUploadFiles();
 
   81         queryFiles = settings.shouldQueryFiles();  
 
   85     public void startUp(IngestJobContext context) 
throws IngestModuleException {
 
   86         sharedProcessing.startUp(context, uploadFiles);
 
   90     public ProcessResult process(AbstractFile af) {
 
   91         return sharedProcessing.process(af);
 
   95     public void shutDown() {
 
   96         sharedProcessing.shutDown();
 
  125                 "application/x-dosexec",
 
  126                 "application/vnd.microsoft.portable-executable",
 
  127                 "application/x-msdownload",
 
  130                 "application/dos-exe",
 
  132                 "application/x-winexe",
 
  133                 "application/msdos-windows",
 
  134                 "application/x-msdos-program" 
  135         ).collect(Collectors.toSet());
 
  141         private final BatchProcessor<FileRecord> 
batchProcessor = 
new BatchProcessor<FileRecord>(
 
  152             "MalwareScanIngestModule_malwareTypeDisplayName=Malware",
 
  153             "MalwareScanIngestModule_ShareProcessing_noLicense_title=No Cyber Triage License",
 
  154             "MalwareScanIngestModule_ShareProcessing_noLicense_desc=No Cyber Triage license could be loaded.  Cyber Triage processing will be disabled.",
 
  155             "MalwareScanIngestModule_ShareProcessing_noLookupsRemaining_title=No remaining lookups",
 
  156             "MalwareScanIngestModule_ShareProcessing_noLookupsRemaining_desc=There are no more remaining hash lookups for this license at this time.  Malware scanning will be disabled.",
 
  157             "MalwareScanIngestModule_ShareProcessing_lowLookupsLimitWarning_title=Hash Lookups Low",
 
  158             "# {0} - remainingLookups",
 
  159             "MalwareScanIngestModule_ShareProcessing_lowLookupsLimitWarning_desc=This license only has {0} lookups remaining.",
 
  160             "MalwareScanIngestModule_ShareProcessing_noUploadsRemaining_title=No remaining file uploads",
 
  161             "MalwareScanIngestModule_ShareProcessing_noUploadsRemaining_desc=There are no more remaining file uploads for this license at this time.  File uploading will be disabled.",
 
  162             "MalwareScanIngestModule_ShareProcessing_lowUploadsLimitWarning_title=File Uploads Limit Low",
 
  163             "# {0} - remainingUploads",
 
  164             "MalwareScanIngestModule_ShareProcessing_lowUploadsLimitWarning_desc=This license only has {0} file uploads remaining.",
 
  165             "MalwareScanIngestModule_ShareProcessing_startup_generalException_desc=An exception occurred on MalwareScanIngestModule startup.  See the log for more information.",
 
  166             "MalwareScanIngestModule_ShareProcessing_startup_invalidLicenseWarning_title=Invalid License",
 
  167             "MalwareScanIngestModule_ShareProcessing_startup_invalidLicenseWarning_desc=The current Cyber Triage license is no longer valid.  Please remove the license from the Cyber Triage options panel."})
 
  170             if (ingestJobState != null) {
 
  176             } 
catch (CTCloudException cloudEx) {
 
  177                 ingestJobState = IngestJobState.DISABLED;
 
  178                 logger.log(Level.WARNING, 
"An error occurred while starting the MalwareScanIngestModule.", cloudEx);
 
  179                 throw new IngestModuleException(cloudEx.getErrorDetails(), cloudEx);
 
  180             } 
catch (IllegalStateException stateEx) {
 
  181                 ingestJobState = IngestJobState.DISABLED;
 
  182                 logger.log(Level.WARNING, 
"An error occurred while starting the MalwareScanIngestModule.", stateEx);
 
  183                 throw new IngestModuleException(stateEx.getMessage(), stateEx);
 
  184             } 
catch (Exception ex) {
 
  185                 ingestJobState = IngestJobState.DISABLED;
 
  186                 logger.log(Level.WARNING, 
"An error occurred while starting the MalwareScanIngestModule.", ex);
 
  187                 throw new IngestModuleException(Bundle.MalwareScanIngestModule_ShareProcessing_startup_generalException_desc(), ex);
 
  201             Optional<LicenseInfo> licenseInfoOpt = ctSettingsPersistence.
loadLicenseInfo();
 
  202             if (licenseInfoOpt.isEmpty() || licenseInfoOpt.get().getDecryptedLicense() == null) {
 
  203                 throw new IllegalStateException(Bundle.MalwareScanIngestModule_ShareProcessing_noLicense_desc());
 
  211             if (lookupsRemaining <= 0) {
 
  213                         Bundle.MalwareScanIngestModule_ShareProcessing_noLookupsRemaining_title(),
 
  214                         Bundle.MalwareScanIngestModule_ShareProcessing_noLookupsRemaining_desc(),
 
  217                 return IngestJobState.DISABLED;
 
  218             } 
else if (lookupsRemaining < LOW_LOOKUPS_REMAINING) {
 
  220                         Bundle.MalwareScanIngestModule_ShareProcessing_lowLookupsLimitWarning_title(),
 
  221                         Bundle.MalwareScanIngestModule_ShareProcessing_lowLookupsLimitWarning_desc(lookupsRemaining),
 
  228                 if (uploadsRemaining <= 0) {
 
  230                             Bundle.MalwareScanIngestModule_ShareProcessing_noUploadsRemaining_title(),
 
  231                             Bundle.MalwareScanIngestModule_ShareProcessing_noUploadsRemaining_desc(),
 
  234                 } 
else if (lookupsRemaining < LOW_UPLOADS_REMAINING) {
 
  236                             Bundle.MalwareScanIngestModule_ShareProcessing_lowUploadsLimitWarning_title(),
 
  237                             Bundle.MalwareScanIngestModule_ShareProcessing_lowUploadsLimitWarning_desc(lookupsRemaining),
 
  244             return new IngestJobState(
 
  247                     new PathNormalizer(tskCase),
 
  249                     licenseInfoOpt.get(),
 
  264             limit = limit == null ? 0 : limit;
 
  265             used = used == null ? 0 : used;
 
  278                     if (StringUtils.isNotBlank(af.
getMd5Hash())) {
 
  290                 if (CollectionUtils.isNotEmpty(hashResults)) {
 
  292                         if (hashResult.getType() == hashType) {
 
  293                             return hashResult.getValue();
 
  298                 logger.log(Level.WARNING,
 
  299                         MessageFormat.format(
"An error occurred while processing hash for file name: {0} and obj id: {1} and hash type {2}.",
 
  336             if (StringUtils.isNotBlank(af.getSha1Hash())) {
 
  337                 return af.getSha1Hash();
 
  340             MessageDigest digest = MessageDigest.getInstance(
"SHA-1");
 
  343             byte[] buffer = 
new byte[8192];
 
  345                 n = afStream.
read(buffer);
 
  347                     digest.update(buffer, 0, n);
 
  350             byte[] hashBytes = digest.digest();
 
  351             String hashString = HexFormat.of().formatHex(hashBytes);
 
  365             "MalwareScanIngestModule_ShareProcessing_batchTimeout_title=Batch Processing Timeout",
 
  366             "MalwareScanIngestModule_ShareProcessing_batchTimeout_desc=Batch processing timed out" 
  370                 if (ingestJobState != null
 
  371                         && ingestJobState.isDoFileLookups()
 
  372                         && !ingestJobState.getIngestJobContext().fileIngestIsCancelled()
 
  374                         && EXECUTABLE_MIME_TYPES.contains(StringUtils.defaultString(ingestJobState.getFileTypeDetector().getMIMEType(af)).trim().toLowerCase())
 
  378                     if (StringUtils.isNotBlank(md5)) {
 
  379                         batchProcessor.add(
new FileRecord(af.
getId(), md5));
 
  382                 return ProcessResult.OK;
 
  383             } 
catch (TskCoreException ex) {
 
  385                         Bundle.MalwareScanIngestModule_SharedProcessing_generalProcessingError_title(),
 
  386                         Bundle.MalwareScanIngestModule_SharedProcessing_generalProcessingError_desc(),
 
  388                 return IngestModule.ProcessResult.ERROR;
 
  389             } 
catch (InterruptedException ex) {
 
  391                         Bundle.MalwareScanIngestModule_ShareProcessing_batchTimeout_title(),
 
  392                         Bundle.MalwareScanIngestModule_ShareProcessing_batchTimeout_desc(),
 
  394                 return IngestModule.ProcessResult.ERROR;
 
  406             "MalwareScanIngestModule_SharedProcessing_authTokenResponseError_title=Authentication API error",
 
  407             "# {0} - errorResponse",
 
  408             "MalwareScanIngestModule_SharedProcessing_authTokenResponseError_desc=Received error: ''{0}'' when fetching the API authentication token for the license",
 
  409             "MalwareScanIngestModule_SharedProcessing_repServicenResponseError_title=Lookup API error",
 
  410             "# {0} - errorResponse",
 
  411             "MalwareScanIngestModule_SharedProcessing_repServicenResponseError_desc=Received error: ''{0}'' when fetching hash lookup results",
 
  412             "MalwareScanIngestModule_SharedProcessing_exhaustedHashLookups_title=Hash Lookups Exhausted",
 
  413             "MalwareScanIngestModule_SharedProcessing_exhaustedHashLookups_desc=The remaining hash lookups for this license have been exhausted",
 
  414             "MalwareScanIngestModule_SharedProcessing_generalProcessingError_title=Hash Lookup Error",
 
  415             "MalwareScanIngestModule_SharedProcessing_generalProcessingError_desc=An error occurred while processing hash lookup results",})
 
  416         private void handleBatch(IngestJobState ingestJobState, List<FileRecord> fileRecords) {
 
  417             if (ingestJobState == null
 
  418                     || !ingestJobState.isDoFileLookups()
 
  419                     || ingestJobState.getIngestJobContext().fileIngestIsCancelled()
 
  420                     || fileRecords == null
 
  421                     || fileRecords.isEmpty()) {
 
  426             Map<String, List<Long>> md5ToObjId = 
new HashMap<>();
 
  428             for (FileRecord fr : fileRecords) {
 
  429                 if (fr == null || StringUtils.isBlank(fr.getMd5hash()) || fr.getObjId() <= 0) {
 
  435                         .computeIfAbsent(sanitizedMd5, (k) -> 
new ArrayList<>())
 
  439             List<String> md5Hashes = 
new ArrayList<>(md5ToObjId.keySet());
 
  441             if (md5Hashes.isEmpty()) {
 
  448             } 
catch (Exception ex) {
 
  450                         Bundle.MalwareScanIngestModule_SharedProcessing_generalProcessingError_title(),
 
  451                         Bundle.MalwareScanIngestModule_SharedProcessing_generalProcessingError_desc(),
 
  467             "MalwareScanIngestModule_SharedProcessing_exhaustedResultsHashLookups_title=Lookup Limits Exceeded",
 
  468             "MalwareScanIngestModule_SharedProcessing_exhaustedResultsHashLookups_desc=Not all files were processed because hash lookup limits were exceeded. Please try again when your limits reset.",})
 
  470             if (CollectionUtils.isEmpty(repResult)) {
 
  474             Map<Status, List<CTCloudBean>> statusGroupings = repResult.stream()
 
  475                     .filter(bean -> bean.getMalwareResult() != null)
 
  476                     .collect(Collectors.groupingBy(bean -> bean.getMalwareResult().getStatus()));
 
  479             List<CTCloudBean> found = statusGroupings.get(
Status.
FOUND);
 
  489             if (CollectionUtils.isNotEmpty(statusGroupings.get(
Status.
ERROR))) {
 
  491                         Bundle.MalwareScanIngestModule_SharedProcessing_generalProcessingError_title(),
 
  492                         Bundle.MalwareScanIngestModule_SharedProcessing_generalProcessingError_desc(),
 
  499                         Bundle.MalwareScanIngestModule_SharedProcessing_exhaustedResultsHashLookups_title(),
 
  500                         Bundle.MalwareScanIngestModule_SharedProcessing_exhaustedResultsHashLookups_desc(),
 
  517             if (CollectionUtils.isNotEmpty(results)
 
  518                     && ingestJobState.isDoFileLookups()
 
  519                     && ((performFileUpload && ingestJobState.isUploadUnknownFiles()) || (!performFileUpload && ingestJobState.isQueryForMissing()))) {
 
  521                 for (
CTCloudBean beingScanned : CollectionUtils.emptyIfNull(results)) {
 
  523                     String sanitizedMd5 = 
normalizedMd5(beingScanned.getMd5HashValue());
 
  524                     if (StringUtils.isBlank(sanitizedMd5)) {
 
  527                     List<Long> correspondingObjIds = md5ToObjId.get(sanitizedMd5);
 
  528                     if (CollectionUtils.isEmpty(correspondingObjIds)) {
 
  532                     if (performFileUpload) {
 
  533                         uploadFile(ingestJobState, sanitizedMd5, correspondingObjIds.get(0));
 
  536                     ingestJobState.getUnidentifiedHashes().put(sanitizedMd5, correspondingObjIds);
 
  551         private List<CTCloudBean> 
getHashLookupResults(IngestJobState ingestJobState, List<String> md5Hashes) 
throws CTCloudException {
 
  552             if (ingestJobState.getIngestJobContext().fileIngestIsCancelled()) {
 
  553                 return Collections.emptyList();
 
  561             if (remainingScans <= 0) {
 
  562                 ingestJobState.disableDoFileLookups();
 
  564                         Bundle.MalwareScanIngestModule_SharedProcessing_exhaustedHashLookups_title(),
 
  565                         Bundle.MalwareScanIngestModule_SharedProcessing_exhaustedHashLookups_desc(),
 
  567                 return Collections.emptyList();
 
  568             } 
else if (ingestJobState.getIngestJobContext().fileIngestIsCancelled()) {
 
  569                 return Collections.emptyList();
 
  573             if (ingestJobState.isUploadUnknownFiles()) {
 
  575                 if (remainingUploads <= 0) {
 
  576                     ingestJobState.disableUploadUnknownFiles();
 
  578                             Bundle.MalwareScanIngestModule_uploadFile_noRemainingFileUploads_title(),
 
  579                             Bundle.MalwareScanIngestModule_uploadFile_noRemainingFileUploads_desc(),
 
  598             return StringUtils.defaultString(orig).trim().toLowerCase();
 
  623             "MalwareScanIngestModule_uploadFile_notUploadable_title=Not Able to Upload",
 
  625             "MalwareScanIngestModule_uploadFile_notUploadable_desc=A file did not meet requirements for upload (object id: {0}).",
 
  626             "MalwareScanIngestModule_uploadFile_noRemainingFileUploads_title=No Remaining File Uploads",
 
  627             "MalwareScanIngestModule_uploadFile_noRemainingFileUploads_desc=There are no more file uploads on this license at this time.  File uploads will be disabled for remaining uploads.",})
 
  629             if (!ingestJobState.isUploadUnknownFiles() || ingestJobState.getIngestJobContext().fileIngestIsCancelled()) {
 
  633             AbstractFile af = ingestJobState.getTskCase().getAbstractFileById(objId);
 
  640                         Bundle.MalwareScanIngestModule_uploadFile_notUploadable_title(),
 
  641                         Bundle.MalwareScanIngestModule_uploadFile_notUploadable_desc(objId),
 
  649                 throw new CTCloudException(CTCloudException.ErrorCode.NETWORK_ERROR);
 
  652                 ingestJobState.disableUploadUnknownFiles();
 
  654                         Bundle.MalwareScanIngestModule_uploadFile_noRemainingFileUploads_title(),
 
  655                         Bundle.MalwareScanIngestModule_uploadFile_noRemainingFileUploads_desc(),
 
  659             } 
else if (ingestJobState.getIngestJobContext().fileIngestIsCancelled()) {
 
  667                     .setContentLength(af.
getSize())
 
  668                     .setFileInputStream(fileInputStream)
 
  676                     .setFilePath(ingestJobState.getPathNormalizer().normalizePath(af.
getUniquePath()))
 
  697             "MalwareScanIngestModule_longPollForNotFound_fileLookupPolling_title=Waiting for File Upload Results",
 
  698             "MalwareScanIngestModule_longPollForNotFound_fileLookupPolling_desc=Waiting for all uploaded files to complete scanning.",
 
  699             "MalwareScanIngestModule_longPollForNotFound_timeout_title=File Upload Results Timeout",
 
  700             "MalwareScanIngestModule_longPollForNotFound_timeout_desc=There was a timeout while waiting for file uploads to be processed.  Please try again later.",})
 
  702             if (!ingestJobState.isDoFileLookups()
 
  703                     || !ingestJobState.isQueryForMissing()
 
  704                     || MapUtils.isEmpty(ingestJobState.getUnidentifiedHashes())
 
  705                     || ingestJobState.getIngestJobContext().fileIngestIsCancelled()) {
 
  710                     Bundle.MalwareScanIngestModule_longPollForNotFound_fileLookupPolling_title(),
 
  711                     Bundle.MalwareScanIngestModule_longPollForNotFound_fileLookupPolling_desc()
 
  713             logger.log(Level.INFO, 
"Begin polling for malware status of file uploads.");
 
  715             Map<String, List<Long>> 
remaining = 
new HashMap<>(ingestJobState.getUnidentifiedHashes());
 
  718                 List<List<String>> md5Batches = Lists.partition(
new ArrayList<>(remaining.keySet()), BATCH_SIZE);
 
  719                 for (List<String> batch : md5Batches) {
 
  721                     if (!ingestJobState.isDoFileLookups() || ingestJobState.getIngestJobContext().fileIngestIsCancelled()) {
 
  727                     Map<Status, List<CTCloudBean>> statusGroupings = repResult.stream()
 
  728                             .filter(bean -> bean.getMalwareResult() != null)
 
  729                             .collect(Collectors.groupingBy(bean -> bean.getMalwareResult().getStatus()));
 
  732                     List<CTCloudBean> found = statusGroupings.get(
Status.
FOUND);
 
  737                     for (
CTCloudBean foundItem : CollectionUtils.emptyIfNull(found)) {
 
  739                         remaining.remove(normalizedMd5);
 
  743                 if (remaining.isEmpty()) {
 
  748                 long waitMultiplier = ((long) Math.pow(2, retry));
 
  750                 logger.log(Level.INFO, MessageFormat.format(
"Waiting {0} milliseconds before polling again for malware status of file uploads.", (waitMultiplier * FILE_UPLOAD_RETRY_SLEEP_MILLIS)));
 
  752                 for (
int i = 0; i < waitMultiplier; i++) {
 
  753                     if (!ingestJobState.isDoFileLookups() || ingestJobState.getIngestJobContext().fileIngestIsCancelled()) {
 
  757                     Thread.sleep(FILE_UPLOAD_RETRY_SLEEP_MILLIS);
 
  762                     Bundle.MalwareScanIngestModule_longPollForNotFound_timeout_title(),
 
  763                     Bundle.MalwareScanIngestModule_longPollForNotFound_timeout_desc(),
 
  779         private void createAnalysisResults(IngestJobState ingestJobState, List<CTCloudBean> repResult, Map<String, List<Long>> md5ToObjId) throws 
Blackboard.BlackboardException, TskCoreException {
 
  780             if (CollectionUtils.isEmpty(repResult)) {
 
  784             List<BlackboardArtifact> createdArtifacts = 
new ArrayList<>();
 
  787                 trans = ingestJobState.getTskCase().beginTransaction();
 
  789                     String sanitizedMd5 = 
normalizedMd5(result.getMd5HashValue());
 
  790                     List<Long> objIds = md5ToObjId.remove(sanitizedMd5);
 
  791                     if (CollectionUtils.isEmpty(objIds)) {
 
  795                     for (Long objId : objIds) {
 
  801                                 createdArtifacts.add(res);
 
  812                     createdArtifacts.clear();
 
  817             if (!CollectionUtils.isEmpty(createdArtifacts)) {
 
  818                 ingestJobState.getTskCase().getBlackboard().postArtifacts(
 
  820                         Bundle.MalwareScanIngestModuleFactory_displayName(),
 
  821                         ingestJobState.getIngestJobId()
 
  839             "MalwareScanIngestModule_SharedProcessing_createAnalysisResult_Yes=YES",
 
  840             "MalwareScanIngestModule_SharedProcessing_createAnalysisResult_No=NO" 
  844                 logger.log(Level.WARNING, MessageFormat.format(
"Attempting to create analysis result with invalid parameters [objId: {0}, cloud bean status: {1}]",
 
  860                     ? Bundle.MalwareScanIngestModule_SharedProcessing_createAnalysisResult_Yes()
 
  861                     : Bundle.MalwareScanIngestModule_SharedProcessing_createAnalysisResult_No();
 
  865             return ingestJobState.getTskCase().getBlackboard().newAnalysisResult(
 
  866                     ingestJobState.getMalwareType(),
 
  868                     ingestJobState.getDsId(),
 
  873                     Collections.emptyList(),
 
  874                     trans).getAnalysisResult();
 
  881             "MalwareScanIngestModule_SharedProcessing_flushTimeout_title=Processing Timeout",
 
  882             "MalwareScanIngestModule_SharedProcessing_flushTimeout_desc=A timeout occurred while finishing processing" 
  884         synchronized void shutDown() {
 
  886             if (ingestJobState == null) {
 
  892                 batchProcessor.flushAndReset();
 
  894             } 
catch (InterruptedException ex) {
 
  896                         Bundle.MalwareScanIngestModule_SharedProcessing_flushTimeout_title(),
 
  897                         Bundle.MalwareScanIngestModule_SharedProcessing_flushTimeout_desc(),
 
  899             } 
catch (Exception ex) {
 
  901                         Bundle.MalwareScanIngestModule_SharedProcessing_generalProcessingError_title(),
 
  902                         Bundle.MalwareScanIngestModule_SharedProcessing_generalProcessingError_desc(),
 
  906                 ingestJobState = null;
 
  918         private static void notifyWarning(String title, String message, Exception ex) {
 
  920             logger.log(Level.WARNING, message, ex);
 
  925             private final long objId;
 
  926             private final String md5hash;
 
  928             FileRecord(
long objId, String md5hash) {
 
  930                 this.md5hash = md5hash;
 
  937             String getMd5hash() {
 
  953         static class IngestJobState {
 
  955             static final IngestJobState DISABLED = 
new IngestJobState(
 
  966             private final SleuthkitCase tskCase;
 
  967             private final FileTypeDetector fileTypeDetector;
 
  968             private final LicenseInfo licenseInfo;
 
  969             private final BlackboardArtifact.Type malwareType;
 
  970             private final long dsId;
 
  971             private final long ingestJobId;
 
  972             private final boolean queryForMissing;
 
  973             private final Map<String, List<Long>> unidentifiedHashes = 
new HashMap<>();
 
  976             private boolean uploadUnknownFiles;
 
  977             private boolean doFileLookups;
 
  978             private final IngestJobContext ingestJobContext;
 
  979             private final PathNormalizer pathNormalizer;
 
  981             IngestJobState(IngestJobContext ingestJobContext, SleuthkitCase tskCase, PathNormalizer pathNormalizer, FileTypeDetector fileTypeDetector, LicenseInfo licenseInfo, BlackboardArtifact.Type malwareType, 
boolean uploadUnknownFiles, 
boolean doFileLookups) {
 
  982                 this.tskCase = tskCase;
 
  983                 this.fileTypeDetector = fileTypeDetector;
 
  984                 this.pathNormalizer = pathNormalizer;
 
  985                 this.licenseInfo = licenseInfo;
 
  986                 this.malwareType = malwareType;
 
  987                 this.dsId = ingestJobContext == null ? 0L : ingestJobContext.getDataSource().getId();
 
  988                 this.ingestJobId = ingestJobContext == null ? 0L : ingestJobContext.getJobId();
 
  989                 this.ingestJobContext = ingestJobContext;
 
  991                 this.queryForMissing = uploadUnknownFiles && doFileLookups;
 
  992                 this.uploadUnknownFiles = uploadUnknownFiles;
 
  993                 this.doFileLookups = doFileLookups;
 
  996             SleuthkitCase getTskCase() {
 
 1000             IngestJobContext getIngestJobContext() {
 
 1001                 return ingestJobContext;
 
 1004             FileTypeDetector getFileTypeDetector() {
 
 1005                 return fileTypeDetector;
 
 1008             LicenseInfo getLicenseInfo() {
 
 1012             BlackboardArtifact.Type getMalwareType() {
 
 1020             long getIngestJobId() {
 
 1024             Map<String, List<Long>> getUnidentifiedHashes() {
 
 1025                 return unidentifiedHashes;
 
 1028             boolean isQueryForMissing() {
 
 1029                 return queryForMissing;
 
 1032             boolean isUploadUnknownFiles() {
 
 1033                 return uploadUnknownFiles;
 
 1036             void disableUploadUnknownFiles() {
 
 1037                 this.uploadUnknownFiles = 
false;
 
 1040             boolean isDoFileLookups() {
 
 1041                 return doFileLookups;
 
 1044             void disableDoFileLookups() {
 
 1045                 this.doFileLookups = 
false;
 
 1048             public PathNormalizer getPathNormalizer() {
 
 1049                 return pathNormalizer;
 
static final long LOW_UPLOADS_REMAINING
Long getFileUploadLimit()
Significance getSignificance()
static final Set< String > EXECUTABLE_MIME_TYPES
static final Score SCORE_UNKNOWN
static long remaining(Long limit, Long used)
void longPollForNotFound(IngestJobState ingestJobState)
String getFileUploadUrl()
static final int NUM_FILE_UPLOAD_RETRIES
Long getFileUploadCount()
String getStatusDescription()
static CTApiDAO getInstance()
List< AnalysisResult > getAnalysisResults(BlackboardArtifact.Type artifactType)
static String getOrCalcMd5(AbstractFile af)
AnalysisResult createAnalysisResult(IngestJobState ingestJobState, SleuthkitCase.CaseDbTransaction trans, CTCloudBean cloudBean, Long objId)
final BatchProcessor< FileRecord > batchProcessor
MalwareResultBean getMalwareResult()
void uploadMeta(AuthenticatedRequestData authenticatedRequestData, MetadataUploadRequest metaRequest)
void handleNonFoundResults(IngestJobState ingestJobState, Map< String, List< Long >> md5ToObjId, List< CTCloudBean > results, boolean performFileUpload)
static void notifyWarning(String title, String message, Exception ex)
synchronized Optional< LicenseInfo > loadLicenseInfo()
static List< HashResult > calculateHashes(Content content, Collection< HashType > hashTypes)
static void info(String title, String message)
List< CTCloudBean > getReputationResults(AuthenticatedRequestData authenticatedRequestData, List< String > md5Hashes)
boolean uploadFile(IngestJobState ingestJobState, String md5, long objId)
void createAnalysisResults(IngestJobState ingestJobState, List< CTCloudBean > repResult, Map< String, List< Long >> md5ToObjId)
void handleBatch(IngestJobState ingestJobState, List< FileRecord > fileRecords)
static CTLicensePersistence getInstance()
static boolean isUploadable(AbstractFile af)
static final Logger logger
TskData.FileKnown getKnown()
void uploadFile(FileUploadRequest fileUploadRequest)
static final long MIN_UPLOAD_SIZE
static final long FLUSH_SECS_TIMEOUT
Long getHashLookupLimit()
static final long LOW_LOOKUPS_REMAINING
static final int BATCH_SIZE
Long getHashLookupCount()
SleuthkitCase getSleuthkitCase()
AuthTokenResponse getAuthToken(DecryptedLicenseResponse decrypted)
IngestJobState ingestJobState
FileUploadRequest setFileName(String fileName)
static final long MAX_UPLOAD_SIZE
static String getOrCalcSha1(AbstractFile af)
void handleLookupResults(IngestJobState ingestJobState, Map< String, List< Long >> md5ToObjId, List< CTCloudBean > repResult)
final CTLicensePersistence ctSettingsPersistence
static String getOrCalcHash(AbstractFile af, HashType hashType)
synchronized static Logger getLogger(String name)
static final String MALWARE_CONFIG
static Case getCurrentCaseThrows()
static final Type TSK_MALWARE
IngestJobState getNewJobState(IngestJobContext context, boolean uploadFiles)
static String getOrCalcSha256(AbstractFile af)
static String normalizedMd5(String orig)
List< CTCloudBean > getHashLookupResults(IngestJobState ingestJobState, List< String > md5Hashes)
static void warn(String title, String message)
static final long FILE_UPLOAD_RETRY_SLEEP_MILLIS