From 2f24f49dba4c41469189a2472c276a07a3c33768 Mon Sep 17 00:00:00 2001 From: Giuseppe Longo Date: Mon, 30 Sep 2024 09:55:33 +0200 Subject: [PATCH] sdp: add sdp.session_name sticky buffer This adds a sticky buffer to match the "Session name" field in both requests and responses. Ticket #7291 --- rust/src/sdp/detect.rs | 100 +++++++++++++++++++++++++++++++++++ rust/src/sdp/mod.rs | 20 +++++++ src/detect-engine-register.c | 1 + 3 files changed, 121 insertions(+) create mode 100644 rust/src/sdp/detect.rs diff --git a/rust/src/sdp/detect.rs b/rust/src/sdp/detect.rs new file mode 100644 index 0000000000..546b99e0bb --- /dev/null +++ b/rust/src/sdp/detect.rs @@ -0,0 +1,100 @@ +/* Copyright (C) 2024 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +// written by Giuseppe Longo + +use crate::detect::{ + DetectBufferSetActiveList, DetectHelperBufferMpmRegister, DetectHelperGetData, + DetectHelperKeywordRegister, DetectSignatureSetAppProto, SCSigTableElmt, SIGMATCH_NOOPT, +}; +use crate::direction::Direction; +use crate::sip::sip::{SIPTransaction, ALPROTO_SIP}; +use std::os::raw::{c_int, c_void}; +use std::ptr; + +static mut G_SDP_SESSION_NAME_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, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_SIP) != 0 { + return -1; + } + if DetectBufferSetActiveList(de, s, G_SDP_SESSION_NAME_BUFFER_ID) < 0 { + return -1; + } + return 0; +} + +unsafe extern "C" fn sdp_session_name_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_session_name_get_data, + ); +} + +unsafe extern "C" fn sdp_session_name_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_message = 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_message { + let session_name = &sdp.session_name; + if !session_name.is_empty() { + *buffer = session_name.as_ptr(); + *buffer_len = session_name.len() as u32; + return true; + } + } + *buffer = ptr::null(); + *buffer_len = 0; + false +} + +#[no_mangle] +pub unsafe extern "C" fn ScDetectSdpRegister() { + let kw = SCSigTableElmt { + name: b"sdp.session_name\0".as_ptr() as *const libc::c_char, + desc: b"sticky buffer to match on the SDP session name field\0".as_ptr() + as *const libc::c_char, + url: b"/rules/sdp-keywords.html#sdp-session-name\0".as_ptr() as *const libc::c_char, + Setup: sdp_session_name_setup, + flags: SIGMATCH_NOOPT, + AppLayerTxMatch: None, + Free: None, + }; + let _ = DetectHelperKeywordRegister(&kw); + G_SDP_SESSION_NAME_BUFFER_ID = DetectHelperBufferMpmRegister( + b"sdp.session_name\0".as_ptr() as *const libc::c_char, + b"sdp.session_name\0".as_ptr() as *const libc::c_char, + ALPROTO_SIP, + true, + true, + sdp_session_name_get, + ); +} diff --git a/rust/src/sdp/mod.rs b/rust/src/sdp/mod.rs index 7f87c8b7e2..6aa7861d49 100644 --- a/rust/src/sdp/mod.rs +++ b/rust/src/sdp/mod.rs @@ -1,2 +1,22 @@ +/* Copyright (C) 2024 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +// written by Giuseppe Longo + +pub mod detect; pub mod logger; pub mod parser; diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index 0664bcb520..1c9f5848d4 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -748,6 +748,7 @@ void SigTableSetup(void) SCDetectSipRegister(); SCDetectTemplateRegister(); SCDetectLdapRegister(); + ScDetectSdpRegister(); for (size_t i = 0; i < preregistered_callbacks_nb; i++) { PreregisteredCallbacks[i]();