From: Giuseppe Longo Date: Mon, 30 Sep 2024 13:12:44 +0000 (+0200) Subject: sdp: add sdp.connection_data sticky buffer X-Git-Tag: suricata-8.0.0-beta1~102 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=47d7024b8af43938e912cf04ceaaad5b8900318c;p=thirdparty%2Fsuricata.git sdp: add sdp.connection_data sticky buffer This adds a sticky buffer to match the "Connection data" field in both requests and responses. Ticket #7291 --- diff --git a/rust/src/sdp/detect.rs b/rust/src/sdp/detect.rs index af3554a780..5cf7d1253c 100644 --- a/rust/src/sdp/detect.rs +++ b/rust/src/sdp/detect.rs @@ -32,6 +32,7 @@ static mut G_SDP_SESSION_INFO_BUFFER_ID: c_int = 0; static mut G_SDP_URI_BUFFER_ID: c_int = 0; static mut G_SDP_EMAIL_BUFFER_ID: c_int = 0; static mut G_SDP_PHONE_NUMBER_BUFFER_ID: c_int = 0; +static mut G_SDP_CONNECTION_DATA_BUFFER_ID: c_int = 0; unsafe extern "C" fn sdp_session_name_setup( de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, @@ -317,6 +318,53 @@ unsafe extern "C" fn sdp_phone_number_get_data( false } +unsafe extern "C" fn sdp_conn_data_setup( + de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_SIP) != 0 { + return -1; + } + if DetectBufferSetActiveList(de, s, G_SDP_CONNECTION_DATA_BUFFER_ID) < 0 { + return -1; + } + return 0; +} + +unsafe extern "C" fn sdp_conn_data_get( + de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8, + tx: *const c_void, list_id: c_int, +) -> *mut c_void { + return DetectHelperGetData( + de, + transforms, + flow, + flow_flags, + tx, + list_id, + sdp_conn_data_get_data, + ); +} + +unsafe extern "C" fn sdp_conn_data_get_data( + tx: *const c_void, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32, +) -> bool { + let tx = cast_pointer!(tx, SIPTransaction); + let sdp_option = match direction.into() { + Direction::ToServer => tx.request.as_ref().and_then(|req| req.body.as_ref()), + Direction::ToClient => tx.response.as_ref().and_then(|resp| resp.body.as_ref()), + }; + if let Some(sdp) = sdp_option { + if let Some(ref c) = sdp.connection_data { + *buffer = c.as_ptr(); + *buffer_len = c.len() as u32; + return true; + } + } + *buffer = ptr::null(); + *buffer_len = 0; + false +} + #[no_mangle] pub unsafe extern "C" fn ScDetectSdpRegister() { let kw = SCSigTableElmt { @@ -430,4 +478,23 @@ pub unsafe extern "C" fn ScDetectSdpRegister() { true, sdp_phone_number_get, ); + let kw = SCSigTableElmt { + name: b"sdp.connection_data\0".as_ptr() as *const libc::c_char, + desc: b"sticky buffer to match on the SDP connection data field\0".as_ptr() + as *const libc::c_char, + url: b"/rules/sdp-keywords.html#sdp-connection-data\0".as_ptr() as *const libc::c_char, + Setup: sdp_conn_data_setup, + flags: SIGMATCH_NOOPT, + AppLayerTxMatch: None, + Free: None, + }; + let _ = DetectHelperKeywordRegister(&kw); + G_SDP_CONNECTION_DATA_BUFFER_ID = DetectHelperBufferMpmRegister( + b"sdp.connection_data\0".as_ptr() as *const libc::c_char, + b"sdp.connection_data\0".as_ptr() as *const libc::c_char, + ALPROTO_SIP, + true, + true, + sdp_conn_data_get, + ); }