diff --git a/configure.ac b/configure.ac index 232ee9bed2b2..bbe62722f8f0 100644 --- a/configure.ac +++ b/configure.ac @@ -324,6 +324,17 @@ CFLAGS="$CFLAGS -std=gnu99" fi + # check if our target supports -Wl,--start-group + AC_MSG_CHECKING(for -Wl,--start-group support) + OLDFLAGS=$LDFLAGS + LDFLAGS="-Wl,--start-group,--end-group" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[ + have_linker_group_support=yes + AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no)]) + LDFLAGS=$OLDFLAGS + AM_CONDITIONAL([LINKER_SUPPORTS_GROUP], [test "x$have_linker_group_support" = "xyes"]) + # check if our target supports thread local storage AC_MSG_CHECKING(for thread local storage gnu __thread support) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], @@ -1419,7 +1430,7 @@ exit 1 fi CFLAGS="${CFLAGS} `pkg-config --cflags libdpdk`" - LIBS="${LIBS} -Wl,-R,`pkg-config --libs-only-L libdpdk | cut -c 3-` -lnuma `pkg-config --libs libdpdk`" + LIBS="${LIBS} -lnuma `pkg-config --libs libdpdk`" if test ! -z "$(ldconfig -p | grep librte_net_bond)"; then AC_DEFINE([HAVE_DPDK_BOND],[1],(DPDK Bond PMD support enabled)) diff --git a/doc/userguide/rules/snmp-keywords.rst b/doc/userguide/rules/snmp-keywords.rst index a5349c2e5056..8429f0d805d7 100644 --- a/doc/userguide/rules/snmp-keywords.rst +++ b/doc/userguide/rules/snmp-keywords.rst @@ -6,6 +6,8 @@ snmp.version SNMP protocol version (integer). Expected values are 1, 2 (for version 2c) or 3. +snmp.version uses an, :ref:` unsigned 32-bits integer `. + Syntax:: snmp.version:[op] @@ -69,6 +71,8 @@ snmp.pdu_type SNMP PDU type (integer). +snmp.pdu_type uses an, :ref:` unsigned 32-bits integer `. + Common values are: - 0: GetRequest diff --git a/examples/lib/simple/Makefile.am b/examples/lib/simple/Makefile.am index afc6505c3bae..c4004b9446c9 100644 --- a/examples/lib/simple/Makefile.am +++ b/examples/lib/simple/Makefile.am @@ -5,7 +5,7 @@ simple_SOURCES = main.c AM_CPPFLAGS = -I$(top_srcdir)/src simple_LDFLAGS = $(all_libraries) $(SECLDFLAGS) -simple_LDADD = $(top_builddir)/src/libsuricata_c.a ../../$(RUST_SURICATA_LIB) $(RUST_LDADD) +simple_LDADD = "-Wl,--start-group,$(top_builddir)/src/libsuricata_c.a,../../$(RUST_SURICATA_LIB),--end-group" $(RUST_LDADD) if HTP_LDADD simple_LDADD += ../../$(HTP_LDADD) endif diff --git a/rust/cbindgen.toml b/rust/cbindgen.toml index 3240f4661ef1..b277e00506d8 100644 --- a/rust/cbindgen.toml +++ b/rust/cbindgen.toml @@ -82,6 +82,7 @@ include = [ "QuicState", "QuicTransaction", "FtpEvent", + "SCSigTableElmt", ] # A list of items to not include in the generated bindings diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index 522143fb6d0e..dbf4b2cd2d4c 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -58,6 +58,9 @@ impl StreamSlice { self.input_len } pub fn as_slice(&self) -> &[u8] { + if self.input.is_null() && self.input_len == 0 { + return &[]; + } unsafe { std::slice::from_raw_parts(self.input, self.input_len as usize) } } pub fn is_empty(&self) -> bool { diff --git a/rust/src/detect/mod.rs b/rust/src/detect/mod.rs index 2b1fd0e464b0..bb2441798edb 100644 --- a/rust/src/detect/mod.rs +++ b/rust/src/detect/mod.rs @@ -27,6 +27,9 @@ pub mod uri; pub mod requires; pub mod tojson; +use crate::core::AppProto; +use std::os::raw::{c_int, c_void}; + /// EnumString trait that will be implemented on enums that /// derive StringEnum. pub trait EnumString { @@ -43,6 +46,64 @@ pub trait EnumString { fn from_str(s: &str) -> Option where Self: Sized; } +#[repr(C)] +#[allow(non_snake_case)] +pub struct SCSigTableElmt { + pub name: *const libc::c_char, + pub desc: *const libc::c_char, + pub url: *const libc::c_char, + pub flags: u16, + pub Setup: unsafe extern "C" fn( + de: *mut c_void, + s: *mut c_void, + raw: *const std::os::raw::c_char, + ) -> c_int, + pub Free: Option, + pub AppLayerTxMatch: Option< + unsafe extern "C" fn( + de: *mut c_void, + f: *mut c_void, + flags: u8, + state: *mut c_void, + tx: *mut c_void, + sig: *const c_void, + ctx: *const c_void, + ) -> c_int, + >, +} + +pub(crate) const SIGMATCH_NOOPT: u16 = 1; // BIT_U16(0) in detect.h +pub(crate) const SIGMATCH_INFO_STICKY_BUFFER: u16 = 0x200; // BIT_U16(9) + +extern { + pub fn DetectBufferSetActiveList(de: *mut c_void, s: *mut c_void, bufid: c_int) -> c_int; + pub fn DetectHelperGetData( + de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8, + tx: *const c_void, list_id: c_int, + get_buf: unsafe extern "C" fn(*const c_void, u8, *mut *const u8, *mut u32) -> bool, + ) -> *mut c_void; + pub fn DetectHelperBufferMpmRegister( + name: *const libc::c_char, desc: *const libc::c_char, alproto: AppProto, toclient: bool, + toserver: bool, + get_data: unsafe extern "C" fn( + *mut c_void, + *const c_void, + *const c_void, + u8, + *const c_void, + i32, + ) -> *mut c_void, + ) -> c_int; + pub fn DetectHelperKeywordRegister(kw: *const SCSigTableElmt) -> c_int; + pub fn DetectHelperBufferRegister( + name: *const libc::c_char, alproto: AppProto, toclient: bool, toserver: bool, + ) -> c_int; + pub fn DetectSignatureSetAppProto(s: *mut c_void, alproto: AppProto) -> c_int; + pub fn SigMatchAppendSMToList( + de: *mut c_void, s: *mut c_void, kwid: c_int, ctx: *const c_void, bufid: c_int, + ) -> *mut c_void; +} + #[cfg(test)] mod test { use super::*; diff --git a/rust/src/detect/uint.rs b/rust/src/detect/uint.rs index 5b28830cea6a..fdfc4c30f89f 100644 --- a/rust/src/detect/uint.rs +++ b/rust/src/detect/uint.rs @@ -398,9 +398,9 @@ pub unsafe extern "C" fn rs_detect_u64_match( } #[no_mangle] -pub unsafe extern "C" fn rs_detect_u64_free(ctx: *mut std::os::raw::c_void) { +pub unsafe extern "C" fn rs_detect_u64_free(ctx: &mut DetectUintData) { // Just unbox... - std::mem::drop(Box::from_raw(ctx as *mut DetectUintData)); + std::mem::drop(Box::from_raw(ctx)); } #[no_mangle] diff --git a/rust/src/dhcp/detect.rs b/rust/src/dhcp/detect.rs index 0215810ae847..73cf92538643 100644 --- a/rust/src/dhcp/detect.rs +++ b/rust/src/dhcp/detect.rs @@ -16,51 +16,208 @@ */ use super::dhcp::{ - DHCPTransaction, DHCP_OPT_ADDRESS_TIME, DHCP_OPT_REBINDING_TIME, DHCP_OPT_RENEWAL_TIME, + DHCPTransaction, ALPROTO_DHCP, DHCP_OPT_ADDRESS_TIME, DHCP_OPT_REBINDING_TIME, + DHCP_OPT_RENEWAL_TIME, }; use super::parser::DHCPOptionWrapper; +use crate::detect::uint::{ + rs_detect_u64_free, rs_detect_u64_match, rs_detect_u64_parse, DetectUintData, +}; +use crate::detect::{ + DetectHelperBufferRegister, DetectHelperKeywordRegister, DetectSignatureSetAppProto, + SCSigTableElmt, SigMatchAppendSMToList, +}; +use std::os::raw::{c_int, c_void}; -#[no_mangle] -pub unsafe extern "C" fn rs_dhcp_tx_get_leasetime( - tx: &mut DHCPTransaction, leasetime: *mut u64, -) -> u8 { +fn rs_dhcp_tx_get_time(tx: &DHCPTransaction, code: u8) -> Option { for option in &tx.message.options { - if option.code == DHCP_OPT_ADDRESS_TIME { + if option.code == code { if let DHCPOptionWrapper::TimeValue(ref time_value) = option.option { - *leasetime = time_value.seconds as u64; - return 1; + return Some(time_value.seconds as u64); } } } + return None; +} + +static mut G_DHCP_LEASE_TIME_KW_ID: c_int = 0; +static mut G_DHCP_LEASE_TIME_BUFFER_ID: c_int = 0; +static mut G_DHCP_REBINDING_TIME_KW_ID: c_int = 0; +static mut G_DHCP_REBINDING_TIME_BUFFER_ID: c_int = 0; +static mut G_DHCP_RENEWAL_TIME_KW_ID: c_int = 0; +static mut G_DHCP_RENEWAL_TIME_BUFFER_ID: c_int = 0; + +unsafe extern "C" fn dhcp_detect_leasetime_setup( + de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_DHCP) != 0 { + return -1; + } + let ctx = rs_detect_u64_parse(raw) as *mut c_void; + if ctx.is_null() { + return -1; + } + if SigMatchAppendSMToList( + de, + s, + G_DHCP_LEASE_TIME_KW_ID, + ctx, + G_DHCP_LEASE_TIME_BUFFER_ID, + ) + .is_null() + { + dhcp_detect_time_free(std::ptr::null_mut(), ctx); + return -1; + } return 0; } -#[no_mangle] -pub unsafe extern "C" fn rs_dhcp_tx_get_rebinding_time( - tx: &mut DHCPTransaction, res: *mut u64, -) -> u8 { - for option in &tx.message.options { - if option.code == DHCP_OPT_REBINDING_TIME { - if let DHCPOptionWrapper::TimeValue(ref time_value) = option.option { - *res = time_value.seconds as u64; - return 1; - } - } +unsafe extern "C" fn dhcp_detect_leasetime_match( + _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void, + _sig: *const c_void, ctx: *const c_void, +) -> c_int { + let tx = cast_pointer!(tx, DHCPTransaction); + let ctx = cast_pointer!(ctx, DetectUintData); + if let Some(val) = rs_dhcp_tx_get_time(tx, DHCP_OPT_ADDRESS_TIME) { + return rs_detect_u64_match(val, ctx); } return 0; } -#[no_mangle] -pub unsafe extern "C" fn rs_dhcp_tx_get_renewal_time( - tx: &mut DHCPTransaction, res: *mut u64, -) -> u8 { - for option in &tx.message.options { - if option.code == DHCP_OPT_RENEWAL_TIME { - if let DHCPOptionWrapper::TimeValue(ref time_value) = option.option { - *res = time_value.seconds as u64; - return 1; - } - } +unsafe extern "C" fn dhcp_detect_time_free(_de: *mut c_void, ctx: *mut c_void) { + // Just unbox... + let ctx = cast_pointer!(ctx, DetectUintData); + rs_detect_u64_free(ctx); +} + +unsafe extern "C" fn dhcp_detect_rebindingtime_setup( + de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_DHCP) != 0 { + return -1; + } + let ctx = rs_detect_u64_parse(raw) as *mut c_void; + if ctx.is_null() { + return -1; + } + if SigMatchAppendSMToList( + de, + s, + G_DHCP_REBINDING_TIME_KW_ID, + ctx, + G_DHCP_REBINDING_TIME_BUFFER_ID, + ) + .is_null() + { + dhcp_detect_time_free(std::ptr::null_mut(), ctx); + return -1; + } + return 0; +} + +unsafe extern "C" fn dhcp_detect_rebindingtime_match( + _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void, + _sig: *const c_void, ctx: *const c_void, +) -> c_int { + let tx = cast_pointer!(tx, DHCPTransaction); + let ctx = cast_pointer!(ctx, DetectUintData); + if let Some(val) = rs_dhcp_tx_get_time(tx, DHCP_OPT_REBINDING_TIME) { + return rs_detect_u64_match(val, ctx); + } + return 0; +} + +unsafe extern "C" fn dhcp_detect_renewaltime_setup( + de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_DHCP) != 0 { + return -1; + } + let ctx = rs_detect_u64_parse(raw) as *mut c_void; + if ctx.is_null() { + return -1; + } + if SigMatchAppendSMToList( + de, + s, + G_DHCP_RENEWAL_TIME_KW_ID, + ctx, + G_DHCP_RENEWAL_TIME_BUFFER_ID, + ) + .is_null() + { + dhcp_detect_time_free(std::ptr::null_mut(), ctx); + return -1; } return 0; } + +unsafe extern "C" fn dhcp_detect_renewaltime_match( + _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void, + _sig: *const c_void, ctx: *const c_void, +) -> c_int { + let tx = cast_pointer!(tx, DHCPTransaction); + let ctx = cast_pointer!(ctx, DetectUintData); + if let Some(val) = rs_dhcp_tx_get_time(tx, DHCP_OPT_RENEWAL_TIME) { + return rs_detect_u64_match(val, ctx); + } + return 0; +} + +#[no_mangle] +pub unsafe extern "C" fn ScDetectDHCPRegister() { + let kw = SCSigTableElmt { + name: b"dhcp.leasetime\0".as_ptr() as *const libc::c_char, + desc: b"match DHCP leasetime\0".as_ptr() as *const libc::c_char, + url: b"/rules/dhcp-keywords.html#dhcp-leasetime\0".as_ptr() as *const libc::c_char, + AppLayerTxMatch: Some(dhcp_detect_leasetime_match), + Setup: dhcp_detect_leasetime_setup, + Free: Some(dhcp_detect_time_free), + flags: 0, + }; + unsafe { + G_DHCP_LEASE_TIME_KW_ID = DetectHelperKeywordRegister(&kw); + G_DHCP_LEASE_TIME_BUFFER_ID = DetectHelperBufferRegister( + b"dhcp.leasetime\0".as_ptr() as *const libc::c_char, + ALPROTO_DHCP, + true, + true, + ); + } + let kw = SCSigTableElmt { + name: b"dhcp.rebinding_time\0".as_ptr() as *const libc::c_char, + desc: b"match DHCP rebinding time\0".as_ptr() as *const libc::c_char, + url: b"/rules/dhcp-keywords.html#dhcp-rebinding-time\0".as_ptr() as *const libc::c_char, + AppLayerTxMatch: Some(dhcp_detect_rebindingtime_match), + Setup: dhcp_detect_rebindingtime_setup, + Free: Some(dhcp_detect_time_free), + flags: 0, + }; + unsafe { + G_DHCP_REBINDING_TIME_KW_ID = DetectHelperKeywordRegister(&kw); + G_DHCP_REBINDING_TIME_BUFFER_ID = DetectHelperBufferRegister( + b"dhcp.rebinding-time\0".as_ptr() as *const libc::c_char, + ALPROTO_DHCP, + true, + true, + ); + } + let kw = SCSigTableElmt { + name: b"dhcp.renewal_time\0".as_ptr() as *const libc::c_char, + desc: b"match DHCP renewal time\0".as_ptr() as *const libc::c_char, + url: b"/rules/dhcp-keywords.html#dhcp-renewal-time\0".as_ptr() as *const libc::c_char, + AppLayerTxMatch: Some(dhcp_detect_renewaltime_match), + Setup: dhcp_detect_renewaltime_setup, + Free: Some(dhcp_detect_time_free), + flags: 0, + }; + unsafe { + G_DHCP_RENEWAL_TIME_KW_ID = DetectHelperKeywordRegister(&kw); + G_DHCP_RENEWAL_TIME_BUFFER_ID = DetectHelperBufferRegister( + b"dhcp.renewal-time\0".as_ptr() as *const libc::c_char, + ALPROTO_DHCP, + true, + true, + ); + } +} diff --git a/rust/src/dhcp/dhcp.rs b/rust/src/dhcp/dhcp.rs index b69b675b8ce9..ec9a3cc06bda 100644 --- a/rust/src/dhcp/dhcp.rs +++ b/rust/src/dhcp/dhcp.rs @@ -22,7 +22,7 @@ use crate::dhcp::parser::*; use std; use std::ffi::CString; -static mut ALPROTO_DHCP: AppProto = ALPROTO_UNKNOWN; +pub(super) static mut ALPROTO_DHCP: AppProto = ALPROTO_UNKNOWN; static DHCP_MIN_FRAME_LEN: u32 = 232; diff --git a/rust/src/snmp/detect.rs b/rust/src/snmp/detect.rs index bb4ffd12c3ba..7dee00a707b1 100644 --- a/rust/src/snmp/detect.rs +++ b/rust/src/snmp/detect.rs @@ -17,42 +17,251 @@ // written by Pierre Chifflier -use crate::snmp::snmp::SNMPTransaction; +use super::snmp::{SNMPTransaction, ALPROTO_SNMP}; +use crate::detect::uint::{ + rs_detect_u32_free, rs_detect_u32_match, rs_detect_u32_parse, DetectUintData, +}; +use crate::detect::{ + DetectBufferSetActiveList, DetectHelperBufferMpmRegister, DetectHelperBufferRegister, + DetectHelperGetData, DetectHelperKeywordRegister, DetectSignatureSetAppProto, SCSigTableElmt, + SigMatchAppendSMToList, SIGMATCH_INFO_STICKY_BUFFER, SIGMATCH_NOOPT, +}; +use std::os::raw::{c_int, c_void}; -#[no_mangle] -pub unsafe extern "C" fn rs_snmp_tx_get_version(tx: &mut SNMPTransaction, version: *mut u32) { - debug_assert!(tx.version != 0, "SNMP version is 0"); - *version = tx.version; +static mut G_SNMP_VERSION_KW_ID: c_int = 0; +static mut G_SNMP_VERSION_BUFFER_ID: c_int = 0; +static mut G_SNMP_PDUTYPE_KW_ID: c_int = 0; +static mut G_SNMP_PDUTYPE_BUFFER_ID: c_int = 0; +static mut G_SNMP_USM_BUFFER_ID: c_int = 0; +static mut G_SNMP_COMMUNITY_BUFFER_ID: c_int = 0; + +unsafe extern "C" fn snmp_detect_version_setup( + de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0 { + return -1; + } + let ctx = rs_detect_u32_parse(raw) as *mut c_void; + if ctx.is_null() { + return -1; + } + if SigMatchAppendSMToList(de, s, G_SNMP_VERSION_KW_ID, ctx, G_SNMP_VERSION_BUFFER_ID).is_null() + { + snmp_detect_version_free(std::ptr::null_mut(), ctx); + return -1; + } + return 0; } -#[no_mangle] -pub unsafe extern "C" fn rs_snmp_tx_get_community( - tx: &mut SNMPTransaction, buf: *mut *const u8, len: *mut u32, -) { - if let Some(ref c) = tx.community { - *buf = c.as_ptr(); - *len = c.len() as u32; +unsafe extern "C" fn snmp_detect_version_match( + _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void, + _sig: *const c_void, ctx: *const c_void, +) -> c_int { + let tx = cast_pointer!(tx, SNMPTransaction); + let ctx = cast_pointer!(ctx, DetectUintData); + return rs_detect_u32_match(tx.version, ctx); +} + +unsafe extern "C" fn snmp_detect_version_free(_de: *mut c_void, ctx: *mut c_void) { + // Just unbox... + let ctx = cast_pointer!(ctx, DetectUintData); + rs_detect_u32_free(ctx); +} + +unsafe extern "C" fn snmp_detect_pdutype_setup( + de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0 { + return -1; } + let ctx = rs_detect_u32_parse(raw) as *mut c_void; + if ctx.is_null() { + return -1; + } + if SigMatchAppendSMToList(de, s, G_SNMP_PDUTYPE_KW_ID, ctx, G_SNMP_PDUTYPE_BUFFER_ID).is_null() + { + snmp_detect_pdutype_free(std::ptr::null_mut(), ctx); + return -1; + } + return 0; } -#[no_mangle] -pub unsafe extern "C" fn rs_snmp_tx_get_pdu_type(tx: &mut SNMPTransaction, pdu_type: *mut u32) { - match tx.info { - Some(ref info) => { - *pdu_type = info.pdu_type.0; - } - None => { - *pdu_type = 0xffffffff; - } +unsafe extern "C" fn snmp_detect_pdutype_match( + _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void, + _sig: *const c_void, ctx: *const c_void, +) -> c_int { + let tx = cast_pointer!(tx, SNMPTransaction); + let ctx = cast_pointer!(ctx, DetectUintData); + if let Some(ref info) = tx.info { + let pdu_type = info.pdu_type.0; + return rs_detect_u32_match(pdu_type, ctx); + } + return 0; +} + +unsafe extern "C" fn snmp_detect_pdutype_free(_de: *mut c_void, ctx: *mut c_void) { + // Just unbox... + let ctx = cast_pointer!(ctx, DetectUintData); + rs_detect_u32_free(ctx); +} + +pub unsafe extern "C" fn snmp_detect_usm_setup( + de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0 { + return -1; + } + if DetectBufferSetActiveList(de, s, G_SNMP_USM_BUFFER_ID) < 0 { + return -1; } + return 0; } +pub unsafe extern "C" fn snmp_detect_usm_get( + tx: *const c_void, _flow_flags: u8, buffer: *mut *const u8, buffer_len: *mut u32, +) -> bool { + let tx = cast_pointer!(tx, SNMPTransaction); + if let Some(ref c) = tx.usm { + *buffer = c.as_ptr(); + *buffer_len = c.len() as u32; + return true; + } + return false; +} + +pub unsafe extern "C" fn snmp_detect_usm_get_data( + 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, + snmp_detect_usm_get, + ); +} + +pub unsafe extern "C" fn snmp_detect_community_setup( + de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0 { + return -1; + } + if DetectBufferSetActiveList(de, s, G_SNMP_COMMUNITY_BUFFER_ID) < 0 { + return -1; + } + return 0; +} + +pub unsafe extern "C" fn snmp_detect_community_get( + tx: *const c_void, _flow_flags: u8, buffer: *mut *const u8, buffer_len: *mut u32, +) -> bool { + let tx = cast_pointer!(tx, SNMPTransaction); + if let Some(ref c) = tx.community { + *buffer = c.as_ptr(); + *buffer_len = c.len() as u32; + return true; + } + return false; +} + +pub unsafe extern "C" fn snmp_detect_community_get_data( + 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, + snmp_detect_community_get, + ); +} #[no_mangle] -pub unsafe extern "C" fn rs_snmp_tx_get_usm( - tx: &mut SNMPTransaction, buf: *mut *const u8, len: *mut u32, -) { - if let Some(ref c) = tx.usm { - *buf = c.as_ptr(); - *len = c.len() as u32; +pub unsafe extern "C" fn ScDetectSNMPRegister() { + let kw = SCSigTableElmt { + name: b"snmp.version\0".as_ptr() as *const libc::c_char, + desc: b"match SNMP version\0".as_ptr() as *const libc::c_char, + url: b"/rules/snmp-keywords.html#snmp-version\0".as_ptr() as *const libc::c_char, + AppLayerTxMatch: Some(snmp_detect_version_match), + Setup: snmp_detect_version_setup, + Free: Some(snmp_detect_version_free), + flags: 0, + }; + unsafe { + G_SNMP_VERSION_KW_ID = DetectHelperKeywordRegister(&kw); + G_SNMP_VERSION_BUFFER_ID = DetectHelperBufferRegister( + b"snmp.version\0".as_ptr() as *const libc::c_char, + ALPROTO_SNMP, + true, + true, + ); + } + + let kw = SCSigTableElmt { + name: b"snmp.pdu_type\0".as_ptr() as *const libc::c_char, + desc: b"match SNMP PDU type\0".as_ptr() as *const libc::c_char, + url: b"/rules/snmp-keywords.html#snmp-pdu-type\0".as_ptr() as *const libc::c_char, + AppLayerTxMatch: Some(snmp_detect_pdutype_match), + Setup: snmp_detect_pdutype_setup, + Free: Some(snmp_detect_pdutype_free), + flags: 0, + }; + unsafe { + G_SNMP_PDUTYPE_KW_ID = DetectHelperKeywordRegister(&kw); + G_SNMP_PDUTYPE_BUFFER_ID = DetectHelperBufferRegister( + b"snmp.pdu_type\0".as_ptr() as *const libc::c_char, + ALPROTO_SNMP, + true, + true, + ); + } + + let kw = SCSigTableElmt { + name: b"snmp.usm\0".as_ptr() as *const libc::c_char, + desc: b"SNMP content modifier to match on the SNMP usm\0".as_ptr() as *const libc::c_char, + url: b"/rules/snmp-keywords.html#snmp-usm\0".as_ptr() as *const libc::c_char, + Setup: snmp_detect_usm_setup, + flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER, + AppLayerTxMatch: None, + Free: None, + }; + unsafe { + let _g_snmp_usm_kw_id = DetectHelperKeywordRegister(&kw); + G_SNMP_USM_BUFFER_ID = DetectHelperBufferMpmRegister( + b"snmp.usm\0".as_ptr() as *const libc::c_char, + b"SNMP USM\0".as_ptr() as *const libc::c_char, + ALPROTO_SNMP, + true, + true, + snmp_detect_usm_get_data, + ); + } + + let kw = SCSigTableElmt { + name: b"snmp.community\0".as_ptr() as *const libc::c_char, + desc: b"SNMP content modifier to match on the SNMP community\0".as_ptr() + as *const libc::c_char, + url: b"/rules/snmp-keywords.html#snmp-community\0".as_ptr() as *const libc::c_char, + Setup: snmp_detect_community_setup, + flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER, + AppLayerTxMatch: None, + Free: None, + }; + unsafe { + let _g_snmp_community_kw_id = DetectHelperKeywordRegister(&kw); + G_SNMP_COMMUNITY_BUFFER_ID = DetectHelperBufferMpmRegister( + b"snmp.community\0".as_ptr() as *const libc::c_char, + b"SNMP Community identifier\0".as_ptr() as *const libc::c_char, + ALPROTO_SNMP, + true, + true, + snmp_detect_community_get_data, + ); } } diff --git a/rust/src/snmp/snmp.rs b/rust/src/snmp/snmp.rs index 3b78b47f7a1d..51aed9fb883f 100644 --- a/rust/src/snmp/snmp.rs +++ b/rust/src/snmp/snmp.rs @@ -322,7 +322,7 @@ pub extern "C" fn rs_snmp_tx_get_alstate_progress(_tx: *mut std::os::raw::c_void 1 } -static mut ALPROTO_SNMP : AppProto = ALPROTO_UNKNOWN; +pub(super) static mut ALPROTO_SNMP : AppProto = ALPROTO_UNKNOWN; // Read PDU sequence and extract version, if similar to SNMP definition fn parse_pdu_envelope_version(i:&[u8]) -> IResult<&[u8],u32> { diff --git a/rust/src/websocket/detect.rs b/rust/src/websocket/detect.rs index 44737ae6f03d..b4457125a633 100644 --- a/rust/src/websocket/detect.rs +++ b/rust/src/websocket/detect.rs @@ -15,9 +15,15 @@ * 02110-1301, USA. */ -use super::websocket::WebSocketTransaction; +use super::websocket::{WebSocketTransaction, ALPROTO_WEBSOCKET}; use crate::detect::uint::{ - detect_parse_uint, detect_parse_uint_enum, DetectUintData, DetectUintMode, + detect_parse_uint, detect_parse_uint_enum, rs_detect_u32_free, rs_detect_u32_match, + rs_detect_u32_parse, rs_detect_u8_free, rs_detect_u8_match, DetectUintData, DetectUintMode, +}; +use crate::detect::{ + DetectBufferSetActiveList, DetectHelperBufferMpmRegister, DetectHelperBufferRegister, + DetectHelperGetData, DetectHelperKeywordRegister, DetectSignatureSetAppProto, SCSigTableElmt, + SigMatchAppendSMToList, SIGMATCH_INFO_STICKY_BUFFER, SIGMATCH_NOOPT, }; use crate::websocket::parser::WebSocketOpcode; @@ -28,39 +34,9 @@ use nom7::multi::many1; use nom7::IResult; use std::ffi::CStr; +use std::os::raw::{c_int, c_void}; -#[no_mangle] -pub unsafe extern "C" fn SCWebSocketGetOpcode(tx: &mut WebSocketTransaction) -> u8 { - return tx.pdu.opcode; -} - -#[no_mangle] -pub unsafe extern "C" fn SCWebSocketGetFlags(tx: &mut WebSocketTransaction) -> u8 { - return tx.pdu.flags; -} - -#[no_mangle] -pub unsafe extern "C" fn SCWebSocketGetPayload( - tx: &WebSocketTransaction, buffer: *mut *const u8, buffer_len: *mut u32, -) -> bool { - *buffer = tx.pdu.payload.as_ptr(); - *buffer_len = tx.pdu.payload.len() as u32; - return true; -} - -#[no_mangle] -pub unsafe extern "C" fn SCWebSocketGetMask( - tx: &mut WebSocketTransaction, value: *mut u32, -) -> bool { - if let Some(xorkey) = tx.pdu.mask { - *value = xorkey; - return true; - } - return false; -} - -#[no_mangle] -pub unsafe extern "C" fn SCWebSocketParseOpcode( +unsafe extern "C" fn websocket_parse_opcode( ustr: *const std::os::raw::c_char, ) -> *mut DetectUintData { let ft_name: &CStr = CStr::from_ptr(ustr); //unsafe @@ -120,8 +96,7 @@ fn parse_flags(s: &str) -> Option> { return None; } -#[no_mangle] -pub unsafe extern "C" fn SCWebSocketParseFlags( +unsafe extern "C" fn websocket_parse_flags( ustr: *const std::os::raw::c_char, ) -> *mut DetectUintData { let ft_name: &CStr = CStr::from_ptr(ustr); //unsafe @@ -133,3 +108,248 @@ pub unsafe extern "C" fn SCWebSocketParseFlags( } return std::ptr::null_mut(); } + +static mut G_WEBSOCKET_OPCODE_KW_ID: c_int = 0; +static mut G_WEBSOCKET_OPCODE_BUFFER_ID: c_int = 0; +static mut G_WEBSOCKET_MASK_KW_ID: c_int = 0; +static mut G_WEBSOCKET_MASK_BUFFER_ID: c_int = 0; +static mut G_WEBSOCKET_FLAGS_KW_ID: c_int = 0; +static mut G_WEBSOCKET_FLAGS_BUFFER_ID: c_int = 0; +static mut G_WEBSOCKET_PAYLOAD_BUFFER_ID: c_int = 0; + +unsafe extern "C" fn websocket_detect_opcode_setup( + de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_WEBSOCKET) != 0 { + return -1; + } + let ctx = websocket_parse_opcode(raw) as *mut c_void; + if ctx.is_null() { + return -1; + } + if SigMatchAppendSMToList( + de, + s, + G_WEBSOCKET_OPCODE_KW_ID, + ctx, + G_WEBSOCKET_OPCODE_BUFFER_ID, + ) + .is_null() + { + websocket_detect_opcode_free(std::ptr::null_mut(), ctx); + return -1; + } + return 0; +} + +unsafe extern "C" fn websocket_detect_opcode_match( + _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void, + _sig: *const c_void, ctx: *const c_void, +) -> c_int { + let tx = cast_pointer!(tx, WebSocketTransaction); + let ctx = cast_pointer!(ctx, DetectUintData); + return rs_detect_u8_match(tx.pdu.opcode, ctx); +} + +unsafe extern "C" fn websocket_detect_opcode_free(_de: *mut c_void, ctx: *mut c_void) { + // Just unbox... + let ctx = cast_pointer!(ctx, DetectUintData); + rs_detect_u8_free(ctx); +} + +unsafe extern "C" fn websocket_detect_mask_setup( + de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_WEBSOCKET) != 0 { + return -1; + } + let ctx = rs_detect_u32_parse(raw) as *mut c_void; + if ctx.is_null() { + return -1; + } + if SigMatchAppendSMToList( + de, + s, + G_WEBSOCKET_MASK_KW_ID, + ctx, + G_WEBSOCKET_MASK_BUFFER_ID, + ) + .is_null() + { + websocket_detect_mask_free(std::ptr::null_mut(), ctx); + return -1; + } + return 0; +} + +unsafe extern "C" fn websocket_detect_mask_match( + _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void, + _sig: *const c_void, ctx: *const c_void, +) -> c_int { + let tx = cast_pointer!(tx, WebSocketTransaction); + let ctx = cast_pointer!(ctx, DetectUintData); + if let Some(xorkey) = tx.pdu.mask { + return rs_detect_u32_match(xorkey, ctx); + } + return 0; +} + +unsafe extern "C" fn websocket_detect_mask_free(_de: *mut c_void, ctx: *mut c_void) { + // Just unbox... + let ctx = cast_pointer!(ctx, DetectUintData); + rs_detect_u32_free(ctx); +} + +unsafe extern "C" fn websocket_detect_flags_setup( + de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_WEBSOCKET) != 0 { + return -1; + } + let ctx = websocket_parse_flags(raw) as *mut c_void; + if ctx.is_null() { + return -1; + } + if SigMatchAppendSMToList( + de, + s, + G_WEBSOCKET_FLAGS_KW_ID, + ctx, + G_WEBSOCKET_FLAGS_BUFFER_ID, + ) + .is_null() + { + websocket_detect_flags_free(std::ptr::null_mut(), ctx); + return -1; + } + return 0; +} + +unsafe extern "C" fn websocket_detect_flags_match( + _de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void, + _sig: *const c_void, ctx: *const c_void, +) -> c_int { + let tx = cast_pointer!(tx, WebSocketTransaction); + let ctx = cast_pointer!(ctx, DetectUintData); + return rs_detect_u8_match(tx.pdu.flags, ctx); +} + +unsafe extern "C" fn websocket_detect_flags_free(_de: *mut c_void, ctx: *mut c_void) { + // Just unbox... + let ctx = cast_pointer!(ctx, DetectUintData); + rs_detect_u8_free(ctx); +} + +pub unsafe extern "C" fn websocket_detect_payload_setup( + de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_WEBSOCKET) != 0 { + return -1; + } + if DetectBufferSetActiveList(de, s, G_WEBSOCKET_PAYLOAD_BUFFER_ID) < 0 { + return -1; + } + return 0; +} + +pub unsafe extern "C" fn websocket_detect_payload_get( + tx: *const c_void, _flow_flags: u8, buffer: *mut *const u8, buffer_len: *mut u32, +) -> bool { + let tx = cast_pointer!(tx, WebSocketTransaction); + *buffer = tx.pdu.payload.as_ptr(); + *buffer_len = tx.pdu.payload.len() as u32; + return true; +} + +pub unsafe extern "C" fn websocket_detect_payload_get_data( + 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, + websocket_detect_payload_get, + ); +} + +#[no_mangle] +pub unsafe extern "C" fn ScDetectWebsocketRegister() { + let kw = SCSigTableElmt { + name: b"websocket.opcode\0".as_ptr() as *const libc::c_char, + desc: b"match WebSocket opcode\0".as_ptr() as *const libc::c_char, + url: b"/rules/websocket-keywords.html#websocket-opcode\0".as_ptr() as *const libc::c_char, + AppLayerTxMatch: Some(websocket_detect_opcode_match), + Setup: websocket_detect_opcode_setup, + Free: Some(websocket_detect_opcode_free), + flags: 0, + }; + unsafe { + G_WEBSOCKET_OPCODE_KW_ID = DetectHelperKeywordRegister(&kw); + G_WEBSOCKET_OPCODE_BUFFER_ID = DetectHelperBufferRegister( + b"websocket.opcode\0".as_ptr() as *const libc::c_char, + ALPROTO_WEBSOCKET, + true, + true, + ); + } + let kw = SCSigTableElmt { + name: b"websocket.mask\0".as_ptr() as *const libc::c_char, + desc: b"match WebSocket mask\0".as_ptr() as *const libc::c_char, + url: b"/rules/websocket-keywords.html#websocket-mask\0".as_ptr() as *const libc::c_char, + AppLayerTxMatch: Some(websocket_detect_mask_match), + Setup: websocket_detect_mask_setup, + Free: Some(websocket_detect_mask_free), + flags: 0, + }; + unsafe { + G_WEBSOCKET_MASK_KW_ID = DetectHelperKeywordRegister(&kw); + G_WEBSOCKET_MASK_BUFFER_ID = DetectHelperBufferRegister( + b"websocket.mask\0".as_ptr() as *const libc::c_char, + ALPROTO_WEBSOCKET, + true, + true, + ); + } + let kw = SCSigTableElmt { + name: b"websocket.flags\0".as_ptr() as *const libc::c_char, + desc: b"match WebSocket flags\0".as_ptr() as *const libc::c_char, + url: b"/rules/websocket-keywords.html#websocket-flags\0".as_ptr() as *const libc::c_char, + AppLayerTxMatch: Some(websocket_detect_flags_match), + Setup: websocket_detect_flags_setup, + Free: Some(websocket_detect_flags_free), + flags: 0, + }; + unsafe { + G_WEBSOCKET_FLAGS_KW_ID = DetectHelperKeywordRegister(&kw); + G_WEBSOCKET_FLAGS_BUFFER_ID = DetectHelperBufferRegister( + b"websocket.flags\0".as_ptr() as *const libc::c_char, + ALPROTO_WEBSOCKET, + true, + true, + ); + } + let kw = SCSigTableElmt { + name: b"websocket.payload\0".as_ptr() as *const libc::c_char, + desc: b"match WebSocket payload\0".as_ptr() as *const libc::c_char, + url: b"/rules/websocket-keywords.html#websocket-payload\0".as_ptr() as *const libc::c_char, + Setup: websocket_detect_payload_setup, + flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER, + AppLayerTxMatch: None, + Free: None, + }; + unsafe { + let _g_ws_payload_kw_id = DetectHelperKeywordRegister(&kw); + G_WEBSOCKET_PAYLOAD_BUFFER_ID = DetectHelperBufferMpmRegister( + b"websocket.payload\0".as_ptr() as *const libc::c_char, + b"WebSocket payload\0".as_ptr() as *const libc::c_char, + ALPROTO_WEBSOCKET, + true, + true, + websocket_detect_payload_get_data, + ); + } +} diff --git a/rust/src/websocket/websocket.rs b/rust/src/websocket/websocket.rs index 4e94ea79b429..f4dad3f90691 100644 --- a/rust/src/websocket/websocket.rs +++ b/rust/src/websocket/websocket.rs @@ -32,7 +32,7 @@ use std::ffi::CString; use std::io::Read; use std::os::raw::{c_char, c_int, c_void}; -static mut ALPROTO_WEBSOCKET: AppProto = ALPROTO_UNKNOWN; +pub(super) static mut ALPROTO_WEBSOCKET: AppProto = ALPROTO_UNKNOWN; static mut WEBSOCKET_MAX_PAYLOAD_SIZE: u32 = 0xFFFF; diff --git a/src/Makefile.am b/src/Makefile.am index ee334a4063d6..154da8c510bc 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -133,6 +133,7 @@ noinst_HEADERS = \ detect-engine-file.h \ detect-engine-frame.h \ detect-engine.h \ + detect-engine-helper.h \ detect-engine-iponly.h \ detect-engine-loader.h \ detect-engine-mpm.h \ @@ -293,13 +294,6 @@ noinst_HEADERS = \ detect-smb-ntlmssp.h \ detect-smb-share.h \ detect-smb-version.h \ - detect-snmp-community.h \ - detect-snmp-pdu_type.h \ - detect-snmp-usm.h \ - detect-snmp-version.h \ - detect-dhcp-leasetime.h \ - detect-dhcp-rebinding-time.h \ - detect-dhcp-renewal-time.h \ detect-ssh-hassh.h \ detect-ssh-hassh-server.h \ detect-ssh-hassh-server-string.h \ @@ -356,7 +350,6 @@ noinst_HEADERS = \ detect-urilen.h \ detect-within.h \ detect-xbits.h \ - detect-websocket.h \ device-storage.h \ feature.h \ flow-bit.h \ @@ -743,6 +736,7 @@ libsuricata_c_a_SOURCES = \ detect-engine-event.c \ detect-engine-file.c \ detect-engine-frame.c \ + detect-engine-helper.c \ detect-engine-iponly.c \ detect-engine-loader.c \ detect-engine-mpm.c \ @@ -901,13 +895,6 @@ libsuricata_c_a_SOURCES = \ detect-smb-ntlmssp.c \ detect-smb-share.c \ detect-smb-version.c \ - detect-snmp-community.c \ - detect-snmp-pdu_type.c \ - detect-snmp-usm.c \ - detect-snmp-version.c \ - detect-dhcp-leasetime.c \ - detect-dhcp-rebinding-time.c \ - detect-dhcp-renewal-time.c \ detect-ssh-hassh.c \ detect-ssh-hassh-server.c \ detect-ssh-hassh-server-string.c \ @@ -964,7 +951,6 @@ libsuricata_c_a_SOURCES = \ detect-urilen.c \ detect-within.c \ detect-xbits.c \ - detect-websocket.c \ device-storage.c \ feature.c \ flow-bit.c \ @@ -1227,8 +1213,6 @@ EXTRA_DIST = \ tests/detect-http2.c \ tests/detect-icmpv6-mtu.c \ tests/detect-icmpv6hdr.c \ - tests/detect-snmp-pdu_type.c \ - tests/detect-snmp-version.c \ tests/detect-template.c \ tests/detect-transform-pcrexform.c \ tests/detect-transform-xor.c \ @@ -1286,7 +1270,13 @@ suricata_SOURCES = main.c # the library search path. suricata_LDFLAGS = $(all_libraries) ${SECLDFLAGS} -suricata_LDADD = libsuricata_c.a $(RUST_SURICATA_LIB) $(HTP_LDADD) $(RUST_LDADD) +# rust library depends also on c +if LINKER_SUPPORTS_GROUP +LDADD_GENERIC = "-Wl,--start-group,libsuricata_c.a,$(RUST_SURICATA_LIB),--end-group" $(HTP_LDADD) $(RUST_LDADD) +else +LDADD_GENERIC = libsuricata_c.a $(RUST_SURICATA_LIB) libsuricata_c.a $(RUST_SURICATA_LIB) $(HTP_LDADD) $(RUST_LDADD) +endif +suricata_LDADD = $(LDADD_GENERIC) suricata_DEPENDENCIES = libsuricata_c.a $(RUST_SURICATA_LIB) if BUILD_SHARED_LIBRARY @@ -1322,11 +1312,12 @@ uninstall-local: if BUILD_FUZZTARGETS LDFLAGS_FUZZ = $(all_libraries) $(SECLDFLAGS) -LDADD_FUZZ = libsuricata_c.a $(RUST_SURICATA_LIB) $(HTP_LDADD) $(RUST_LDADD) +LDADD_FUZZ = $(LDADD_GENERIC) fuzz_applayerprotodetectgetproto_SOURCES = tests/fuzz/fuzz_applayerprotodetectgetproto.c fuzz_applayerprotodetectgetproto_LDFLAGS = $(LDFLAGS_FUZZ) fuzz_applayerprotodetectgetproto_LDADD = $(LDADD_FUZZ) +fuzz_applayerprotodetectgetproto_DEPENDENCIES = libsuricata_c.a $(RUST_SURICATA_LIB) if HAS_FUZZLDFLAGS fuzz_applayerprotodetectgetproto_LDFLAGS += $(LIB_FUZZING_ENGINE) else @@ -1338,6 +1329,7 @@ nodist_EXTRA_fuzz_applayerprotodetectgetproto_SOURCES = force-cxx-linking.cxx fuzz_applayerparserparse_SOURCES = tests/fuzz/fuzz_applayerparserparse.c fuzz_applayerparserparse_LDFLAGS = $(LDFLAGS_FUZZ) fuzz_applayerparserparse_LDADD = $(LDADD_FUZZ) +fuzz_applayerparserparse_DEPENDENCIES = libsuricata_c.a $(RUST_SURICATA_LIB) if HAS_FUZZLDFLAGS fuzz_applayerparserparse_LDFLAGS += $(LIB_FUZZING_ENGINE) else @@ -1349,6 +1341,7 @@ nodist_EXTRA_fuzz_applayerparserparse_SOURCES = force-cxx-linking.cxx fuzz_siginit_SOURCES = tests/fuzz/fuzz_siginit.c fuzz_siginit_LDFLAGS = $(LDFLAGS_FUZZ) fuzz_siginit_LDADD = $(LDADD_FUZZ) +fuzz_siginit_DEPENDENCIES = libsuricata_c.a $(RUST_SURICATA_LIB) if HAS_FUZZLDFLAGS fuzz_siginit_LDFLAGS += $(LIB_FUZZING_ENGINE) else @@ -1360,6 +1353,7 @@ nodist_EXTRA_fuzz_siginit_SOURCES = force-cxx-linking.cxx fuzz_confyamlloadstring_SOURCES = tests/fuzz/fuzz_confyamlloadstring.c fuzz_confyamlloadstring_LDFLAGS = $(LDFLAGS_FUZZ) fuzz_confyamlloadstring_LDADD = $(LDADD_FUZZ) +fuzz_confyamlloadstring_DEPENDENCIES = libsuricata_c.a $(RUST_SURICATA_LIB) if HAS_FUZZLDFLAGS fuzz_confyamlloadstring_LDFLAGS += $(LIB_FUZZING_ENGINE) else @@ -1371,6 +1365,7 @@ nodist_EXTRA_fuzz_confyamlloadstring_SOURCES = force-cxx-linking.cxx fuzz_decodepcapfile_SOURCES = tests/fuzz/fuzz_decodepcapfile.c fuzz_decodepcapfile_LDFLAGS = $(LDFLAGS_FUZZ) fuzz_decodepcapfile_LDADD = $(LDADD_FUZZ) +fuzz_decodepcapfile_DEPENDENCIES = libsuricata_c.a $(RUST_SURICATA_LIB) if HAS_FUZZLDFLAGS fuzz_decodepcapfile_LDFLAGS += $(LIB_FUZZING_ENGINE) else @@ -1382,6 +1377,7 @@ nodist_EXTRA_fuzz_decodepcapfile_SOURCES = force-cxx-linking.cxx fuzz_sigpcap_SOURCES = tests/fuzz/fuzz_sigpcap.c fuzz_sigpcap_LDFLAGS = $(LDFLAGS_FUZZ) fuzz_sigpcap_LDADD = $(LDADD_FUZZ) +fuzz_sigpcap_DEPENDENCIES = libsuricata_c.a $(RUST_SURICATA_LIB) if HAS_FUZZLDFLAGS fuzz_sigpcap_LDFLAGS += $(LIB_FUZZING_ENGINE) else @@ -1394,6 +1390,7 @@ if HAS_FUZZPCAP fuzz_sigpcap_aware_SOURCES = tests/fuzz/fuzz_sigpcap_aware.c fuzz_sigpcap_aware_LDFLAGS = $(LDFLAGS_FUZZ) fuzz_sigpcap_aware_LDADD = $(LDADD_FUZZ) -lfuzzpcap +fuzz_sigpcap_aware_DEPENDENCIES = libsuricata_c.a $(RUST_SURICATA_LIB) if HAS_FUZZLDFLAGS fuzz_sigpcap_aware_LDFLAGS += $(LIB_FUZZING_ENGINE) else @@ -1405,6 +1402,7 @@ nodist_EXTRA_fuzz_sigpcap_aware_SOURCES = force-cxx-linking.cxx fuzz_predefpcap_aware_SOURCES = tests/fuzz/fuzz_predefpcap_aware.c fuzz_predefpcap_aware_LDFLAGS = $(LDFLAGS_FUZZ) fuzz_predefpcap_aware_LDADD = $(LDADD_FUZZ) -lfuzzpcap +fuzz_predefpcap_aware_DEPENDENCIES = libsuricata_c.a $(RUST_SURICATA_LIB) if HAS_FUZZLDFLAGS fuzz_predefpcap_aware_LDFLAGS += $(LIB_FUZZING_ENGINE) else @@ -1417,6 +1415,7 @@ endif fuzz_mimedecparseline_SOURCES = tests/fuzz/fuzz_mimedecparseline.c fuzz_mimedecparseline_LDFLAGS = $(LDFLAGS_FUZZ) fuzz_mimedecparseline_LDADD = $(LDADD_FUZZ) +fuzz_mimedecparseline_DEPENDENCIES = libsuricata_c.a $(RUST_SURICATA_LIB) if HAS_FUZZLDFLAGS fuzz_mimedecparseline_LDFLAGS += $(LIB_FUZZING_ENGINE) else diff --git a/src/app-layer-detect-proto.c b/src/app-layer-detect-proto.c index c47a437659fd..c5df63b0885a 100644 --- a/src/app-layer-detect-proto.c +++ b/src/app-layer-detect-proto.c @@ -1431,7 +1431,7 @@ AppProto AppLayerProtoDetectGetProto(AppLayerProtoDetectThreadCtx *tctx, Flow *f } } - if (!FLOW_IS_PP_DONE(f, flags)) { + if (!FLOW_IS_PP_DONE(f, flags) && buf != NULL) { bool rflow = false; alproto = AppLayerProtoDetectPPGetProto(f, buf, buflen, ipproto, flags, &rflow); if (AppProtoIsValid(alproto)) { diff --git a/src/detect-dhcp-leasetime.c b/src/detect-dhcp-leasetime.c deleted file mode 100644 index f86d645dc633..000000000000 --- a/src/detect-dhcp-leasetime.c +++ /dev/null @@ -1,127 +0,0 @@ -/* Copyright (C) 2022 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. - */ - -#include "suricata-common.h" -#include "rust.h" -#include "detect-dhcp-leasetime.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-prefilter.h" -#include "detect-engine-uint.h" -#include "detect-parse.h" - -static int g_buffer_id = 0; - -/** - * \internal - * \brief Function to match leasetime of a TX - * - * \param t Pointer to thread vars. - * \param det_ctx Pointer to the pattern matcher thread. - * \param f Pointer to the current flow. - * \param flags Flags. - * \param state App layer state. - * \param s Pointer to the Signature. - * \param m Pointer to the sigmatch that we will cast into - * DetectU64Data. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DetectDHCPLeaseTimeMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, - void *state, void *txv, const Signature *s, const SigMatchCtx *ctx) -{ - SCEnter(); - - uint64_t leasetime; - if (rs_dhcp_tx_get_leasetime(txv, &leasetime)) { - const DetectU64Data *dd = (const DetectU64Data *)ctx; - if (DetectU64Match(leasetime, dd)) { - SCReturnInt(1); - } - } - SCReturnInt(0); -} - -/** - * \internal - * \brief Function to free memory associated with DetectU64Data. - * - * \param de_ptr Pointer to DetectU64Data. - */ -static void DetectDHCPLeaseTimeFree(DetectEngineCtx *de_ctx, void *ptr) -{ - rs_detect_u64_free(ptr); -} - -/** - * \brief Function to add the parsed dhcp leasetime field into the current signature. - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param s Pointer to the Current Signature. - * \param rawstr Pointer to the user provided flags options. - * \param type Defines if this is notBefore or notAfter. - * - * \retval 0 on Success. - * \retval -1 on Failure. - */ -static int DetectDHCPLeaseTimeSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr) -{ - if (DetectSignatureSetAppProto(s, ALPROTO_DHCP) != 0) - return -1; - - DetectU64Data *dd = DetectU64Parse(rawstr); - if (dd == NULL) { - SCLogError("Parsing \'%s\' failed for %s", rawstr, - sigmatch_table[DETECT_AL_DHCP_LEASETIME].name); - return -1; - } - - /* okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - - if (SigMatchAppendSMToList( - de_ctx, s, DETECT_AL_DHCP_LEASETIME, (SigMatchCtx *)dd, g_buffer_id) == NULL) { - goto error; - } - return 0; - -error: - DetectDHCPLeaseTimeFree(de_ctx, dd); - return -1; -} - -/** - * \brief Registration function for dhcp.procedure keyword. - */ -void DetectDHCPLeaseTimeRegister(void) -{ - sigmatch_table[DETECT_AL_DHCP_LEASETIME].name = "dhcp.leasetime"; - sigmatch_table[DETECT_AL_DHCP_LEASETIME].desc = "match DHCP leasetime"; - sigmatch_table[DETECT_AL_DHCP_LEASETIME].url = "/rules/dhcp-keywords.html#dhcp-leasetime"; - sigmatch_table[DETECT_AL_DHCP_LEASETIME].AppLayerTxMatch = DetectDHCPLeaseTimeMatch; - sigmatch_table[DETECT_AL_DHCP_LEASETIME].Setup = DetectDHCPLeaseTimeSetup; - sigmatch_table[DETECT_AL_DHCP_LEASETIME].Free = DetectDHCPLeaseTimeFree; - - DetectAppLayerInspectEngineRegister("dhcp.leasetime", ALPROTO_DHCP, SIG_FLAG_TOSERVER, 0, - DetectEngineInspectGenericList, NULL); - - DetectAppLayerInspectEngineRegister("dhcp.leasetime", ALPROTO_DHCP, SIG_FLAG_TOCLIENT, 0, - DetectEngineInspectGenericList, NULL); - - g_buffer_id = DetectBufferTypeGetByName("dhcp.leasetime"); -} diff --git a/src/detect-dhcp-leasetime.h b/src/detect-dhcp-leasetime.h deleted file mode 100644 index 53b1f42ac73d..000000000000 --- a/src/detect-dhcp-leasetime.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (C) 2022 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. - */ - -#ifndef SURICATA_DETECT_DHCP_LEASETIME_H -#define SURICATA_DETECT_DHCP_LEASETIME_H - -void DetectDHCPLeaseTimeRegister(void); - -#endif /* SURICATA_DETECT_DHCP_LEASETIME_H */ diff --git a/src/detect-dhcp-rebinding-time.c b/src/detect-dhcp-rebinding-time.c deleted file mode 100644 index 737d332841b7..000000000000 --- a/src/detect-dhcp-rebinding-time.c +++ /dev/null @@ -1,128 +0,0 @@ -/* Copyright (C) 2022 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. - */ - -#include "suricata-common.h" -#include "rust.h" -#include "detect-dhcp-rebinding-time.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-prefilter.h" -#include "detect-engine-uint.h" -#include "detect-parse.h" - -static int g_buffer_id = 0; - -/** - * \internal - * \brief Function to match rebinding time of a TX - * - * \param t Pointer to thread vars. - * \param det_ctx Pointer to the pattern matcher thread. - * \param f Pointer to the current flow. - * \param flags Flags. - * \param state App layer state. - * \param s Pointer to the Signature. - * \param m Pointer to the sigmatch that we will cast into - * DetectU64Data. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DetectDHCPRebindingTimeMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, - void *state, void *txv, const Signature *s, const SigMatchCtx *ctx) -{ - SCEnter(); - - uint64_t res; - if (rs_dhcp_tx_get_rebinding_time(txv, &res)) { - const DetectU64Data *dd = (const DetectU64Data *)ctx; - if (DetectU64Match(res, dd)) { - SCReturnInt(1); - } - } - SCReturnInt(0); -} - -/** - * \internal - * \brief Function to free memory associated with DetectU64Data. - * - * \param de_ptr Pointer to DetectU64Data. - */ -static void DetectDHCPRebindingTimeFree(DetectEngineCtx *de_ctx, void *ptr) -{ - rs_detect_u64_free(ptr); -} - -/** - * \brief Function to add the parsed dhcp rebinding time field into the current signature. - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param s Pointer to the Current Signature. - * \param rawstr Pointer to the user provided flags options. - * \param type Defines if this is notBefore or notAfter. - * - * \retval 0 on Success. - * \retval -1 on Failure. - */ -static int DetectDHCPRebindingTimeSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr) -{ - if (DetectSignatureSetAppProto(s, ALPROTO_DHCP) != 0) - return -1; - - DetectU64Data *dd = DetectU64Parse(rawstr); - if (dd == NULL) { - SCLogError("Parsing \'%s\' failed for %s", rawstr, - sigmatch_table[DETECT_AL_DHCP_REBINDING_TIME].name); - return -1; - } - - /* okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - - if (SigMatchAppendSMToList( - de_ctx, s, DETECT_AL_DHCP_REBINDING_TIME, (SigMatchCtx *)dd, g_buffer_id) == NULL) { - goto error; - } - return 0; - -error: - DetectDHCPRebindingTimeFree(de_ctx, dd); - return -1; -} - -/** - * \brief Registration function for dhcp.procedure keyword. - */ -void DetectDHCPRebindingTimeRegister(void) -{ - sigmatch_table[DETECT_AL_DHCP_REBINDING_TIME].name = "dhcp.rebinding_time"; - sigmatch_table[DETECT_AL_DHCP_REBINDING_TIME].desc = "match DHCP rebinding time"; - sigmatch_table[DETECT_AL_DHCP_REBINDING_TIME].url = - "/rules/dhcp-keywords.html#dhcp-rebinding-time"; - sigmatch_table[DETECT_AL_DHCP_REBINDING_TIME].AppLayerTxMatch = DetectDHCPRebindingTimeMatch; - sigmatch_table[DETECT_AL_DHCP_REBINDING_TIME].Setup = DetectDHCPRebindingTimeSetup; - sigmatch_table[DETECT_AL_DHCP_REBINDING_TIME].Free = DetectDHCPRebindingTimeFree; - - DetectAppLayerInspectEngineRegister("dhcp.rebinding-time", ALPROTO_DHCP, SIG_FLAG_TOSERVER, 0, - DetectEngineInspectGenericList, NULL); - - DetectAppLayerInspectEngineRegister("dhcp.rebinding-time", ALPROTO_DHCP, SIG_FLAG_TOCLIENT, 0, - DetectEngineInspectGenericList, NULL); - - g_buffer_id = DetectBufferTypeGetByName("dhcp.rebinding-time"); -} diff --git a/src/detect-dhcp-rebinding-time.h b/src/detect-dhcp-rebinding-time.h deleted file mode 100644 index b14f0af66139..000000000000 --- a/src/detect-dhcp-rebinding-time.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (C) 2022 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. - */ - -#ifndef SURICATA_DETECT_DHCP_REBINDING_TIME_H -#define SURICATA_DETECT_DHCP_REBINDING_TIME_H - -void DetectDHCPRebindingTimeRegister(void); - -#endif /* SURICATA_DETECT_DHCP_REBINDING_TIME_H */ diff --git a/src/detect-dhcp-renewal-time.c b/src/detect-dhcp-renewal-time.c deleted file mode 100644 index d991fa1d2a4f..000000000000 --- a/src/detect-dhcp-renewal-time.c +++ /dev/null @@ -1,127 +0,0 @@ -/* Copyright (C) 2022 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. - */ - -#include "suricata-common.h" -#include "rust.h" -#include "detect-dhcp-renewal-time.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-prefilter.h" -#include "detect-engine-uint.h" -#include "detect-parse.h" - -static int g_buffer_id = 0; - -/** - * \internal - * \brief Function to match renewal time of a TX - * - * \param t Pointer to thread vars. - * \param det_ctx Pointer to the pattern matcher thread. - * \param f Pointer to the current flow. - * \param flags Flags. - * \param state App layer state. - * \param s Pointer to the Signature. - * \param m Pointer to the sigmatch that we will cast into - * DetectU64Data. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DetectDHCPRenewalTimeMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, - void *state, void *txv, const Signature *s, const SigMatchCtx *ctx) -{ - SCEnter(); - - uint64_t res; - if (rs_dhcp_tx_get_renewal_time(txv, &res)) { - const DetectU64Data *dd = (const DetectU64Data *)ctx; - if (DetectU64Match(res, dd)) { - SCReturnInt(1); - } - } - SCReturnInt(0); -} - -/** - * \internal - * \brief Function to free memory associated with DetectU64Data. - * - * \param de_ptr Pointer to DetectU64Data. - */ -static void DetectDHCPRenewalTimeFree(DetectEngineCtx *de_ctx, void *ptr) -{ - rs_detect_u64_free(ptr); -} - -/** - * \brief Function to add the parsed dhcp renewal time field into the current signature. - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param s Pointer to the Current Signature. - * \param rawstr Pointer to the user provided flags options. - * \param type Defines if this is notBefore or notAfter. - * - * \retval 0 on Success. - * \retval -1 on Failure. - */ -static int DetectDHCPRenewalTimeSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr) -{ - if (DetectSignatureSetAppProto(s, ALPROTO_DHCP) != 0) - return -1; - - DetectU64Data *dd = DetectU64Parse(rawstr); - if (dd == NULL) { - SCLogError("Parsing \'%s\' failed for %s", rawstr, - sigmatch_table[DETECT_AL_DHCP_RENEWAL_TIME].name); - return -1; - } - - /* okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - - if (SigMatchAppendSMToList( - de_ctx, s, DETECT_AL_DHCP_RENEWAL_TIME, (SigMatchCtx *)dd, g_buffer_id) == NULL) { - goto error; - } - return 0; - -error: - DetectDHCPRenewalTimeFree(de_ctx, dd); - return -1; -} - -/** - * \brief Registration function for dhcp.procedure keyword. - */ -void DetectDHCPRenewalTimeRegister(void) -{ - sigmatch_table[DETECT_AL_DHCP_RENEWAL_TIME].name = "dhcp.renewal_time"; - sigmatch_table[DETECT_AL_DHCP_RENEWAL_TIME].desc = "match DHCP renewal time"; - sigmatch_table[DETECT_AL_DHCP_RENEWAL_TIME].url = "/rules/dhcp-keywords.html#dhcp-renewal-time"; - sigmatch_table[DETECT_AL_DHCP_RENEWAL_TIME].AppLayerTxMatch = DetectDHCPRenewalTimeMatch; - sigmatch_table[DETECT_AL_DHCP_RENEWAL_TIME].Setup = DetectDHCPRenewalTimeSetup; - sigmatch_table[DETECT_AL_DHCP_RENEWAL_TIME].Free = DetectDHCPRenewalTimeFree; - - DetectAppLayerInspectEngineRegister("dhcp.renewal-time", ALPROTO_DHCP, SIG_FLAG_TOSERVER, 0, - DetectEngineInspectGenericList, NULL); - - DetectAppLayerInspectEngineRegister("dhcp.renewal-time", ALPROTO_DHCP, SIG_FLAG_TOCLIENT, 0, - DetectEngineInspectGenericList, NULL); - - g_buffer_id = DetectBufferTypeGetByName("dhcp.renewal-time"); -} diff --git a/src/detect-dhcp-renewal-time.h b/src/detect-dhcp-renewal-time.h deleted file mode 100644 index 06d64c5560b3..000000000000 --- a/src/detect-dhcp-renewal-time.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (C) 2022 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. - */ - -#ifndef SURICATA_DETECT_DHCP_RENEWAL_TIME_H -#define SURICATA_DETECT_DHCP_RENEWAL_TIME_H - -void DetectDHCPRenewalTimeRegister(void); - -#endif /* SURICATA_DETECT_DHCP_RENEWAL_TIME_H */ diff --git a/src/detect-engine-helper.c b/src/detect-engine-helper.c new file mode 100644 index 000000000000..0b7c9ccb2077 --- /dev/null +++ b/src/detect-engine-helper.c @@ -0,0 +1,107 @@ +/* Copyright (C) 2023 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. + */ + +/** + * \file + * + * \author Philippe Antoine + * + */ + +#include "suricata-common.h" +#include "detect-engine.h" +#include "detect-engine-helper.h" +#include "detect-engine-mpm.h" +#include "detect-engine-prefilter.h" +#include "detect-parse.h" + +int DetectHelperBufferRegister(const char *name, AppProto alproto, bool toclient, bool toserver) +{ + if (toserver) { + DetectAppLayerInspectEngineRegister( + name, alproto, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL); + } + if (toclient) { + DetectAppLayerInspectEngineRegister( + name, alproto, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectGenericList, NULL); + } + return DetectBufferTypeRegister(name); +} + +InspectionBuffer *DetectHelperGetData(struct DetectEngineThreadCtx_ *det_ctx, + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, + const int list_id, + bool (*GetBuf)(void *txv, const uint8_t flow_flags, const uint8_t **buf, uint32_t *buf_len)) +{ + InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); + if (buffer->inspect == NULL) { + const uint8_t *b = NULL; + uint32_t b_len = 0; + + if (!GetBuf(txv, flow_flags, &b, &b_len)) + return NULL; + + InspectionBufferSetup(det_ctx, list_id, buffer, b, b_len); + InspectionBufferApplyTransforms(buffer, transforms); + } + return buffer; +} + +int DetectHelperBufferMpmRegister(const char *name, const char *desc, AppProto alproto, + bool toclient, bool toserver, InspectionBufferGetDataPtr GetData) +{ + if (toserver) { + DetectAppLayerInspectEngineRegister( + name, alproto, SIG_FLAG_TOSERVER, 0, DetectEngineInspectBufferGeneric, GetData); + DetectAppLayerMpmRegister( + name, SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister, GetData, alproto, 0); + } + if (toclient) { + DetectAppLayerInspectEngineRegister( + name, alproto, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectBufferGeneric, GetData); + DetectAppLayerMpmRegister( + name, SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister, GetData, alproto, 0); + } + DetectBufferTypeSetDescriptionByName(name, desc); + return DetectBufferTypeGetByName(name); +} + +int DetectHelperKeywordRegister(const SCSigTableElmt *kw) +{ + if (DETECT_TBLSIZE_IDX >= DETECT_TBLSIZE) { + void *tmp = SCRealloc( + sigmatch_table, (DETECT_TBLSIZE + DETECT_TBLSIZE_STEP) * sizeof(SigTableElmt)); + if (unlikely(tmp == NULL)) { + return -1; + } + sigmatch_table = tmp; + DETECT_TBLSIZE += DETECT_TBLSIZE_STEP; + } + + sigmatch_table[DETECT_TBLSIZE_IDX].name = kw->name; + sigmatch_table[DETECT_TBLSIZE_IDX].desc = kw->desc; + sigmatch_table[DETECT_TBLSIZE_IDX].url = kw->url; + sigmatch_table[DETECT_TBLSIZE_IDX].flags = kw->flags; + sigmatch_table[DETECT_TBLSIZE_IDX].AppLayerTxMatch = + (int (*)(DetectEngineThreadCtx * det_ctx, Flow * f, uint8_t flags, void *alstate, + void *txv, const Signature *s, const SigMatchCtx *ctx)) kw->AppLayerTxMatch; + sigmatch_table[DETECT_TBLSIZE_IDX].Setup = + (int (*)(DetectEngineCtx * de, Signature * s, const char *raw)) kw->Setup; + sigmatch_table[DETECT_TBLSIZE_IDX].Free = (void (*)(DetectEngineCtx * de, void *ptr)) kw->Free; + DETECT_TBLSIZE_IDX++; + return DETECT_TBLSIZE_IDX - 1; +} diff --git a/src/detect-engine-helper.h b/src/detect-engine-helper.h new file mode 100644 index 000000000000..bd8fe6cce5a6 --- /dev/null +++ b/src/detect-engine-helper.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2023 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. + */ + +/** + * \file + * + * \author Philippe Antoine + */ + +#ifndef SURICATA_DETECT_ENGINE_HELPER_H +#define SURICATA_DETECT_ENGINE_HELPER_H + +#include "app-layer-protos.h" +#include "detect.h" +#include "rust.h" + +int DetectHelperKeywordRegister(const SCSigTableElmt *kw); +int DetectHelperBufferRegister(const char *name, AppProto alproto, bool toclient, bool toserver); + +typedef bool (*SimpleGetTxBuffer)(void *, uint8_t, const uint8_t **, uint32_t *); +InspectionBuffer *DetectHelperGetData(struct DetectEngineThreadCtx_ *det_ctx, + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, + const int list_id, SimpleGetTxBuffer GetBuf); +int DetectHelperBufferMpmRegister(const char *name, const char *desc, AppProto alproto, + bool toclient, bool toserver, InspectionBufferGetDataPtr GetData); + +#endif /* SURICATA_DETECT_ENGINE_HELPER_H */ diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index 5608ae218f51..a1f098f1a24a 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -211,13 +211,6 @@ #include "detect-rfb-name.h" #include "detect-target.h" #include "detect-template-rust-buffer.h" -#include "detect-dhcp-leasetime.h" -#include "detect-dhcp-rebinding-time.h" -#include "detect-dhcp-renewal-time.h" -#include "detect-snmp-usm.h" -#include "detect-snmp-version.h" -#include "detect-snmp-community.h" -#include "detect-snmp-pdu_type.h" #include "detect-mqtt-type.h" #include "detect-mqtt-flags.h" #include "detect-mqtt-qos.h" @@ -241,7 +234,6 @@ #include "detect-quic-cyu-hash.h" #include "detect-quic-cyu-string.h" #include "detect-ja4-hash.h" -#include "detect-websocket.h" #include "detect-bypass.h" #include "detect-ftpdata.h" @@ -321,6 +313,9 @@ #include "util-mpm-ac.h" #include "runmodes.h" +int DETECT_TBLSIZE = 0; +int DETECT_TBLSIZE_IDX = DETECT_TBLSIZE_STATIC; + static void PrintFeatureList(const SigTableElmt *e, char sep) { const uint16_t flags = e->flags; @@ -389,7 +384,7 @@ static void SigMultilinePrint(int i, const char *prefix) int SigTableList(const char *keyword) { - size_t size = sizeof(sigmatch_table) / sizeof(SigTableElmt); + size_t size = DETECT_TBLSIZE; size_t i; if (keyword == NULL) { @@ -464,15 +459,32 @@ int SigTableList(const char *keyword) static void DetectFileHandlerRegister(void) { - for (int i = 0; i < DETECT_TBLSIZE; i++) { + for (int i = 0; i < DETECT_TBLSIZE_STATIC; i++) { if (filehandler_table[i].name) DetectFileRegisterFileProtocols(&filehandler_table[i]); } } +void SigTableCleanup(void) +{ + if (sigmatch_table != NULL) { + SCFree(sigmatch_table); + sigmatch_table = NULL; + DETECT_TBLSIZE = 0; + } +} + void SigTableSetup(void) { - memset(sigmatch_table, 0, sizeof(sigmatch_table)); + if (sigmatch_table == NULL) { + DETECT_TBLSIZE = DETECT_TBLSIZE_STATIC + DETECT_TBLSIZE_STEP; + sigmatch_table = SCCalloc(DETECT_TBLSIZE, sizeof(SigTableElmt)); + if (sigmatch_table == NULL) { + DETECT_TBLSIZE = 0; + FatalError("Could not allocate sigmatch_table"); + return; + } + } DetectSidRegister(); DetectPriorityRegister(); @@ -680,13 +692,6 @@ void SigTableSetup(void) DetectRfbNameRegister(); DetectTargetRegister(); DetectTemplateRustBufferRegister(); - DetectDHCPLeaseTimeRegister(); - DetectDHCPRebindingTimeRegister(); - DetectDHCPRenewalTimeRegister(); - DetectSNMPUsmRegister(); - DetectSNMPVersionRegister(); - DetectSNMPCommunityRegister(); - DetectSNMPPduTypeRegister(); DetectMQTTTypeRegister(); DetectMQTTFlagsRegister(); DetectMQTTQosRegister(); @@ -710,7 +715,6 @@ void SigTableSetup(void) DetectQuicCyuHashRegister(); DetectQuicCyuStringRegister(); DetectJa4HashRegister(); - DetectWebsocketRegister(); DetectBypassRegister(); DetectConfigRegister(); @@ -731,6 +735,10 @@ void SigTableSetup(void) DetectFileHandlerRegister(); + ScDetectSNMPRegister(); + ScDetectDHCPRegister(); + ScDetectWebsocketRegister(); + /* close keyword registration */ DetectBufferTypeCloseRegistration(); } diff --git a/src/detect-engine-register.h b/src/detect-engine-register.h index cd2edf5979b8..7bde1bead30c 100644 --- a/src/detect-engine-register.h +++ b/src/detect-engine-register.h @@ -290,13 +290,6 @@ enum DetectKeywordId { DETECT_FTPDATA, DETECT_TARGET, DETECT_AL_TEMPLATE_BUFFER, - DETECT_AL_DHCP_LEASETIME, - DETECT_AL_DHCP_REBINDING_TIME, - DETECT_AL_DHCP_RENEWAL_TIME, - DETECT_AL_SNMP_USM, - DETECT_AL_SNMP_VERSION, - DETECT_AL_SNMP_COMMUNITY, - DETECT_AL_SNMP_PDU_TYPE, DETECT_AL_MQTT_TYPE, DETECT_AL_MQTT_FLAGS, DETECT_AL_MQTT_QOS, @@ -319,10 +312,6 @@ enum DetectKeywordId { DETECT_AL_QUIC_UA, DETECT_AL_QUIC_CYU_HASH, DETECT_AL_QUIC_CYU_STRING, - DETECT_WEBSOCKET_MASK, - DETECT_WEBSOCKET_OPCODE, - DETECT_WEBSOCKET_FLAGS, - DETECT_WEBSOCKET_PAYLOAD, DETECT_BYPASS, @@ -355,10 +344,15 @@ enum DetectKeywordId { DETECT_AL_JA4_HASH, /* make sure this stays last */ - DETECT_TBLSIZE, + DETECT_TBLSIZE_STATIC, }; +extern int DETECT_TBLSIZE; +extern int DETECT_TBLSIZE_IDX; +// step for reallocating sigmatch_table +#define DETECT_TBLSIZE_STEP 256 int SigTableList(const char *keyword); +void SigTableCleanup(void); void SigTableSetup(void); void SigTableRegisterTests(void); diff --git a/src/detect-engine.c b/src/detect-engine.c index 21ce4906f58b..3c5727ecc4d5 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -2439,6 +2439,14 @@ static DetectEngineCtx *DetectEngineCtxInitReal( goto error; } + de_ctx->sm_types_prefilter = SCCalloc(DETECT_TBLSIZE, sizeof(bool)); + if (de_ctx->sm_types_prefilter == NULL) { + goto error; + } + de_ctx->sm_types_silent_error = SCCalloc(DETECT_TBLSIZE, sizeof(bool)); + if (de_ctx->sm_types_silent_error == NULL) { + goto error; + } if (DetectEngineCtxLoadConf(de_ctx) == -1) { goto error; } @@ -2572,6 +2580,8 @@ void DetectEngineCtxFree(DetectEngineCtx *de_ctx) SigGroupCleanup(de_ctx); SpmDestroyGlobalThreadCtx(de_ctx->spm_global_thread_ctx); + SCFree(de_ctx->sm_types_prefilter); + SCFree(de_ctx->sm_types_silent_error); MpmFactoryDeRegisterAllMpmCtxProfiles(de_ctx); diff --git a/src/detect-icode.c b/src/detect-icode.c index 33d5beea4ebf..ab56553cc0c6 100644 --- a/src/detect-icode.c +++ b/src/detect-icode.c @@ -311,7 +311,6 @@ static int DetectICodeParseTest08(void) DetectU8Data *icd = DetectU8Parse("> 8 <> 20"); FAIL_IF_NOT_NULL(icd); - DetectICodeFree(NULL, icd); PASS; } @@ -324,7 +323,6 @@ static int DetectICodeParseTest09(void) DetectU8Data *icd = DetectU8Parse("8<<20"); FAIL_IF_NOT_NULL(icd); - DetectICodeFree(NULL, icd); PASS; } diff --git a/src/detect-itype.c b/src/detect-itype.c index 8a9af908836b..237d0548e6f1 100644 --- a/src/detect-itype.c +++ b/src/detect-itype.c @@ -334,7 +334,6 @@ static int DetectITypeParseTest08(void) DetectU8Data *itd = NULL; itd = DetectITypeParse(NULL, "> 8 <> 20"); FAIL_IF_NOT_NULL(itd); - DetectITypeFree(NULL, itd); PASS; } diff --git a/src/detect-parse.c b/src/detect-parse.c index 028943920072..8f4482c62b6e 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -74,7 +74,7 @@ #include "util-validate.h" /* Table with all filehandler registrations */ -DetectFileHandlerTableElmt filehandler_table[DETECT_TBLSIZE]; +DetectFileHandlerTableElmt filehandler_table[DETECT_TBLSIZE_STATIC]; void DetectFileRegisterFileProtocols(DetectFileHandlerTableElmt *reg) { @@ -124,7 +124,7 @@ void DetectFileRegisterFileProtocols(DetectFileHandlerTableElmt *reg) } /* Table with all SigMatch registrations */ -SigTableElmt sigmatch_table[DETECT_TBLSIZE]; +SigTableElmt *sigmatch_table = NULL; extern bool sc_set_caps; @@ -394,7 +394,7 @@ bool SigMatchSilentErrorEnabled(const DetectEngineCtx *de_ctx, bool SigMatchStrictEnabled(const enum DetectKeywordId id) { - if (id < DETECT_TBLSIZE) { + if ((int)id < DETECT_TBLSIZE) { return ((sigmatch_table[id].flags & SIGMATCH_STRICT_PARSING) != 0); } return false; diff --git a/src/detect-parse.h b/src/detect-parse.h index 0a993a794f84..ec2c204c0f42 100644 --- a/src/detect-parse.h +++ b/src/detect-parse.h @@ -42,7 +42,7 @@ typedef struct DetectFileHandlerTableElmt_ { void DetectFileRegisterFileProtocols(DetectFileHandlerTableElmt *entry); /* File registration table */ -extern DetectFileHandlerTableElmt filehandler_table[DETECT_TBLSIZE]; +extern DetectFileHandlerTableElmt filehandler_table[DETECT_TBLSIZE_STATIC]; /** Flags to indicate if the Signature parsing must be done * switching the source and dest (for ip addresses and ports) diff --git a/src/detect-snmp-community.c b/src/detect-snmp-community.c deleted file mode 100644 index 76c4bddd0ab6..000000000000 --- a/src/detect-snmp-community.c +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright (C) 2015-2019 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. - */ - -/** - * \file - * - * \author Pierre Chifflier - * - * Set up of the "snmp.community" keyword to allow content - * inspections on the decoded snmp community. - */ - -#include "suricata-common.h" -#include "conf.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-prefilter.h" -#include "detect-engine-content-inspection.h" -#include "detect-snmp-community.h" -#include "app-layer-parser.h" -#include "rust.h" - -static int DetectSNMPCommunitySetup(DetectEngineCtx *, Signature *, - const char *); -static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, - const int list_id); -static int g_snmp_rust_id = 0; - -void DetectSNMPCommunityRegister(void) -{ - sigmatch_table[DETECT_AL_SNMP_COMMUNITY].name = "snmp.community"; - sigmatch_table[DETECT_AL_SNMP_COMMUNITY].desc = - "SNMP content modifier to match on the SNMP community"; - sigmatch_table[DETECT_AL_SNMP_COMMUNITY].Setup = DetectSNMPCommunitySetup; - sigmatch_table[DETECT_AL_SNMP_COMMUNITY].url = "/rules/snmp-keywords.html#snmp-community"; - sigmatch_table[DETECT_AL_SNMP_COMMUNITY].flags |= SIGMATCH_NOOPT|SIGMATCH_INFO_STICKY_BUFFER; - - /* register inspect engines */ - DetectAppLayerInspectEngineRegister("snmp.community", ALPROTO_SNMP, SIG_FLAG_TOSERVER, 0, - DetectEngineInspectBufferGeneric, GetData); - DetectAppLayerMpmRegister("snmp.community", SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister, - GetData, ALPROTO_SNMP, 0); - DetectAppLayerInspectEngineRegister("snmp.community", ALPROTO_SNMP, SIG_FLAG_TOCLIENT, 0, - DetectEngineInspectBufferGeneric, GetData); - DetectAppLayerMpmRegister("snmp.community", SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister, - GetData, ALPROTO_SNMP, 0); - - DetectBufferTypeSetDescriptionByName("snmp.community", "SNMP Community identifier"); - - g_snmp_rust_id = DetectBufferTypeGetByName("snmp.community"); -} - -static int DetectSNMPCommunitySetup(DetectEngineCtx *de_ctx, Signature *s, - const char *str) -{ - if (DetectBufferSetActiveList(de_ctx, s, g_snmp_rust_id) < 0) - return -1; - - if (DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0) - return -1; - - return 0; -} - -static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *f, - const uint8_t flow_flags, void *txv, const int list_id) -{ - InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); - if (buffer->inspect == NULL) { - uint32_t data_len = 0; - const uint8_t *data = NULL; - - rs_snmp_tx_get_community(txv, &data, &data_len); - if (data == NULL || data_len == 0) { - return NULL; - } - - InspectionBufferSetup(det_ctx, list_id, buffer, data, data_len); - InspectionBufferApplyTransforms(buffer, transforms); - } - - return buffer; -} diff --git a/src/detect-snmp-community.h b/src/detect-snmp-community.h deleted file mode 100644 index 082d9c1970f6..000000000000 --- a/src/detect-snmp-community.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2015-2019 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. - */ - -/** - * \file - * - * \author FirstName LastName - */ - -#ifndef SURICATA_DETECT_SNMP_COMMUNITY_H -#define SURICATA_DETECT_SNMP_COMMUNITY_H - -void DetectSNMPCommunityRegister(void); - -#endif /* SURICATA_DETECT_SNMP_COMMUNITY_H */ diff --git a/src/detect-snmp-pdu_type.c b/src/detect-snmp-pdu_type.c deleted file mode 100644 index 331abce7f355..000000000000 --- a/src/detect-snmp-pdu_type.c +++ /dev/null @@ -1,221 +0,0 @@ -/* Copyright (C) 2015-2020 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. - */ - -/** - * \file - * - * \author Pierre Chifflier - */ - -#include "suricata-common.h" -#include "conf.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-content-inspection.h" -#include "detect-snmp-pdu_type.h" -#include "app-layer-parser.h" -#include "rust.h" - -/** - * [snmp.pdu_type]:; - */ -#define PARSE_REGEX "^\\s*([0-9]+)\\s*$" -static DetectParseRegex parse_regex; - -typedef struct DetectSNMPPduTypeData_ { - uint32_t pdu_type; -} DetectSNMPPduTypeData; - -static DetectSNMPPduTypeData *DetectSNMPPduTypeParse (const char *); -static int DetectSNMPPduTypeSetup (DetectEngineCtx *, Signature *s, const char *str); -static void DetectSNMPPduTypeFree(DetectEngineCtx *, void *); -#ifdef UNITTESTS -static void DetectSNMPPduTypeRegisterTests(void); -#endif -static int g_snmp_pdu_type_buffer_id = 0; - -static int DetectSNMPPduTypeMatch (DetectEngineThreadCtx *, Flow *, - uint8_t, void *, void *, const Signature *, - const SigMatchCtx *); - -void DetectSNMPPduTypeRegister(void) -{ - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].name = "snmp.pdu_type"; - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].desc = "match SNMP PDU type"; - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].url = "/rules/snmp-keywords.html#snmp-pdu-type"; - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].Match = NULL; - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].AppLayerTxMatch = DetectSNMPPduTypeMatch; - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].Setup = DetectSNMPPduTypeSetup; - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].Free = DetectSNMPPduTypeFree; -#ifdef UNITTESTS - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].RegisterTests = DetectSNMPPduTypeRegisterTests; -#endif - - DetectSetupParseRegexes(PARSE_REGEX, &parse_regex); - - DetectAppLayerInspectEngineRegister("snmp.pdu_type", ALPROTO_SNMP, SIG_FLAG_TOSERVER, 0, - DetectEngineInspectGenericList, NULL); - - DetectAppLayerInspectEngineRegister("snmp.pdu_type", ALPROTO_SNMP, SIG_FLAG_TOCLIENT, 0, - DetectEngineInspectGenericList, NULL); - - g_snmp_pdu_type_buffer_id = DetectBufferTypeGetByName("snmp.pdu_type"); -} - -/** - * \internal - * \brief Function to match pdu_type of a TX - * - * \param t Pointer to thread vars. - * \param det_ctx Pointer to the pattern matcher thread. - * \param f Pointer to the current flow. - * \param flags Flags. - * \param state App layer state. - * \param s Pointer to the Signature. - * \param m Pointer to the sigmatch that we will cast into - * DetectSNMPPduTypeData. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DetectSNMPPduTypeMatch (DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *state, - void *txv, const Signature *s, - const SigMatchCtx *ctx) -{ - SCEnter(); - - const DetectSNMPPduTypeData *dd = (const DetectSNMPPduTypeData *)ctx; - uint32_t pdu_type; - rs_snmp_tx_get_pdu_type(txv, &pdu_type); - SCLogDebug("pdu_type %u ref_pdu_type %d", - pdu_type, dd->pdu_type); - if (pdu_type == dd->pdu_type) - SCReturnInt(1); - SCReturnInt(0); -} - -/** - * \internal - * \brief Function to parse options passed via snmp.pdu_type keywords. - * - * \param rawstr Pointer to the user provided options. - * - * \retval dd pointer to DetectSNMPPduTypeData on success. - * \retval NULL on failure. - */ -static DetectSNMPPduTypeData *DetectSNMPPduTypeParse (const char *rawstr) -{ - DetectSNMPPduTypeData *dd = NULL; - int res = 0; - size_t pcre2len; - char value1[20] = ""; - char *endptr = NULL; - - pcre2_match_data *match = NULL; - int ret = DetectParsePcreExec(&parse_regex, &match, rawstr, 0, 0); - if (ret != 2) { - SCLogError("Parse error %s", rawstr); - goto error; - } - - pcre2len = sizeof(value1); - res = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)value1, &pcre2len); - if (res < 0) { - SCLogError("pcre2_substring_copy_bynumber failed"); - goto error; - } - - dd = SCCalloc(1, sizeof(DetectSNMPPduTypeData)); - if (unlikely(dd == NULL)) - goto error; - - /* set the value */ - dd->pdu_type = strtoul(value1, &endptr, 10); - if (endptr == NULL || *endptr != '\0') { - SCLogError("invalid character as arg " - "to snmp.pdu_type keyword"); - goto error; - } - - pcre2_match_data_free(match); - return dd; - -error: - if (match) { - pcre2_match_data_free(match); - } - if (dd) - SCFree(dd); - return NULL; -} - -/** - * \brief Function to add the parsed snmp pdu_type field into the current signature. - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param s Pointer to the Current Signature. - * \param rawstr Pointer to the user provided flags options. - * \param type Defines if this is notBefore or notAfter. - * - * \retval 0 on Success. - * \retval -1 on Failure. - */ -static int DetectSNMPPduTypeSetup (DetectEngineCtx *de_ctx, Signature *s, - const char *rawstr) -{ - DetectSNMPPduTypeData *dd = NULL; - - if (DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0) - return -1; - - dd = DetectSNMPPduTypeParse(rawstr); - if (dd == NULL) { - SCLogError("Parsing \'%s\' failed", rawstr); - goto error; - } - - /* okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - - SCLogDebug("snmp.pdu_type %d", dd->pdu_type); - if (SigMatchAppendSMToList(de_ctx, s, DETECT_AL_SNMP_PDU_TYPE, (SigMatchCtx *)dd, - g_snmp_pdu_type_buffer_id) == NULL) { - goto error; - } - return 0; - -error: - DetectSNMPPduTypeFree(de_ctx, dd); - return -1; -} - -/** - * \internal - * \brief Function to free memory associated with DetectSNMPPduTypeData. - * - * \param de_ptr Pointer to DetectSNMPPduTypeData. - */ -static void DetectSNMPPduTypeFree(DetectEngineCtx *de_ctx, void *ptr) -{ - SCFree(ptr); -} - -#ifdef UNITTESTS -#include "tests/detect-snmp-pdu_type.c" -#endif /* UNITTESTS */ diff --git a/src/detect-snmp-pdu_type.h b/src/detect-snmp-pdu_type.h deleted file mode 100644 index a01dc98d4580..000000000000 --- a/src/detect-snmp-pdu_type.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2015-2019 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. - */ - -/** - * \file - * - * \author Pierre Chifflier - */ - -#ifndef SURICATA_DETECT_SNMP_PDU_TYPE_H -#define SURICATA_DETECT_SNMP_PDU_TYPE_H - -void DetectSNMPPduTypeRegister(void); - -#endif /* SURICATA_DETECT_SNMP_PDU_TYPE_H */ diff --git a/src/detect-snmp-usm.c b/src/detect-snmp-usm.c deleted file mode 100644 index fd1a814d164d..000000000000 --- a/src/detect-snmp-usm.c +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright (C) 2022 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. - */ - -#include "suricata-common.h" -#include "rust.h" -#include "detect-snmp-usm.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-prefilter.h" -#include "detect-parse.h" - -static int g_buffer_id = 0; - -static int DetectSNMPUsmSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str) -{ - if (DetectBufferSetActiveList(de_ctx, s, g_buffer_id) < 0) - return -1; - - if (DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0) - return -1; - - return 0; -} - -static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, - const int list_id) -{ - InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); - if (buffer->inspect == NULL) { - uint32_t data_len = 0; - const uint8_t *data = NULL; - - rs_snmp_tx_get_usm(txv, &data, &data_len); - if (data == NULL || data_len == 0) { - return NULL; - } - - InspectionBufferSetup(det_ctx, list_id, buffer, data, data_len); - InspectionBufferApplyTransforms(buffer, transforms); - } - - return buffer; -} - -void DetectSNMPUsmRegister(void) -{ - sigmatch_table[DETECT_AL_SNMP_USM].name = "snmp.usm"; - sigmatch_table[DETECT_AL_SNMP_USM].desc = "SNMP content modifier to match on the SNMP usm"; - sigmatch_table[DETECT_AL_SNMP_USM].Setup = DetectSNMPUsmSetup; - - sigmatch_table[DETECT_AL_SNMP_USM].flags |= SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER; - - /* register inspect engines */ - DetectAppLayerInspectEngineRegister("snmp.usm", ALPROTO_SNMP, SIG_FLAG_TOSERVER, 0, - DetectEngineInspectBufferGeneric, GetData); - DetectAppLayerMpmRegister("snmp.usm", SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister, - GetData, ALPROTO_SNMP, 0); - DetectAppLayerInspectEngineRegister("snmp.usm", ALPROTO_SNMP, SIG_FLAG_TOCLIENT, 0, - DetectEngineInspectBufferGeneric, GetData); - DetectAppLayerMpmRegister("snmp.usm", SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister, - GetData, ALPROTO_SNMP, 0); - - DetectBufferTypeSetDescriptionByName("snmp.usm", "SNMP USM"); - - g_buffer_id = DetectBufferTypeGetByName("snmp.usm"); -} diff --git a/src/detect-snmp-usm.h b/src/detect-snmp-usm.h deleted file mode 100644 index 9c86dad807b7..000000000000 --- a/src/detect-snmp-usm.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (C) 2022 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. - */ - -#ifndef SURICATA_DETECT_SNMP_USM_H -#define SURICATA_DETECT_SNMP_USM_H - -void DetectSNMPUsmRegister(void); - -#endif /* SURICATA_DETECT_SNMP_USM_H */ diff --git a/src/detect-snmp-version.c b/src/detect-snmp-version.c deleted file mode 100644 index cde70f251024..000000000000 --- a/src/detect-snmp-version.c +++ /dev/null @@ -1,174 +0,0 @@ -/* Copyright (C) 2015-2020 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. - */ - -/** - * \file - * - * \author Pierre Chifflier - */ - -#include "suricata-common.h" -#include "conf.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-content-inspection.h" -#include "detect-snmp-version.h" -#include "detect-engine-uint.h" -#include "app-layer-parser.h" -#include "rust.h" - - -static int DetectSNMPVersionSetup (DetectEngineCtx *, Signature *s, const char *str); -static void DetectSNMPVersionFree(DetectEngineCtx *, void *); -#ifdef UNITTESTS -static void DetectSNMPVersionRegisterTests(void); -#endif -static int g_snmp_version_buffer_id = 0; - -static int DetectSNMPVersionMatch (DetectEngineThreadCtx *, Flow *, - uint8_t, void *, void *, const Signature *, - const SigMatchCtx *); - -/** - * \brief Registration function for snmp.procedure keyword. - */ -void DetectSNMPVersionRegister (void) -{ - sigmatch_table[DETECT_AL_SNMP_VERSION].name = "snmp.version"; - sigmatch_table[DETECT_AL_SNMP_VERSION].desc = "match SNMP version"; - sigmatch_table[DETECT_AL_SNMP_VERSION].url = "/rules/snmp-keywords.html#snmp-version"; - sigmatch_table[DETECT_AL_SNMP_VERSION].Match = NULL; - sigmatch_table[DETECT_AL_SNMP_VERSION].AppLayerTxMatch = DetectSNMPVersionMatch; - sigmatch_table[DETECT_AL_SNMP_VERSION].Setup = DetectSNMPVersionSetup; - sigmatch_table[DETECT_AL_SNMP_VERSION].Free = DetectSNMPVersionFree; -#ifdef UNITTESTS - sigmatch_table[DETECT_AL_SNMP_VERSION].RegisterTests = DetectSNMPVersionRegisterTests; -#endif - - DetectAppLayerInspectEngineRegister("snmp.version", ALPROTO_SNMP, SIG_FLAG_TOSERVER, 0, - DetectEngineInspectGenericList, NULL); - - DetectAppLayerInspectEngineRegister("snmp.version", ALPROTO_SNMP, SIG_FLAG_TOCLIENT, 0, - DetectEngineInspectGenericList, NULL); - - g_snmp_version_buffer_id = DetectBufferTypeGetByName("snmp.version"); -} - -/** - * \internal - * \brief Function to match version of a TX - * - * \param t Pointer to thread vars. - * \param det_ctx Pointer to the pattern matcher thread. - * \param f Pointer to the current flow. - * \param flags Flags. - * \param state App layer state. - * \param s Pointer to the Signature. - * \param m Pointer to the sigmatch that we will cast into - * DetectU32Data. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DetectSNMPVersionMatch (DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *state, - void *txv, const Signature *s, - const SigMatchCtx *ctx) -{ - SCEnter(); - - const DetectU32Data *dd = (const DetectU32Data *)ctx; - uint32_t version; - rs_snmp_tx_get_version(txv, &version); - SCLogDebug("version %u mode %u ref_version %d", version, dd->mode, dd->arg1); - if (DetectU32Match(version, dd)) - SCReturnInt(1); - SCReturnInt(0); -} - -/** - * \internal - * \brief Function to parse options passed via snmp.version keywords. - * - * \param rawstr Pointer to the user provided options. - * - * \retval dd pointer to DetectU32Data on success. - * \retval NULL on failure. - */ -static DetectU32Data *DetectSNMPVersionParse(const char *rawstr) -{ - return DetectU32Parse(rawstr); -} - - - -/** - * \brief Function to add the parsed snmp version field into the current signature. - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param s Pointer to the Current Signature. - * \param rawstr Pointer to the user provided flags options. - * \param type Defines if this is notBefore or notAfter. - * - * \retval 0 on Success. - * \retval -1 on Failure. - */ -static int DetectSNMPVersionSetup (DetectEngineCtx *de_ctx, Signature *s, - const char *rawstr) -{ - DetectU32Data *dd = NULL; - - if (DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0) - return -1; - - dd = DetectSNMPVersionParse(rawstr); - if (dd == NULL) { - SCLogError("Parsing \'%s\' failed", rawstr); - goto error; - } - - /* okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - - SCLogDebug("snmp.version %d", dd->arg1); - if (SigMatchAppendSMToList(de_ctx, s, DETECT_AL_SNMP_VERSION, (SigMatchCtx *)dd, - g_snmp_version_buffer_id) == NULL) { - goto error; - } - return 0; - -error: - DetectSNMPVersionFree(de_ctx, dd); - return -1; -} - -/** - * \internal - * \brief Function to free memory associated with DetectU32Data. - * - * \param de_ptr Pointer to DetectU32Data. - */ -static void DetectSNMPVersionFree(DetectEngineCtx *de_ctx, void *ptr) -{ - rs_detect_u32_free(ptr); -} - - -#ifdef UNITTESTS -#include "tests/detect-snmp-version.c" -#endif /* UNITTESTS */ diff --git a/src/detect-snmp-version.h b/src/detect-snmp-version.h deleted file mode 100644 index cd71b59a245c..000000000000 --- a/src/detect-snmp-version.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2015-2019 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. - */ - -/** - * \file - * - * \author Pierre Chifflier - */ - -#ifndef SURICATA_DETECT_SNMP_VERSION_H -#define SURICATA_DETECT_SNMP_VERSION_H - -void DetectSNMPVersionRegister(void); - -#endif /* SURICATA_DETECT_SNMP_VERSION_H */ diff --git a/src/detect-websocket.c b/src/detect-websocket.c deleted file mode 100644 index 91f650c85c55..000000000000 --- a/src/detect-websocket.c +++ /dev/null @@ -1,251 +0,0 @@ -/* Copyright (C) 2023 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. - */ - -/** - * \file - * - * \author Philippe Antoine - */ - -#include "suricata-common.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-content-inspection.h" -#include "detect-engine-uint.h" -#include "detect-engine-prefilter.h" -#include "detect-websocket.h" - -#include "rust.h" - -static int websocket_tx_id = 0; -static int websocket_payload_id = 0; - -/** - * \internal - * \brief this function will free memory associated with DetectWebSocketOpcodeData - * - * \param de pointer to DetectWebSocketOpcodeData - */ -static void DetectWebSocketOpcodeFree(DetectEngineCtx *de_ctx, void *de_ptr) -{ - rs_detect_u8_free(de_ptr); -} - -/** - * \internal - * \brief Function to match opcode of a websocket tx - * - * \param det_ctx Pointer to the pattern matcher thread. - * \param f Pointer to the current flow. - * \param flags Flags. - * \param state App layer state. - * \param txv Pointer to the transaction. - * \param s Pointer to the Signature. - * \param ctx Pointer to the sigmatch that we will cast into DetectWebSocketOpcodeData. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DetectWebSocketOpcodeMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, - void *state, void *txv, const Signature *s, const SigMatchCtx *ctx) -{ - const DetectU8Data *de = (const DetectU8Data *)ctx; - uint8_t opc = SCWebSocketGetOpcode(txv); - return DetectU8Match(opc, de); -} - -/** - * \internal - * \brief this function is used to add the parsed sigmatch into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param rawstr pointer to the user provided options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectWebSocketOpcodeSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr) -{ - if (DetectSignatureSetAppProto(s, ALPROTO_WEBSOCKET) < 0) - return -1; - - DetectU8Data *de = SCWebSocketParseOpcode(rawstr); - if (de == NULL) - return -1; - - if (SigMatchAppendSMToList( - de_ctx, s, DETECT_WEBSOCKET_OPCODE, (SigMatchCtx *)de, websocket_tx_id) == NULL) { - DetectWebSocketOpcodeFree(de_ctx, de); - return -1; - } - - return 0; -} - -/** - * \internal - * \brief this function will free memory associated with DetectWebSocketMaskData - * - * \param de pointer to DetectWebSocketMaskData - */ -static void DetectWebSocketMaskFree(DetectEngineCtx *de_ctx, void *de_ptr) -{ - rs_detect_u32_free(de_ptr); -} - -static int DetectWebSocketMaskMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, - void *state, void *txv, const Signature *s, const SigMatchCtx *ctx) -{ - uint32_t val; - const DetectU32Data *du32 = (const DetectU32Data *)ctx; - if (SCWebSocketGetMask(txv, &val)) { - return DetectU32Match(val, du32); - } - return 0; -} - -static int DetectWebSocketMaskSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr) -{ - if (DetectSignatureSetAppProto(s, ALPROTO_WEBSOCKET) < 0) - return -1; - - DetectU32Data *du32 = DetectU32Parse(rawstr); - if (du32 == NULL) - return -1; - - if (SigMatchAppendSMToList( - de_ctx, s, DETECT_WEBSOCKET_MASK, (SigMatchCtx *)du32, websocket_tx_id) == NULL) { - DetectWebSocketMaskFree(de_ctx, du32); - return -1; - } - - return 0; -} - -static void DetectWebSocketFlagsFree(DetectEngineCtx *de_ctx, void *de_ptr) -{ - rs_detect_u8_free(de_ptr); -} - -static int DetectWebSocketFlagsMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, - void *state, void *txv, const Signature *s, const SigMatchCtx *ctx) -{ - const DetectU8Data *de = (const DetectU8Data *)ctx; - uint8_t val = SCWebSocketGetFlags(txv); - return DetectU8Match(val, de); -} - -static int DetectWebSocketFlagsSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr) -{ - if (DetectSignatureSetAppProto(s, ALPROTO_WEBSOCKET) < 0) - return -1; - - DetectU8Data *de = SCWebSocketParseFlags(rawstr); - if (de == NULL) - return -1; - - if (SigMatchAppendSMToList( - de_ctx, s, DETECT_WEBSOCKET_FLAGS, (SigMatchCtx *)de, websocket_tx_id) == NULL) { - DetectWebSocketOpcodeFree(de_ctx, de); - return -1; - } - - return 0; -} - -static int DetectWebSocketPayloadSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rulestr) -{ - if (DetectBufferSetActiveList(de_ctx, s, websocket_payload_id) < 0) - return -1; - - if (DetectSignatureSetAppProto(s, ALPROTO_WEBSOCKET) != 0) - return -1; - - return 0; -} - -static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *_f, const uint8_t _flow_flags, void *txv, - const int list_id) -{ - InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); - if (buffer->inspect == NULL) { - const uint8_t *b = NULL; - uint32_t b_len = 0; - - if (!SCWebSocketGetPayload(txv, &b, &b_len)) - return NULL; - if (b == NULL || b_len == 0) - return NULL; - - InspectionBufferSetup(det_ctx, list_id, buffer, b, b_len); - InspectionBufferApplyTransforms(buffer, transforms); - } - return buffer; -} - -/** - * \brief Registration function for websocket.opcode: keyword - */ -void DetectWebsocketRegister(void) -{ - sigmatch_table[DETECT_WEBSOCKET_OPCODE].name = "websocket.opcode"; - sigmatch_table[DETECT_WEBSOCKET_OPCODE].desc = "match WebSocket opcode"; - sigmatch_table[DETECT_WEBSOCKET_OPCODE].url = "/rules/websocket-keywords.html#websocket-opcode"; - sigmatch_table[DETECT_WEBSOCKET_OPCODE].AppLayerTxMatch = DetectWebSocketOpcodeMatch; - sigmatch_table[DETECT_WEBSOCKET_OPCODE].Setup = DetectWebSocketOpcodeSetup; - sigmatch_table[DETECT_WEBSOCKET_OPCODE].Free = DetectWebSocketOpcodeFree; - - DetectAppLayerInspectEngineRegister("websocket.tx", ALPROTO_WEBSOCKET, SIG_FLAG_TOSERVER, 1, - DetectEngineInspectGenericList, NULL); - DetectAppLayerInspectEngineRegister("websocket.tx", ALPROTO_WEBSOCKET, SIG_FLAG_TOCLIENT, 1, - DetectEngineInspectGenericList, NULL); - - websocket_tx_id = DetectBufferTypeGetByName("websocket.tx"); - - sigmatch_table[DETECT_WEBSOCKET_MASK].name = "websocket.mask"; - sigmatch_table[DETECT_WEBSOCKET_MASK].desc = "match WebSocket mask"; - sigmatch_table[DETECT_WEBSOCKET_MASK].url = "/rules/websocket-keywords.html#websocket-mask"; - sigmatch_table[DETECT_WEBSOCKET_MASK].AppLayerTxMatch = DetectWebSocketMaskMatch; - sigmatch_table[DETECT_WEBSOCKET_MASK].Setup = DetectWebSocketMaskSetup; - sigmatch_table[DETECT_WEBSOCKET_MASK].Free = DetectWebSocketMaskFree; - - sigmatch_table[DETECT_WEBSOCKET_FLAGS].name = "websocket.flags"; - sigmatch_table[DETECT_WEBSOCKET_FLAGS].desc = "match WebSocket flags"; - sigmatch_table[DETECT_WEBSOCKET_FLAGS].url = "/rules/websocket-keywords.html#websocket-flags"; - sigmatch_table[DETECT_WEBSOCKET_FLAGS].AppLayerTxMatch = DetectWebSocketFlagsMatch; - sigmatch_table[DETECT_WEBSOCKET_FLAGS].Setup = DetectWebSocketFlagsSetup; - sigmatch_table[DETECT_WEBSOCKET_FLAGS].Free = DetectWebSocketFlagsFree; - - sigmatch_table[DETECT_WEBSOCKET_PAYLOAD].name = "websocket.payload"; - sigmatch_table[DETECT_WEBSOCKET_PAYLOAD].desc = "match WebSocket payload"; - sigmatch_table[DETECT_WEBSOCKET_PAYLOAD].url = - "/rules/websocket-keywords.html#websocket-payload"; - sigmatch_table[DETECT_WEBSOCKET_PAYLOAD].Setup = DetectWebSocketPayloadSetup; - sigmatch_table[DETECT_WEBSOCKET_PAYLOAD].flags |= SIGMATCH_NOOPT; - DetectAppLayerInspectEngineRegister("websocket.payload", ALPROTO_WEBSOCKET, SIG_FLAG_TOSERVER, - 0, DetectEngineInspectBufferGeneric, GetData); - DetectAppLayerInspectEngineRegister("websocket.payload", ALPROTO_WEBSOCKET, SIG_FLAG_TOCLIENT, - 0, DetectEngineInspectBufferGeneric, GetData); - DetectAppLayerMpmRegister("websocket.payload", SIG_FLAG_TOSERVER, 2, - PrefilterGenericMpmRegister, GetData, ALPROTO_WEBSOCKET, 1); - DetectAppLayerMpmRegister("websocket.payload", SIG_FLAG_TOCLIENT, 2, - PrefilterGenericMpmRegister, GetData, ALPROTO_WEBSOCKET, 1); - websocket_payload_id = DetectBufferTypeGetByName("websocket.payload"); -} diff --git a/src/detect-websocket.h b/src/detect-websocket.h deleted file mode 100644 index 54e8a22ae4a8..000000000000 --- a/src/detect-websocket.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2023 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. - */ - -/** - * \file - * - * \author Philippe Antoine - */ - -#ifndef __DETECT_WEBSOCKET_H__ -#define __DETECT_WEBSOCKET_H__ - -void DetectWebsocketRegister(void); - -#endif /* __DETECT_WEBSOCKET_H__ */ diff --git a/src/detect.h b/src/detect.h index 52b456318969..29e8c5eaf516 100644 --- a/src/detect.h +++ b/src/detect.h @@ -1019,8 +1019,8 @@ typedef struct DetectEngineCtx_ { /** per keyword flag indicating if a prefilter has been * set for it. If true, the setup function will have to * run. */ - bool sm_types_prefilter[DETECT_TBLSIZE]; - bool sm_types_silent_error[DETECT_TBLSIZE]; + bool *sm_types_prefilter; + bool *sm_types_silent_error; /* classification config parsing */ @@ -1552,7 +1552,7 @@ typedef struct DetectEngineMasterCtx_ { } DetectEngineMasterCtx; /* Table with all SigMatch registrations */ -extern SigTableElmt sigmatch_table[DETECT_TBLSIZE]; +extern SigTableElmt *sigmatch_table; /** Remember to add the options in SignatureIsIPOnly() at detect.c otherwise it wont be part of a signature group */ diff --git a/src/suricata.c b/src/suricata.c index 6d316771f9a0..abad2ca45fa5 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -394,6 +394,7 @@ void GlobalsDestroy(void) FeatureTrackingRelease(); SCProtoNameRelease(); TimeDeinit(); + SigTableCleanup(); TmqhCleanup(); TmModuleRunDeInit(); ParseSizeDeinit(); diff --git a/src/tests/detect-snmp-pdu_type.c b/src/tests/detect-snmp-pdu_type.c deleted file mode 100644 index 0e7693bcc625..000000000000 --- a/src/tests/detect-snmp-pdu_type.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (C) 2019 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. - */ - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -/** - * \test This is a test for a valid value 2. - * - * \retval 1 on success. - * \retval 0 on failure. - */ -static int SNMPValidityTestParse01 (void) -{ - DetectSNMPPduTypeData *dd = NULL; - dd = DetectSNMPPduTypeParse("2"); - FAIL_IF_NULL(dd); - FAIL_IF_NOT(dd->pdu_type == 2); - DetectSNMPPduTypeFree(NULL, dd); - PASS; -} - -static void DetectSNMPPduTypeRegisterTests(void) -{ - UtRegisterTest("SNMPValidityTestParse01", SNMPValidityTestParse01); -} diff --git a/src/tests/detect-snmp-version.c b/src/tests/detect-snmp-version.c deleted file mode 100644 index 5da24b1b8700..000000000000 --- a/src/tests/detect-snmp-version.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (C) 2019 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. - */ - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -/** - * \test This is a test for a valid value 2. - * - * \retval 1 on success. - * \retval 0 on failure. - */ -static int SNMPValidityTestParse01 (void) -{ - DetectU32Data *dd = NULL; - dd = DetectSNMPVersionParse("2"); - FAIL_IF_NULL(dd); - FAIL_IF_NOT(dd->arg1 == 2 && dd->mode == DETECT_UINT_EQ); - DetectSNMPVersionFree(NULL, dd); - PASS; -} - -/** - * \test This is a test for a valid value >2. - * - * \retval 1 on success. - * \retval 0 on failure. - */ -static int SNMPValidityTestParse02 (void) -{ - DetectU32Data *dd = NULL; - dd = DetectSNMPVersionParse(">2"); - FAIL_IF_NULL(dd); - FAIL_IF_NOT(dd->arg1 == 2 && dd->mode == DETECT_UINT_GT); - DetectSNMPVersionFree(NULL, dd); - PASS; -} - -static void DetectSNMPVersionRegisterTests(void) -{ - UtRegisterTest("SNMPValidityTestParse01", SNMPValidityTestParse01); - UtRegisterTest("SNMPValidityTestParse02", SNMPValidityTestParse02); -}