From: Philippe Antoine Date: Wed, 2 Oct 2024 19:41:06 +0000 (+0200) Subject: transforms: move dotprefix to rust X-Git-Tag: suricata-8.0.0-beta1~732 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=71da38e7020969664ddf9664fd3c8802e2757340;p=thirdparty%2Fsuricata.git transforms: move dotprefix to rust Ticket: 7229 --- diff --git a/rust/src/detect/transforms/dotprefix.rs b/rust/src/detect/transforms/dotprefix.rs new file mode 100644 index 0000000000..eef6d048bd --- /dev/null +++ b/rust/src/detect/transforms/dotprefix.rs @@ -0,0 +1,97 @@ +/* Copyright (C) 2024 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use super::{ + DetectHelperTransformRegister, DetectSignatureAddTransform, InspectionBufferCheckAndExpand, + InspectionBufferLength, InspectionBufferPtr, InspectionBufferTruncate, SCTransformTableElmt, +}; +use crate::detect::SIGMATCH_NOOPT; + +use std::os::raw::{c_int, c_void}; +use std::ptr; + +static mut G_TRANSFORM_DOT_PREFIX_ID: c_int = 0; + +#[no_mangle] +unsafe extern "C" fn dot_prefix_setup( + _de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, +) -> c_int { + return DetectSignatureAddTransform(s, G_TRANSFORM_DOT_PREFIX_ID, ptr::null_mut()); +} + +fn dot_prefix_transform_do(input: &[u8], output: &mut [u8]) { + output[0] = b'.'; + output[1..].copy_from_slice(input); +} + +#[no_mangle] +unsafe extern "C" fn dot_prefix_transform(buffer: *mut c_void, _ctx: *mut c_void) { + let input = InspectionBufferPtr(buffer); + let input_len = InspectionBufferLength(buffer); + if input.is_null() || input_len == 0 { + return; + } + let input = build_slice!(input, input_len as usize); + + let output = InspectionBufferCheckAndExpand(buffer, input_len + 1); + if output.is_null() { + // allocation failure + return; + } + let output = std::slice::from_raw_parts_mut(output, (input_len + 1) as usize); + + dot_prefix_transform_do(input, output); + + InspectionBufferTruncate(buffer, input_len + 1); +} + +#[no_mangle] +pub unsafe extern "C" fn DetectTransformDotPrefixRegister() { + let kw = SCTransformTableElmt { + name: b"dotprefix\0".as_ptr() as *const libc::c_char, + desc: b"modify buffer to extract the dotprefix\0".as_ptr() as *const libc::c_char, + url: b"/rules/transforms.html#dotprefix\0".as_ptr() as *const libc::c_char, + Setup: dot_prefix_setup, + flags: SIGMATCH_NOOPT, + Transform: dot_prefix_transform, + Free: None, + TransformValidate: None, + }; + unsafe { + G_TRANSFORM_DOT_PREFIX_ID = DetectHelperTransformRegister(&kw); + if G_TRANSFORM_DOT_PREFIX_ID < 0 { + SCLogWarning!("Failed registering transform dot_prefix"); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_dot_prefix_transform() { + let buf = b"example.com"; + let mut out = vec![0; b"example.com".len() + 1]; + dot_prefix_transform_do(buf, &mut out); + assert_eq!(out, b".example.com"); + let buf = b"hello.example.com"; + let mut out = vec![0; b"hello.example.com".len() + 1]; + dot_prefix_transform_do(buf, &mut out); + assert_eq!(out, b".hello.example.com"); + } +} diff --git a/rust/src/detect/transforms/mod.rs b/rust/src/detect/transforms/mod.rs index 99c929a9df..120a8ff54e 100644 --- a/rust/src/detect/transforms/mod.rs +++ b/rust/src/detect/transforms/mod.rs @@ -20,6 +20,7 @@ use std::os::raw::{c_char, c_int, c_void}; pub mod compress_whitespace; +pub mod dotprefix; pub mod strip_whitespace; #[repr(C)] diff --git a/src/Makefile.am b/src/Makefile.am index c6a52f3643..bb86a0cde1 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -307,7 +307,6 @@ noinst_HEADERS = \ detect-tos.h \ detect-transform-base64.h \ detect-transform-casechange.h \ - detect-transform-dotprefix.h \ detect-transform-header-lowercase.h \ detect-transform-md5.h \ detect-transform-pcrexform.h \ @@ -874,7 +873,6 @@ libsuricata_c_a_SOURCES = \ detect-tos.c \ detect-transform-base64.c \ detect-transform-casechange.c \ - detect-transform-dotprefix.c \ detect-transform-header-lowercase.c \ detect-transform-md5.c \ detect-transform-pcrexform.c \ diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index ec5d5c26c0..e6ef73e7f8 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -219,7 +219,6 @@ #include "detect-transform-md5.h" #include "detect-transform-sha1.h" #include "detect-transform-sha256.h" -#include "detect-transform-dotprefix.h" #include "detect-transform-pcrexform.h" #include "detect-transform-urldecode.h" #include "detect-transform-xor.h" diff --git a/src/detect-transform-dotprefix.c b/src/detect-transform-dotprefix.c deleted file mode 100644 index 52a263372b..0000000000 --- a/src/detect-transform-dotprefix.c +++ /dev/null @@ -1,186 +0,0 @@ -/* Copyright (C) 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 Jeff Lucovsky - * - * Implements the dotprefix transformation - */ - -#include "suricata-common.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-prefilter.h" -#include "detect-parse.h" -#include "detect-transform-dotprefix.h" -#include "detect-engine-build.h" - -#include "util-unittest.h" -#include "util-print.h" -#include "util-memrchr.h" -#include "util-memcpy.h" - -static int DetectTransformDotPrefixSetup (DetectEngineCtx *, Signature *, const char *); -#ifdef UNITTESTS -static void DetectTransformDotPrefixRegisterTests(void); -#endif -static void TransformDotPrefix(InspectionBuffer *buffer, void *options); - -void DetectTransformDotPrefixRegister(void) -{ - sigmatch_table[DETECT_TRANSFORM_DOTPREFIX].name = "dotprefix"; - sigmatch_table[DETECT_TRANSFORM_DOTPREFIX].desc = - "modify buffer to extract the dotprefix"; - sigmatch_table[DETECT_TRANSFORM_DOTPREFIX].url = - "/rules/transforms.html#dotprefix"; - sigmatch_table[DETECT_TRANSFORM_DOTPREFIX].Transform = TransformDotPrefix; - sigmatch_table[DETECT_TRANSFORM_DOTPREFIX].Setup = DetectTransformDotPrefixSetup; -#ifdef UNITTESTS - sigmatch_table[DETECT_TRANSFORM_DOTPREFIX].RegisterTests = - DetectTransformDotPrefixRegisterTests; -#endif - sigmatch_table[DETECT_TRANSFORM_DOTPREFIX].flags |= SIGMATCH_NOOPT; -} - -/** - * \internal - * \brief Extract the dotprefix, if any, the last pattern match, either content or uricontent - * \param det_ctx detection engine ctx - * \param s signature - * \param nullstr should be null - * \retval 0 ok - * \retval -1 failure - */ -static int DetectTransformDotPrefixSetup (DetectEngineCtx *de_ctx, Signature *s, const char *nullstr) -{ - SCEnter(); - int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_DOTPREFIX, NULL); - SCReturnInt(r); -} - -/** - * \brief Return the dotprefix, if any, in the last pattern match. - * - * Input values are modified by prefixing with a ".". - * - * Rule: "alert dns any any -> any any (dns_query; dotprefix; content:".google.com"; sid:1;)" - * 1. hello.google.com --> match - * 2. hey.agoogle.com --> no match - * 3. agoogle.com --> no match - * 4. something.google.com.au --> match - * 5. google.com --> match - * - * To match on the dotprefix only: - * Rule: "alert dns any any -> any any (dns_query; dotprefix; content:".google.com"; endswith; sid:1;)" - * - * 1. hello.google.com --> match - * 2. hey.agoogle.com --> no match - * 3. agoogle.com --> no match - * 4. something.google.com.au --> no match - * 5. google.com --> match - * - * To match on a TLD: - * Rule: "alert dns any any -> any any (dns_query; dotprefix; content:".co.uk"; endswith; sid:1;)" - * - * 1. hello.google.com --> no match - * 2. hey.agoogle.com --> no match - * 3. agoogle.com --> no match - * 4. something.google.co.uk --> match - * 5. google.com --> no match - */ -static void TransformDotPrefix(InspectionBuffer *buffer, void *options) -{ - const size_t input_len = buffer->inspect_len; - - if (input_len) { - uint8_t output[input_len + 1]; // For the leading '.' - - output[0] = '.'; - memcpy(&output[1], buffer->inspect, input_len); - InspectionBufferCopy(buffer, output, input_len + 1); - } -} - -#ifdef UNITTESTS -static int DetectTransformDotPrefixTest01(void) -{ - const uint8_t *input = (const uint8_t *)"example.com"; - uint32_t input_len = strlen((char *)input); - - const char *result = ".example.com"; - uint32_t result_len = strlen((char *)result); - - InspectionBuffer buffer; - InspectionBufferInit(&buffer, input_len); - InspectionBufferSetup(NULL, -1, &buffer, input, input_len); - PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); - TransformDotPrefix(&buffer, NULL); - PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); - FAIL_IF_NOT(buffer.inspect_len == result_len); - FAIL_IF_NOT(strncmp(result, (const char *)buffer.inspect, result_len) == 0); - InspectionBufferFree(&buffer); - PASS; -} - -static int DetectTransformDotPrefixTest02(void) -{ - const uint8_t *input = (const uint8_t *)"hello.example.com"; - uint32_t input_len = strlen((char *)input); - - const char *result = ".hello.example.com"; - uint32_t result_len = strlen((char *)result); - - InspectionBuffer buffer; - InspectionBufferInit(&buffer, input_len); - InspectionBufferSetup(NULL, -1, &buffer, input, input_len); - PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); - TransformDotPrefix(&buffer, NULL); - PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len); - FAIL_IF_NOT(buffer.inspect_len == result_len); - FAIL_IF_NOT(strncmp(result, (const char *)buffer.inspect, result_len) == 0); - InspectionBufferFree(&buffer); - PASS; -} - -static int DetectTransformDotPrefixTest03(void) -{ - const char rule[] = "alert dns any any -> any any (dns.query; dotprefix; content:\".google.com\"; sid:1;)"; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - memset(&th_v, 0, sizeof(th_v)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - FAIL_IF_NULL(de_ctx); - Signature *s = DetectEngineAppendSig(de_ctx, rule); - FAIL_IF_NULL(s); - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - PASS; -} - -static void DetectTransformDotPrefixRegisterTests(void) -{ - UtRegisterTest("DetectTransformDotPrefixTest01", DetectTransformDotPrefixTest01); - UtRegisterTest("DetectTransformDotPrefixTest02", DetectTransformDotPrefixTest02); - UtRegisterTest("DetectTransformDotPrefixTest03", DetectTransformDotPrefixTest03); -} -#endif diff --git a/src/detect-transform-dotprefix.h b/src/detect-transform-dotprefix.h deleted file mode 100644 index 2062055d8d..0000000000 --- a/src/detect-transform-dotprefix.h +++ /dev/null @@ -1,30 +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. - */ - -/** - * \file - * - * \author Jeff Lucovsky - */ - -#ifndef SURICATA_DETECT_TRANSFORM_DOTPREFIX_H -#define SURICATA_DETECT_TRANSFORM_DOTPREFIX_H - -/* prototypes */ -void DetectTransformDotPrefixRegister (void); - -#endif /* SURICATA_DETECT_TRANSFORM_DOTPREFIX_H */