file_ctx->log_file_event(flow, policy);
policy->log_file_action(flow, file_ctx, FILE_RESUME_BLOCK);
}
- else
+ else if (file_ctx->is_cacheable())
store_verdict(flow, file_ctx, block_timeout);
return true;
context->check_policy(flow, dir, file_policy);
if (!index)
+ {
context->set_file_id(get_new_file_instance());
+ context->set_not_cacheable();
+ }
else
context->set_file_id(index);
{
int64_t file_depth = FileService::get_max_file_depth();
bool continue_processing;
+ bool cacheable = file_id or offset;
+
if (!multi_file_processing_id)
multi_file_processing_id = file_id;
if (!context)
return false;
+ if (!cacheable)
+ context->set_not_cacheable();
+
set_current_file_context(context);
if (!context->get_processed_bytes())
context->set_file_id(file_id);
}
- if ( offset != 0 and
+ if ( offset != 0 and context->is_cacheable() and
(FileService::get_file_cache()->cached_verdict_lookup(p, context, file_policy) !=
FILE_VERDICT_UNKNOWN) )
{
return false;
}
- if ((FileService::get_file_cache()->cached_verdict_lookup(p, this,
- policy) != FILE_VERDICT_UNKNOWN))
+ if (cacheable and (FileService::get_file_cache()->cached_verdict_lookup(p, this, policy) !=
+ FILE_VERDICT_UNKNOWN))
{
processing_complete = true;
return true;
static void print_file_data(FILE* fp, const uint8_t* data, int len, int max_depth);
void print(std::ostream&);
char* get_UTF8_fname(size_t* converted_len);
+ void set_not_cacheable() { cacheable = false; }
+ bool is_cacheable() { return cacheable; }
private:
uint64_t processed_bytes = 0;
FileSegments* file_segments;
FileInspect* inspector;
FileConfig* config;
+ bool cacheable = true;
inline void finalize_file_type();
inline void finish_signature_lookup(Packet*, bool, FilePolicyBase*);
// Clear MIME's file data to prepare for next file
file_counter++;
file_process_offset = 0;
- current_mime_file_id = 0;
+ current_file_cache_file_id = 0;
+ current_multiprocessing_file_id = 0;
continue_inspecting_file = true;
}
delete(log_state);
}
-uint64_t MimeSession::get_mime_file_id()
+// File verdicts get cached with key (file_id, sip, dip). File_id is hash of filename if available.
+// Otherwise file_id is 0 and verdict will not be cached.
+uint64_t MimeSession::get_file_cache_file_id()
{
- if (!current_mime_file_id)
+ if (!current_file_cache_file_id and filename.length() > 0)
+ current_file_cache_file_id = str_to_hash((const uint8_t*)filename.c_str(), filename.length());
+ return current_file_cache_file_id;
+}
+
+// This file id is used to store file contexts on the flow during processing. Each file processed
+// per flow needs a unique (per flow) id, so use hash of the URL (passed from http_inspect) with a
+// file counter
+uint64_t MimeSession::get_multiprocessing_file_id()
+{
+ if (!current_multiprocessing_file_id)
{
const int data_len = sizeof(session_base_file_id) + sizeof(file_counter);
uint8_t data[data_len];
memcpy(data, (void*)&session_base_file_id, sizeof(session_base_file_id));
memcpy(data + sizeof(session_base_file_id), (void*)&file_counter, sizeof(file_counter));
- current_mime_file_id = str_to_hash(data, data_len);
+ current_multiprocessing_file_id = str_to_hash(data, data_len);
}
- return current_mime_file_id;
+ return current_multiprocessing_file_id;
}
void MimeSession::mime_file_process(Packet* p, const uint8_t* data, int data_size,
{
const FileDirection dir = upload? FILE_UPLOAD : FILE_DOWNLOAD;
uint64_t offset = file_process_offset;
- // MIME has found the end of a file that file processing didn't want - tell file
- // processing it can clear this file's data
- if (!continue_inspecting_file)
- offset = 0;
- uint64_t file_id = get_mime_file_id();
- continue_inspecting_file = file_flows->file_process(p, file_id, data, data_size, offset,
- dir, file_id, position);
+ continue_inspecting_file = file_flows->file_process(p, get_file_cache_file_id(), data,
+ data_size, offset, dir, get_multiprocessing_file_id(), position);
}
else
{
uint32_t file_counter = 0;
uint32_t file_process_offset = 0;
uint64_t session_base_file_id = 0;
- uint64_t current_mime_file_id = 0;
- uint64_t get_mime_file_id();
+ uint64_t current_file_cache_file_id = 0;
+ uint64_t current_multiprocessing_file_id = 0;
+ uint64_t get_file_cache_file_id();
+ uint64_t get_multiprocessing_file_id();
void mime_file_process(Packet* p, const uint8_t* data, int data_size,
FilePosition position, bool upload);
void reset_file_data();
size_t file_index = 0;
- if ((request != nullptr) and (request->get_http_uri() != nullptr))
+ // For downloads file_id for the file cache is the URL since that should be unique per file.
+ // Upload verdicts are not currently cached since we have no unique information.
+ // FIXIT-E For uploads use the filename for the file_id when available.
+ if ((request != nullptr) and (request->get_http_uri() != nullptr)
+ and (dir == FILE_DOWNLOAD))
{
file_index = request->get_http_uri()->get_file_proc_hash();
}