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