static inline void cleanDynamicContext (FileContext *context) { if (context->file_signature_context) free(context->file_signature_context); if(context->sha256) free(context->sha256); if(context->file_capture) file_capture_stop(context); if(context->file_name && context->file_name_saved) free(context->file_name); }
/* * Return: * 1: continue processing/log/block this file * 0: ignore this file */ static int process_file_context(FileContext *context, void *p, uint8_t *file_data, int data_size, FilePosition position, bool suspend_block_verdict) { Packet *pkt = (Packet *)p; void *ssnptr = pkt->ssnptr; if (!context) return 0; set_current_file_context(ssnptr, context); file_stats.file_data_total += data_size; if ((!context->file_type_enabled) && (!context->file_signature_enabled)) { updateFileSize(context, data_size, position); return 0; } /* if file config is changed, update it*/ if ((context->file_config != snort_conf->file_config) || (context->file_config_version != file_config_version)) { context->file_config = snort_conf->file_config; context->file_config_version = file_config_version; /* Reset file type context that relies on file_conf. * File type id will become UNKNOWN after file_type_id() * if in the middle of file and file type is CONTINUE (undecided) */ context->file_type_context = NULL; } if(check_http_partial_content(p)) { context->file_type_enabled = false; context->file_signature_enabled = false; return 0; } /*file type id*/ if (context->file_type_enabled) { File_Verdict verdict = FILE_VERDICT_UNKNOWN; file_type_id(context, file_data, data_size, position); /*Don't care unknown file type*/ if (context->file_type_id == SNORT_FILE_TYPE_UNKNOWN) { context->file_type_enabled = false; context->file_signature_enabled = false; updateFileSize(context, data_size, position); file_capture_stop(context); return 0; } if (context->file_type_id != SNORT_FILE_TYPE_CONTINUE) { if (file_type_cb) { verdict = file_type_cb(p, ssnptr, context->file_type_id, context->upload, context->file_id); file_stats.verdicts_type[verdict]++; } context->file_type_enabled = false; file_stats.files_processed[context->file_type_id][context->upload]++; #ifdef TARGET_BASED file_stats.files_by_proto[context->app_id]++; #endif } if (verdict == FILE_VERDICT_LOG ) { file_eventq_add(GENERATOR_FILE_TYPE, context->file_type_id, file_type_name(context->file_config, context->file_type_id), RULE_TYPE__ALERT); context->file_signature_enabled = false; pkt->packet_flags |= PKT_FILE_EVENT_SET; } else if (verdict == FILE_VERDICT_BLOCK) { file_eventq_add(GENERATOR_FILE_TYPE, context->file_type_id, file_type_name(context->file_config, context->file_type_id), RULE_TYPE__DROP); updateFileSize(context, data_size, position); context->file_signature_enabled = false; add_file_to_block(p, verdict, context->file_type_id, NULL); return 1; } else if (verdict == FILE_VERDICT_REJECT) { file_eventq_add(GENERATOR_FILE_TYPE, context->file_type_id, file_type_name(context->file_config, context->file_type_id), RULE_TYPE__REJECT); updateFileSize(context, data_size, position); context->file_signature_enabled = false; add_file_to_block(p, verdict, context->file_type_id, NULL); return 1; } else if (verdict == FILE_VERDICT_STOP) { context->file_signature_enabled = false; } else if (verdict == FILE_VERDICT_STOP_CAPTURE) { file_capture_stop(context); } } /* file signature calculation */ if (context->file_signature_enabled) { file_signature_sha256(context, file_data, data_size, position); file_stats.data_processed[context->file_type_id][context->upload] += data_size; updateFileSize(context, data_size, position); /*Fails to capture, when out of memory or size limit, need lookup*/ if (context->file_capture_enabled && file_capture_process(context, file_data, data_size, position)) { file_capture_stop(context); _file_signature_lookup(context, p, false, suspend_block_verdict); if (context->verdict != FILE_VERDICT_UNKNOWN) return 1; } FILE_REG_DEBUG_WRAP(if (context->sha256) file_sha256_print(context->sha256);) /*Either get SHA or exceeding the SHA limit, need lookup*/ if (context->file_state.sig_state != FILE_SIG_PROCESSING)