]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
ldap: create a generic funtion to match integer responses
authorAlice Akaki <akakialice@gmail.com>
Thu, 27 Feb 2025 23:38:07 +0000 (19:38 -0400)
committerVictor Julien <victor@inliniac.net>
Wed, 5 Mar 2025 14:59:53 +0000 (15:59 +0100)
rust/src/ldap/detect.rs

index 2c630f83a989fd0a87ea1921c0f050ff86b2a079..fcd84c56111b5054b5f1226c2500f15e78bafedf 100644 (file)
@@ -17,8 +17,8 @@
 
 use super::ldap::{LdapTransaction, ALPROTO_LDAP};
 use crate::detect::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,
+    detect_match_uint, detect_parse_uint_enum, rs_detect_u32_free, rs_detect_u32_parse,
+    rs_detect_u8_free, DetectUintData,
 };
 use crate::detect::{
     DetectBufferSetActiveList, DetectHelperBufferMpmRegister, DetectHelperBufferRegister,
@@ -28,6 +28,7 @@ use crate::detect::{
 };
 use crate::ldap::types::{LdapMessage, ProtocolOp, ProtocolOpCode};
 
+use std::collections::VecDeque;
 use std::ffi::CStr;
 use std::os::raw::{c_int, c_void};
 use std::str::FromStr;
@@ -104,7 +105,7 @@ unsafe extern "C" fn ldap_detect_request_operation_match(
     let ctx = cast_pointer!(ctx, DetectUintData<u8>);
     if let Some(request) = &tx.request {
         let option = request.protocol_op.to_u8();
-        return rs_detect_u8_match(option, ctx);
+        return detect_match_uint(ctx, option) as c_int;
     }
     return 0;
 }
@@ -181,49 +182,65 @@ unsafe extern "C" fn ldap_detect_responses_operation_setup(
     return 0;
 }
 
-unsafe extern "C" fn ldap_detect_responses_operation_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,
+fn match_at_index<T, U>(
+    array: &VecDeque<T>, ctx_value: &DetectUintData<U>, get_value: impl Fn(&T) -> Option<U>,
+    detect_match: impl Fn(U, &DetectUintData<U>) -> c_int, index: &LdapIndex,
 ) -> c_int {
-    let tx = cast_pointer!(tx, LdapTransaction);
-    let ctx = cast_pointer!(ctx, DetectLdapRespOpData);
-
-    match ctx.index {
+    match index {
         LdapIndex::Any => {
-            for response in &tx.responses {
-                let option: u8 = response.protocol_op.to_u8();
-                if rs_detect_u8_match(option, &ctx.du8) == 1 {
-                    return 1;
+            for response in array {
+                if let Some(code) = get_value(response) {
+                    if detect_match(code, ctx_value) == 1 {
+                        return 1;
+                    }
                 }
             }
             return 0;
         }
         LdapIndex::All => {
-            for response in &tx.responses {
-                let option: u8 = response.protocol_op.to_u8();
-                if rs_detect_u8_match(option, &ctx.du8) == 0 {
-                    return 0;
+            for response in array {
+                if let Some(code) = get_value(response) {
+                    if detect_match(code, ctx_value) == 0 {
+                        return 0;
+                    }
                 }
             }
             return 1;
         }
         LdapIndex::Index(idx) => {
-            let index = if idx < 0 {
+            let index = if *idx < 0 {
                 // negative values for backward indexing.
-                ((tx.responses.len() as i32) + idx) as usize
+                ((array.len() as i32) + idx) as usize
             } else {
-                idx as usize
+                *idx as usize
             };
-            if tx.responses.len() <= index {
+            if array.len() <= index {
                 return 0;
             }
-            let response: &LdapMessage = &tx.responses[index];
-            let option: u8 = response.protocol_op.to_u8();
-            return rs_detect_u8_match(option, &ctx.du8);
+            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(
+    _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, LdapTransaction);
+    let ctx = cast_pointer!(ctx, DetectLdapRespOpData);
+
+    return match_at_index::<LdapMessage, u8>(
+        &tx.responses,
+        &ctx.du8,
+        |response| Some(response.protocol_op.to_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 c_void, ctx: *mut c_void) {
     // Just unbox...
     let ctx = cast_pointer!(ctx, DetectLdapRespOpData);
@@ -262,7 +279,7 @@ unsafe extern "C" fn ldap_detect_responses_count_match(
     let tx = cast_pointer!(tx, LdapTransaction);
     let ctx = cast_pointer!(ctx, DetectUintData<u32>);
     let len = tx.responses.len() as u32;
-    return rs_detect_u32_match(len, ctx);
+    return detect_match_uint(ctx, len) as c_int;
 }
 
 unsafe extern "C" fn ldap_detect_responses_count_free(_de: *mut c_void, ctx: *mut c_void) {