bool FileFlows::file_process(Packet* p, uint64_t file_id, const uint8_t* file_data,
int data_size, uint64_t offset, FileDirection dir, uint64_t multi_file_processing_id,
FilePosition position, const uint8_t* fname, uint32_t name_size,
- const uint8_t* url, uint32_t url_size, const std::string& host_name)
+ const uint8_t* url, uint32_t url_size, const std::string& host_name, const bool is_partial)
{
int64_t file_depth = FileService::get_max_file_depth();
bool continue_processing;
return false;
}
- if (context->has_to_re_eval() and context->processing_complete)
+ if (context->has_to_re_eval() and context->processing_complete and not is_partial)
context->reset();
+ context->set_partial_flag(is_partial);
context->set_weak_file_name((const char*)fname, name_size);
context->set_weak_url((const char*)url, url_size);
context->set_host(host_name.c_str(), host_name.size());
context->set_file_id(file_id);
}
- if (context->is_cacheable() and not is_new_context)
+ if ((context->is_cacheable() and not is_new_context) or context->is_partial_download()) // If partial header was seen - check file_cache
{
FileVerdict verdict = FileService::get_file_cache()->cached_verdict_lookup(p, context,
file_policy);
bool file_process(Packet* p, uint64_t file_id, const uint8_t* file_data,
int data_size, uint64_t offset, FileDirection, uint64_t multi_file_processing_id=0,
FilePosition=SNORT_FILE_POSITION_UNKNOWN, const uint8_t* fname = nullptr, uint32_t name_size = 0,
- const uint8_t* url = nullptr, uint32_t url_size = 0, const std::string& host_name = "");
+ const uint8_t* url = nullptr, uint32_t url_size = 0, const std::string& host_name = "", const bool is_partial = false);
static unsigned file_flow_data_id;
host_set = other.host_set;
verdict = other.verdict;
file_type_enabled = other.file_type_enabled;
+ is_partial = other.is_partial;
file_signature_enabled = other.file_signature_enabled;
file_capture_enabled = other.file_capture_enabled;
file_state = other.file_state;
policy->policy_check(flow, this);
}
+void FileInfo::set_partial_flag(bool partial)
+{
+ is_partial = partial;
+}
+
+bool FileInfo::is_partial_download() const
+{
+ return is_partial;
+}
+
void FileInfo::reset()
{
verdict = FILE_VERDICT_UNKNOWN;
info.unset_re_eval();
CHECK (false == info.has_to_re_eval());
}
+
+TEST_CASE ("is_partial", "[file_info]")
+{
+ FI_TEST info;
+ CHECK (false == info.is_partial_download());
+ info.set_partial_flag(true);
+ CHECK (true == info.is_partial_download());
+ info.set_partial_flag(false);
+ CHECK (false == info.is_partial_download());
+}
#endif
bool has_to_re_eval();
void unset_re_eval();
- // Flag which indicates that the file requires re-eval even though it was fully processed before.
- // If "true" and the policy was checked - has to be set to "false" again.
- bool re_eval = false;
+ void set_partial_flag(bool partial);
+ bool is_partial_download() const;
protected:
std::string file_name;
FileState file_state = { FILE_CAPTURE_SUCCESS, FILE_SIG_PROCESSING };
uint32_t policy_id = 0;
UserFileDataBase* user_file_data = nullptr;
+
+ // Flag which indicates that the file requires re-eval even though it was fully processed before.
+ // If "true" and the policy was checked - has to be set to "false" again.
+ bool re_eval = false;
+ // Indicates that file transmission goes through 206 HTTP Partial Content
+ bool is_partial = false;
};
class SO_PUBLIC FileContext : public FileInfo
// Configuration functions
void remove_segments();
void reset();
-
private:
uint64_t processed_bytes = 0;
void* file_type_context;
if (errno or end_ptr != hdr_content.c_str() + dash_pos)
return SNORT_FILE_POSITION_UNKNOWN;
+ // return middle no matter what range actually is
if (range_start != 0)
return SNORT_FILE_MIDDLE;
const bool front = (body_octets == 0) &&
(session_data->partial_inspected_octets[source_id] == 0);
const bool back = (session_data->cutter[source_id] == nullptr) || tcp_close;
+ bool is_partially_downloaded = false;
if (session_data->status_code_num != 206 or source_id != SRC_SERVER)
{
if (file_position == SNORT_FILE_POSITION_UNKNOWN)
return;
+
+ is_partially_downloaded = true;
}
const int32_t fp_length = (file_data.length() <=
uint64_t file_index = get_header(source_id)->get_file_cache_index();
// Get host from the header field.
std::string host = get_header(source_id)->get_host_header_field();
-
+
const uint8_t* filename_buffer = nullptr;
uint32_t filename_length = 0;
const uint8_t* filetype_buffer = nullptr;
bool continue_processing_file = file_flows->file_process(p, file_index, file_data.start(),
fp_length, session_data->file_octets[source_id], dir,
get_header(source_id)->get_multi_file_processing_id(), file_position,
- filename_buffer, filename_length, uri_buffer, uri_length, host);
+ filename_buffer, filename_length, uri_buffer, uri_length, host, is_partially_downloaded);
if (continue_processing_file)
{
session_data->file_depth_remaining[source_id] -= fp_length;