mqtt/detect: mqtt.type can now use index

Ticket: 7480
pull/13878/head
Philippe Antoine 1 year ago committed by Victor Julien
parent dad424d74a
commit 9fc407fd75

@ -48,6 +48,8 @@ where ``UNASSIGNED`` refers to message type code 0.
mqtt.type uses an :ref:`unsigned 8-bits integer <rules-integer-keywords>`. mqtt.type uses an :ref:`unsigned 8-bits integer <rules-integer-keywords>`.
mqtt.type is also a :ref:`multi-integer <multi-integers>`.
Examples:: Examples::
mqtt.type:CONNECT; mqtt.type:CONNECT;

@ -19,8 +19,8 @@
use crate::core::{STREAM_TOCLIENT, STREAM_TOSERVER}; use crate::core::{STREAM_TOCLIENT, STREAM_TOSERVER};
use crate::detect::uint::{ use crate::detect::uint::{
detect_match_uint, detect_parse_uint, detect_parse_uint_enum, DetectUintData, DetectUintMode, detect_match_uint, detect_parse_array_uint_enum, detect_parse_uint, detect_uint_match_at_index,
SCDetectU8Free, SCDetectU8Parse, DetectUintArrayData, DetectUintData, DetectUintMode, SCDetectU8Free, SCDetectU8Parse,
}; };
use crate::detect::{helper_keyword_register_sticky_buffer, SigTableElmtStickyBuffer}; use crate::detect::{helper_keyword_register_sticky_buffer, SigTableElmtStickyBuffer};
use suricata_sys::sys::{ use suricata_sys::sys::{
@ -38,19 +38,16 @@ use nom7::IResult;
use super::mqtt::{MQTTState, MQTTTransaction, ALPROTO_MQTT}; use super::mqtt::{MQTTState, MQTTTransaction, ALPROTO_MQTT};
use crate::conf::conf_get; use crate::conf::conf_get;
use crate::mqtt::mqtt_message::{MQTTOperation, MQTTTypeCode}; use crate::mqtt::mqtt_message::{MQTTMessage, MQTTOperation, MQTTTypeCode};
use std::ffi::CStr; use std::ffi::CStr;
use std::os::raw::{c_int, c_void}; use std::os::raw::{c_int, c_void};
use std::ptr; use std::ptr;
use std::str::FromStr; use std::str::FromStr;
fn mqtt_tx_has_type(tx: &MQTTTransaction, mtype: &DetectUintData<u8>) -> c_int { fn mqtt_tx_has_type(tx: &MQTTTransaction, ctx: &DetectUintArrayData<u8>) -> c_int {
for msg in tx.msg.iter() { return detect_uint_match_at_index::<MQTTMessage, u8>(&tx.msg, ctx, |msg| {
if detect_match_uint(mtype, msg.header.message_type as u8) { Some(msg.header.message_type as u8)
return 1; });
}
}
return 0;
} }
unsafe extern "C" fn mqtt_conn_clientid_get_data( unsafe extern "C" fn mqtt_conn_clientid_get_data(
@ -382,10 +379,12 @@ unsafe extern "C" fn sub_topic_setup(
return 0; return 0;
} }
unsafe extern "C" fn mqtt_parse_type(ustr: *const std::os::raw::c_char) -> *mut DetectUintData<u8> { unsafe extern "C" fn mqtt_parse_type(
ustr: *const std::os::raw::c_char,
) -> *mut DetectUintArrayData<u8> {
let ft_name: &CStr = CStr::from_ptr(ustr); //unsafe let ft_name: &CStr = CStr::from_ptr(ustr); //unsafe
if let Ok(s) = ft_name.to_str() { if let Ok(s) = ft_name.to_str() {
if let Some(ctx) = detect_parse_uint_enum::<u8, MQTTTypeCode>(s) { if let Some(ctx) = detect_parse_array_uint_enum::<u8, MQTTTypeCode>(s) {
let boxed = Box::new(ctx); let boxed = Box::new(ctx);
return Box::into_raw(boxed) as *mut _; return Box::into_raw(boxed) as *mut _;
} }
@ -423,14 +422,14 @@ unsafe extern "C" fn mqtt_type_match(
tx: *mut c_void, _sig: *const Signature, ctx: *const SigMatchCtx, tx: *mut c_void, _sig: *const Signature, ctx: *const SigMatchCtx,
) -> c_int { ) -> c_int {
let tx = cast_pointer!(tx, MQTTTransaction); let tx = cast_pointer!(tx, MQTTTransaction);
let ctx = cast_pointer!(ctx, DetectUintData<u8>); let ctx = cast_pointer!(ctx, DetectUintArrayData<u8>);
return mqtt_tx_has_type(tx, ctx); return mqtt_tx_has_type(tx, ctx);
} }
unsafe extern "C" fn mqtt_type_free(_de: *mut DetectEngineCtx, ctx: *mut c_void) { unsafe extern "C" fn mqtt_type_free(_de: *mut DetectEngineCtx, ctx: *mut c_void) {
// Just unbox... // Just unbox...
let ctx = cast_pointer!(ctx, DetectUintData<u8>); let ctx = cast_pointer!(ctx, DetectUintArrayData<u8>);
SCDetectU8Free(ctx); std::mem::drop(Box::from_raw(ctx));
} }
unsafe extern "C" fn mqtt_reason_code_setup( unsafe extern "C" fn mqtt_reason_code_setup(
@ -1324,19 +1323,19 @@ mod test {
#[test] #[test]
fn mqtt_type_test_parse() { fn mqtt_type_test_parse() {
let ctx = detect_parse_uint_enum::<u8, MQTTTypeCode>("CONNECT").unwrap(); let ctx = detect_parse_array_uint_enum::<u8, MQTTTypeCode>("CONNECT").unwrap();
assert_eq!(ctx.arg1, 1); assert_eq!(ctx.du.arg1, 1);
assert_eq!(ctx.mode, DetectUintMode::DetectUintModeEqual); assert_eq!(ctx.du.mode, DetectUintMode::DetectUintModeEqual);
let ctx = detect_parse_uint_enum::<u8, MQTTTypeCode>("PINGRESP").unwrap(); let ctx = detect_parse_array_uint_enum::<u8, MQTTTypeCode>("PINGRESP").unwrap();
assert_eq!(ctx.arg1, 13); assert_eq!(ctx.du.arg1, 13);
assert_eq!(ctx.mode, DetectUintMode::DetectUintModeEqual); assert_eq!(ctx.du.mode, DetectUintMode::DetectUintModeEqual);
let ctx = detect_parse_uint_enum::<u8, MQTTTypeCode>("auth").unwrap(); let ctx = detect_parse_array_uint_enum::<u8, MQTTTypeCode>("auth").unwrap();
assert_eq!(ctx.arg1, 15); assert_eq!(ctx.du.arg1, 15);
assert_eq!(ctx.mode, DetectUintMode::DetectUintModeEqual); assert_eq!(ctx.du.mode, DetectUintMode::DetectUintModeEqual);
assert!(detect_parse_uint_enum::<u8, MQTTTypeCode>("invalidopt").is_none()); assert!(detect_parse_array_uint_enum::<u8, MQTTTypeCode>("invalidopt").is_none());
let ctx = detect_parse_uint_enum::<u8, MQTTTypeCode>("unassigned").unwrap(); let ctx = detect_parse_array_uint_enum::<u8, MQTTTypeCode>("unassigned").unwrap();
assert_eq!(ctx.arg1, 0); assert_eq!(ctx.du.arg1, 0);
assert_eq!(ctx.mode, DetectUintMode::DetectUintModeEqual); assert_eq!(ctx.du.mode, DetectUintMode::DetectUintModeEqual);
} }
#[test] #[test]

Loading…
Cancel
Save