rust/detect: generic detect_uint_match_at_index

and make ldap use it

Ticket: 7480

No behavior change, just code restyling
pull/13878/head
Philippe Antoine 1 year ago committed by Victor Julien
parent 7effcb7835
commit d8c1f8e7be

@ -25,7 +25,7 @@ use nom7::IResult;
use super::EnumString; use super::EnumString;
use std::ffi::CStr; use std::ffi::{c_int, CStr};
use std::str::FromStr; use std::str::FromStr;
#[derive(PartialEq, Eq, Clone, Debug)] #[derive(PartialEq, Eq, Clone, Debug)]
@ -94,6 +94,48 @@ pub(crate) fn detect_parse_array_uint_enum<T1: DetectIntType, T2: EnumString<T1>
Some(DetectUintArrayData { du, index }) Some(DetectUintArrayData { du, index })
} }
pub(crate) fn detect_uint_match_at_index<T, U: DetectIntType>(
array: &[T], ctx: &DetectUintArrayData<U>, get_value: impl Fn(&T) -> Option<U>,
) -> c_int {
match ctx.index {
DetectUintIndex::Any => {
for response in array {
if let Some(code) = get_value(response) {
if detect_match_uint::<U>(&ctx.du, code) {
return 1;
}
}
}
return 0;
}
DetectUintIndex::All => {
for response in array {
if let Some(code) = get_value(response) {
if !detect_match_uint::<U>(&ctx.du, code) {
return 0;
}
}
}
return 1;
}
DetectUintIndex::Index(idx) => {
let index = if idx < 0 {
// negative values for backward indexing.
((array.len() as i32) + idx) as usize
} else {
idx as usize
};
if array.len() <= index {
return 0;
}
if let Some(code) = get_value(&array[index]) {
return detect_match_uint::<U>(&ctx.du, code) as c_int;
}
return 0;
}
}
}
/// Parses a string for detection with integers, using enumeration strings /// Parses a string for detection with integers, using enumeration strings
/// ///
/// Needs to specify T1 the integer type (like u8) /// Needs to specify T1 the integer type (like u8)

@ -18,8 +18,9 @@
use super::ldap::{LdapTransaction, ALPROTO_LDAP}; use super::ldap::{LdapTransaction, ALPROTO_LDAP};
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_array_uint_enum, detect_parse_uint_enum, DetectUintArrayData, detect_match_uint, detect_parse_array_uint_enum, detect_parse_uint_enum,
DetectUintData, DetectUintIndex, SCDetectU32Free, SCDetectU32Parse, SCDetectU8Free, detect_uint_match_at_index, DetectUintArrayData, DetectUintData, SCDetectU32Free,
SCDetectU32Parse, SCDetectU8Free,
}; };
use crate::detect::{helper_keyword_register_sticky_buffer, SigTableElmtStickyBuffer}; use crate::detect::{helper_keyword_register_sticky_buffer, SigTableElmtStickyBuffer};
use crate::ldap::types::*; use crate::ldap::types::*;
@ -107,7 +108,7 @@ unsafe extern "C" fn ldap_detect_request_free(_de: *mut DetectEngineCtx, ctx: *m
unsafe extern "C" fn ldap_parse_protocol_resp_op( unsafe extern "C" fn ldap_parse_protocol_resp_op(
ustr: *const std::os::raw::c_char, ustr: *const std::os::raw::c_char,
) -> *mut DetectUintData<u8> { ) -> *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_array_uint_enum::<u8, ProtocolOpCode>(s) { if let Some(ctx) = detect_parse_array_uint_enum::<u8, ProtocolOpCode>(s) {
@ -143,49 +144,6 @@ unsafe extern "C" fn ldap_detect_responses_operation_setup(
return 0; return 0;
} }
fn match_at_index<T, U>(
array: &[T], ctx_value: &DetectUintData<U>, get_value: impl Fn(&T) -> Option<U>,
detect_match: impl Fn(U, &DetectUintData<U>) -> c_int, index: &DetectUintIndex,
) -> c_int {
match index {
DetectUintIndex::Any => {
for response in array {
if let Some(code) = get_value(response) {
if detect_match(code, ctx_value) == 1 {
return 1;
}
}
}
return 0;
}
DetectUintIndex::All => {
for response in array {
if let Some(code) = get_value(response) {
if detect_match(code, ctx_value) == 0 {
return 0;
}
}
}
return 1;
}
DetectUintIndex::Index(idx) => {
let index = if *idx < 0 {
// negative values for backward indexing.
((array.len() as i32) + idx) as usize
} else {
*idx as usize
};
if array.len() <= index {
return 0;
}
if let Some(code) = get_value(&array[index]) {
return detect_match(code, ctx_value);
}
return 0;
}
}
}
unsafe extern "C" fn ldap_detect_responses_operation_match( unsafe extern "C" fn ldap_detect_responses_operation_match(
_de: *mut DetectEngineThreadCtx, _f: *mut Flow, _flags: u8, _state: *mut c_void, _de: *mut DetectEngineThreadCtx, _f: *mut Flow, _flags: u8, _state: *mut c_void,
tx: *mut c_void, _sig: *const Signature, ctx: *const SigMatchCtx, tx: *mut c_void, _sig: *const Signature, ctx: *const SigMatchCtx,
@ -193,13 +151,9 @@ unsafe extern "C" fn ldap_detect_responses_operation_match(
let tx = cast_pointer!(tx, LdapTransaction); let tx = cast_pointer!(tx, LdapTransaction);
let ctx = cast_pointer!(ctx, DetectUintArrayData<u8>); let ctx = cast_pointer!(ctx, DetectUintArrayData<u8>);
return match_at_index::<LdapMessage, u8>( return detect_uint_match_at_index::<LdapMessage, u8>(&tx.responses, ctx, |response| {
&tx.responses, Some(response.protocol_op.tag().0 as u8)
&ctx.du, });
|response| Some(response.protocol_op.tag().0 as u8),
|code, ctx_value| detect_match_uint(ctx_value, code) as c_int,
&ctx.index,
);
} }
unsafe extern "C" fn ldap_detect_responses_free(_de: *mut DetectEngineCtx, ctx: *mut c_void) { unsafe extern "C" fn ldap_detect_responses_free(_de: *mut DetectEngineCtx, ctx: *mut c_void) {
@ -335,7 +289,7 @@ unsafe extern "C" fn ldap_tx_get_responses_dn(
unsafe extern "C" fn ldap_parse_responses_result_code( unsafe extern "C" fn ldap_parse_responses_result_code(
ustr: *const std::os::raw::c_char, ustr: *const std::os::raw::c_char,
) -> *mut DetectUintData<u32> { ) -> *mut DetectUintArrayData<u32> {
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_array_uint_enum::<u32, LdapResultCode>(s) { if let Some(ctx) = detect_parse_array_uint_enum::<u32, LdapResultCode>(s) {
@ -392,12 +346,10 @@ unsafe extern "C" fn ldap_detect_responses_result_code_match(
let tx = cast_pointer!(tx, LdapTransaction); let tx = cast_pointer!(tx, LdapTransaction);
let ctx = cast_pointer!(ctx, DetectUintArrayData<u32>); let ctx = cast_pointer!(ctx, DetectUintArrayData<u32>);
return match_at_index::<LdapMessage, u32>( return detect_uint_match_at_index::<LdapMessage, u32>(
&tx.responses, &tx.responses,
&ctx.du, ctx,
get_ldap_result_code, get_ldap_result_code,
|code, ctx_value| detect_match_uint(ctx_value, code) as c_int,
&ctx.index,
); );
} }

Loading…
Cancel
Save