From: Victor Julien Date: Sun, 7 Jun 2020 11:42:09 +0000 (+0200) Subject: app-layer: add ApplyTxConfig API X-Git-Tag: suricata-6.0.0-beta1~190 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5665fc830132a0359e01919dc054dbdcd85decdb;p=thirdparty%2Fsuricata.git app-layer: add ApplyTxConfig API Optional callback a parser can register for applying configuration to the 'transaction'. Most parsers have a bidirectional tx. For those parsers that have different types of transaction handling, this new callback can be used to properly apply the config. --- diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index 1ed11b36e1..0feab3ebe0 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -234,6 +234,12 @@ pub struct RustParser { pub get_tx_detect_flags: Option, pub get_tx_data: Option, + + // Function to apply config to a TX. Optional. Normal (bidirectional) + // transactions don't need to set this. It is meant for cases where + // the requests and responses are not sharing tx. It is then up to + // the implementation to make sure the config is applied correctly. + pub apply_tx_config: Option, } /// Create a slice, given a buffer and a length @@ -286,6 +292,7 @@ pub type GetTxIteratorFn = extern "C" fn (ipproto: u8, alproto: AppProto, pub type GetTxDetectFlagsFn = unsafe extern "C" fn(*mut c_void, u8) -> u64; pub type SetTxDetectFlagsFn = unsafe extern "C" fn(*mut c_void, u8, u64); pub type GetTxDataFn = unsafe extern "C" fn(*mut c_void) -> *mut AppLayerTxData; +pub type ApplyTxConfigFn = unsafe extern "C" fn (*mut c_void, *mut c_void, c_int, AppLayerTxConfig); // Defined in app-layer-register.h extern { diff --git a/rust/src/applayertemplate/template.rs b/rust/src/applayertemplate/template.rs index 6b241bfbdf..f59e474816 100644 --- a/rust/src/applayertemplate/template.rs +++ b/rust/src/applayertemplate/template.rs @@ -538,6 +538,7 @@ pub unsafe extern "C" fn rs_template_register_parser() { get_tx_detect_flags: None, set_tx_detect_flags: None, get_tx_data: None, + apply_tx_config: None, }; let ip_proto_str = CString::new("tcp").unwrap(); diff --git a/rust/src/dhcp/dhcp.rs b/rust/src/dhcp/dhcp.rs index d38cf932e1..094565eebf 100644 --- a/rust/src/dhcp/dhcp.rs +++ b/rust/src/dhcp/dhcp.rs @@ -452,6 +452,7 @@ pub unsafe extern "C" fn rs_dhcp_register_parser() { set_tx_detect_flags: None, get_tx_detect_flags: None, get_tx_data : None, + apply_tx_config : None, }; let ip_proto_str = CString::new("udp").unwrap(); diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index c95d9df3ca..72d2e37593 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -1033,6 +1033,7 @@ pub unsafe extern "C" fn rs_dns_udp_register_parser() { get_de_state: rs_dns_state_get_tx_detect_state, set_de_state: rs_dns_state_set_tx_detect_state, get_tx_data: Some(rs_dns_state_get_tx_data), + apply_tx_config: None, }; let ip_proto_str = CString::new("udp").unwrap(); @@ -1079,6 +1080,7 @@ pub unsafe extern "C" fn rs_dns_tcp_register_parser() { get_de_state: rs_dns_state_get_tx_detect_state, set_de_state: rs_dns_state_set_tx_detect_state, get_tx_data: Some(rs_dns_state_get_tx_data), + apply_tx_config: None, }; let ip_proto_str = CString::new("tcp").unwrap(); diff --git a/rust/src/ikev2/ikev2.rs b/rust/src/ikev2/ikev2.rs index 86ac3a778f..fae04be1d5 100644 --- a/rust/src/ikev2/ikev2.rs +++ b/rust/src/ikev2/ikev2.rs @@ -736,6 +736,7 @@ pub unsafe extern "C" fn rs_register_ikev2_parser() { get_tx_detect_flags: None, set_tx_detect_flags: None, get_tx_data : None, + apply_tx_config : None, }; let ip_proto_str = CString::new("udp").unwrap(); diff --git a/rust/src/krb/krb5.rs b/rust/src/krb/krb5.rs index 9602a0a4de..b52cc93d38 100644 --- a/rust/src/krb/krb5.rs +++ b/rust/src/krb/krb5.rs @@ -683,6 +683,7 @@ pub unsafe extern "C" fn rs_register_krb5_parser() { get_tx_detect_flags: Some(rs_krb5_tx_detect_flags_get), set_tx_detect_flags: Some(rs_krb5_tx_detect_flags_set), get_tx_data : None, + apply_tx_config : None, }; // register UDP parser let ip_proto_str = CString::new("udp").unwrap(); diff --git a/rust/src/ntp/ntp.rs b/rust/src/ntp/ntp.rs index 4a73f9e1c7..71d8277f42 100644 --- a/rust/src/ntp/ntp.rs +++ b/rust/src/ntp/ntp.rs @@ -435,6 +435,7 @@ pub unsafe extern "C" fn rs_register_ntp_parser() { get_tx_detect_flags: None, set_tx_detect_flags: None, get_tx_data : None, + apply_tx_config : None, }; let ip_proto_str = CString::new("udp").unwrap(); diff --git a/rust/src/rdp/rdp.rs b/rust/src/rdp/rdp.rs index d4a4d327da..25a678e206 100644 --- a/rust/src/rdp/rdp.rs +++ b/rust/src/rdp/rdp.rs @@ -533,6 +533,7 @@ pub unsafe extern "C" fn rs_rdp_register_parser() { get_tx_detect_flags: None, set_tx_detect_flags: None, get_tx_data: None, + apply_tx_config: None, }; let ip_proto_str = std::ffi::CString::new("tcp").unwrap(); diff --git a/rust/src/rfb/rfb.rs b/rust/src/rfb/rfb.rs index 5abbf7b6ca..85cb1982fa 100644 --- a/rust/src/rfb/rfb.rs +++ b/rust/src/rfb/rfb.rs @@ -725,6 +725,7 @@ pub unsafe extern "C" fn rs_rfb_register_parser() { get_tx_detect_flags: Some(rs_rfb_get_tx_detect_flags), set_tx_detect_flags: Some(rs_rfb_set_tx_detect_flags), get_tx_data: None, + apply_tx_config: None, }; let ip_proto_str = CString::new("tcp").unwrap(); diff --git a/rust/src/sip/sip.rs b/rust/src/sip/sip.rs index fb3b21a649..00be0a8bcc 100755 --- a/rust/src/sip/sip.rs +++ b/rust/src/sip/sip.rs @@ -413,6 +413,7 @@ pub unsafe extern "C" fn rs_sip_register_parser() { get_tx_detect_flags: None, set_tx_detect_flags: None, get_tx_data: None, + apply_tx_config: None, }; let ip_proto_str = CString::new("udp").unwrap(); diff --git a/rust/src/snmp/snmp.rs b/rust/src/snmp/snmp.rs index 5eb45a9b7e..4d11d9e871 100644 --- a/rust/src/snmp/snmp.rs +++ b/rust/src/snmp/snmp.rs @@ -615,6 +615,7 @@ pub unsafe extern "C" fn rs_register_snmp_parser() { get_tx_detect_flags: Some(rs_snmp_get_tx_detect_flags), set_tx_detect_flags: Some(rs_snmp_set_tx_detect_flags), get_tx_data : None, + apply_tx_config : None, }; let ip_proto_str = CString::new("udp").unwrap(); if AppLayerProtoDetectConfProtoDetectionEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { diff --git a/rust/src/ssh/ssh.rs b/rust/src/ssh/ssh.rs index 7d20b04cd6..5c5545b437 100644 --- a/rust/src/ssh/ssh.rs +++ b/rust/src/ssh/ssh.rs @@ -582,6 +582,7 @@ pub unsafe extern "C" fn rs_ssh_register_parser() { get_tx_detect_flags: Some(rs_ssh_get_tx_detect_flags), set_tx_detect_flags: Some(rs_ssh_set_tx_detect_flags), get_tx_data: None, + apply_tx_config: None, }; let ip_proto_str = CString::new("tcp").unwrap(); diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index e96c827dab..fd6b24c6ab 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -126,6 +126,7 @@ typedef struct AppLayerParserProtoCtx_ uint64_t (*GetTxDetectFlags)(void *tx, uint8_t dir); void (*SetTxDetectFlags)(void *tx, uint8_t dir, uint64_t); AppLayerTxData *(*GetTxData)(void *tx); + bool (*ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig); void (*SetStreamDepthFlag)(void *tx, uint8_t flags); @@ -605,6 +606,16 @@ void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto, SCReturn; } +void AppLayerParserRegisterApplyTxConfigFunc(uint8_t ipproto, AppProto alproto, + bool (*ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig)) +{ + SCEnter(); + + alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].ApplyTxConfig = ApplyTxConfig; + + SCReturn; +} + void AppLayerParserRegisterSetStreamDepthFlag(uint8_t ipproto, AppProto alproto, void (*SetStreamDepthFlag)(void *tx, uint8_t flags)) { @@ -1219,6 +1230,16 @@ AppLayerTxData *AppLayerParserGetTxData(uint8_t ipproto, AppProto alproto, void SCReturnPtr(NULL, "AppLayerTxData"); } +void AppLayerParserApplyTxConfig(uint8_t ipproto, AppProto alproto, + void *state, void *tx, enum ConfigAction mode, AppLayerTxConfig config) +{ + SCEnter(); + if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].ApplyTxConfig) { + alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].ApplyTxConfig(state, tx, mode, config); + } + SCReturn; +} + /***** General *****/ /** \retval int -1 in case of unrecoverable error. App-layer tracking stops for this flow. diff --git a/src/app-layer-parser.h b/src/app-layer-parser.h index 7b7e44e13f..733a819324 100644 --- a/src/app-layer-parser.h +++ b/src/app-layer-parser.h @@ -30,6 +30,7 @@ #include "util-file.h" #include "stream-tcp-private.h" #include "rust.h" +#include "util-config.h" /* Flags for AppLayerParserState. */ #define APP_LAYER_PARSER_EOF BIT_U8(0) @@ -189,6 +190,8 @@ void AppLayerParserRegisterSetStreamDepthFlag(uint8_t ipproto, AppProto alproto, void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto, AppLayerTxData *(*GetTxData)(void *tx)); +void AppLayerParserRegisterApplyTxConfigFunc(uint8_t ipproto, AppProto alproto, + bool (*ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig)); /***** Get and transaction functions *****/ @@ -240,6 +243,8 @@ void AppLayerParserSetTxDetectFlags(uint8_t ipproto, AppProto alproto, void *tx, bool AppLayerParserSupportsTxDetectFlags(AppProto alproto); AppLayerTxData *AppLayerParserGetTxData(uint8_t ipproto, AppProto alproto, void *tx); +void AppLayerParserApplyTxConfig(uint8_t ipproto, AppProto alproto, + void *state, void *tx, enum ConfigAction mode, AppLayerTxConfig); /***** General *****/ diff --git a/src/app-layer-register.c b/src/app-layer-register.c index 06c6d026e9..5ac182e964 100644 --- a/src/app-layer-register.c +++ b/src/app-layer-register.c @@ -181,6 +181,11 @@ int AppLayerRegisterParser(const struct AppLayerParser *p, AppProto alproto) p->GetTxData); } + if (p->ApplyTxConfig) { + AppLayerParserRegisterApplyTxConfigFunc(p->ip_proto, alproto, + p->ApplyTxConfig); + } + return 0; } diff --git a/src/app-layer-register.h b/src/app-layer-register.h index ea6190ee10..a6d5f75300 100644 --- a/src/app-layer-register.h +++ b/src/app-layer-register.h @@ -73,6 +73,7 @@ typedef struct AppLayerParser { uint64_t (*GetTxDetectFlags)(void *, uint8_t); AppLayerTxData *(*GetTxData)(void *tx); + bool (*ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig); } AppLayerParser; /**