From 907e71a984ee41aae6fefe3ff700cab5cf1d2948 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Thu, 29 Jan 2026 21:49:34 +0100 Subject: [PATCH] detect/quic: move quic.version to rust Ticket: 8255 --- rust/src/quic/detect.rs | 53 +++++++++-- rust/src/quic/quic.rs | 2 +- src/Makefile.am | 2 - src/detect-engine-register.c | 3 +- src/detect-engine-register.h | 1 - src/detect-quic-version.c | 172 ----------------------------------- src/detect-quic-version.h | 28 ------ 7 files changed, 47 insertions(+), 214 deletions(-) delete mode 100644 src/detect-quic-version.c delete mode 100644 src/detect-quic-version.h diff --git a/rust/src/quic/detect.rs b/rust/src/quic/detect.rs index 4d23603e95..98d6912791 100644 --- a/rust/src/quic/detect.rs +++ b/rust/src/quic/detect.rs @@ -15,11 +15,16 @@ * 02110-1301, USA. */ +use super::quic::ALPROTO_QUIC; use crate::core::{STREAM_TOCLIENT, STREAM_TOSERVER}; +use crate::detect::{helper_keyword_register_sticky_buffer, SigTableElmtStickyBuffer}; use crate::quic::quic::QuicTransaction; -use std::os::raw::c_void; +use std::os::raw::{c_int, c_void}; use std::ptr; -use suricata_sys::sys::DetectEngineThreadCtx; +use suricata_sys::sys::{ + DetectEngineCtx, DetectEngineThreadCtx, SCDetectBufferSetActiveList, + SCDetectHelperBufferMpmRegister, SCDetectSignatureSetAppProto, Signature, +}; #[no_mangle] pub unsafe extern "C" fn SCQuicTxGetUa( @@ -85,19 +90,19 @@ pub unsafe extern "C" fn SCQuicTxGetJa4( } } -#[no_mangle] -pub unsafe extern "C" fn SCQuicTxGetVersion( - tx: &QuicTransaction, buffer: *mut *const u8, buffer_len: *mut u32, -) -> u8 { +unsafe extern "C" fn quic_tx_get_version( + tx: *const c_void, _flags: u8, buffer: *mut *const u8, buffer_len: *mut u32, +) -> bool { + let tx = cast_pointer!(tx, QuicTransaction); if tx.header.flags.is_long { let s = &tx.header.version_buf; *buffer = s.as_ptr(); *buffer_len = s.len() as u32; - 1 + true } else { *buffer = ptr::null(); *buffer_len = 0; - 0 + false } } @@ -145,3 +150,35 @@ pub unsafe extern "C" fn SCQuicTxGetCyuString( false } } + +unsafe extern "C" fn quic_version_setup( + de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char, +) -> c_int { + if SCDetectSignatureSetAppProto(s, ALPROTO_QUIC) != 0 { + return -1; + } + if SCDetectBufferSetActiveList(de, s, G_QUIC_VERSION_BUFFER_ID) < 0 { + return -1; + } + return 0; +} + +static mut G_QUIC_VERSION_BUFFER_ID: c_int = 0; + +#[no_mangle] +pub unsafe extern "C" fn SCDetectQuicRegister() { + let kw = SigTableElmtStickyBuffer { + name: String::from("quic.version"), + desc: String::from("match Quic version"), + url: String::from("/rules/quic-keywords.html#quic-version"), + setup: quic_version_setup, + }; + helper_keyword_register_sticky_buffer(&kw); + G_QUIC_VERSION_BUFFER_ID = SCDetectHelperBufferMpmRegister( + b"quic_version\0".as_ptr() as *const libc::c_char, + b"quic version\0".as_ptr() as *const libc::c_char, + ALPROTO_QUIC, + STREAM_TOSERVER | STREAM_TOCLIENT, + Some(quic_tx_get_version), + ); +} diff --git a/rust/src/quic/quic.rs b/rust/src/quic/quic.rs index c26a967814..a94c485ec6 100644 --- a/rust/src/quic/quic.rs +++ b/rust/src/quic/quic.rs @@ -43,7 +43,7 @@ use suricata_sys::sys::{ }; use tls_parser::TlsExtensionType; -static mut ALPROTO_QUIC: AppProto = ALPROTO_UNKNOWN; +pub(super) static mut ALPROTO_QUIC: AppProto = ALPROTO_UNKNOWN; static mut ENCRYPTION_BYPASS_ENABLED: EncryptionHandling = EncryptionHandling::ENCRYPTION_HANDLING_TRACK_ONLY; diff --git a/src/Makefile.am b/src/Makefile.am index e8f1553df5..f1dcac47d3 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -268,7 +268,6 @@ noinst_HEADERS = \ detect-quic-cyu-string.h \ detect-quic-sni.h \ detect-quic-ua.h \ - detect-quic-version.h \ detect-rawbytes.h \ detect-reference.h \ detect-replace.h \ @@ -860,7 +859,6 @@ libsuricata_c_a_SOURCES = \ detect-quic-cyu-string.c \ detect-quic-sni.c \ detect-quic-ua.c \ - detect-quic-version.c \ detect-rawbytes.c \ detect-reference.c \ detect-replace.c \ diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index 97693e96e4..55fafc7f1a 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -205,7 +205,6 @@ #include "detect-target.h" #include "detect-quic-sni.h" #include "detect-quic-ua.h" -#include "detect-quic-version.h" #include "detect-quic-cyu-hash.h" #include "detect-quic-cyu-string.h" #include "detect-ja4-hash.h" @@ -737,7 +736,6 @@ void SigTableSetup(void) DetectTargetRegister(); DetectQuicSniRegister(); DetectQuicUaRegister(); - DetectQuicVersionRegister(); DetectQuicCyuHashRegister(); DetectQuicCyuStringRegister(); DetectJa4HashRegister(); @@ -788,6 +786,7 @@ void SigTableSetup(void) SCDetectDNSRegister(); SCDetectPgsqlRegister(); SCDetectSshRegister(); + SCDetectQuicRegister(); for (size_t i = 0; i < preregistered_callbacks_nb; i++) { PreregisteredCallbacks[i](); diff --git a/src/detect-engine-register.h b/src/detect-engine-register.h index b6694074a2..8cbd2bc641 100644 --- a/src/detect-engine-register.h +++ b/src/detect-engine-register.h @@ -283,7 +283,6 @@ enum DetectKeywordId { DETECT_TCP_WSCALE, DETECT_FTPDATA, DETECT_TARGET, - DETECT_QUIC_VERSION, DETECT_QUIC_SNI, DETECT_QUIC_UA, DETECT_QUIC_CYU_HASH, diff --git a/src/detect-quic-version.c b/src/detect-quic-version.c deleted file mode 100644 index 5b3076c1b3..0000000000 --- a/src/detect-quic-version.c +++ /dev/null @@ -1,172 +0,0 @@ -/* Copyright (C) 2021 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. - */ - -/** - * - * Implements the quic.version - */ - -#include "suricata-common.h" -#include "conf.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-buffer.h" -#include "detect-engine-prefilter.h" -#include "detect-engine-mpm.h" -#include "detect-engine-content-inspection.h" -#include "detect-engine-uint.h" -#include "detect-quic-version.h" -#include "util-byte.h" -#include "util-unittest.h" -#include "rust.h" - -#ifdef UNITTESTS -static void DetectQuicVersionRegisterTests(void); -#endif - -#define BUFFER_NAME "quic_version" -#define KEYWORD_NAME "quic.version" - -static int quic_version_id = 0; - -static int DetectQuicVersionSetup(DetectEngineCtx *, Signature *, const char *); - -static InspectionBuffer *GetVersionData(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 b_len = 0; - const uint8_t *b = NULL; - - if (SCQuicTxGetVersion(txv, &b, &b_len) != 1) - return NULL; - if (b == NULL || b_len == 0) - return NULL; - - InspectionBufferSetupAndApplyTransforms(det_ctx, list_id, buffer, b, b_len, transforms); - } - return buffer; -} - -/** - * \brief Registration function for quic.version: keyword - */ -void DetectQuicVersionRegister(void) -{ - sigmatch_table[DETECT_QUIC_VERSION].name = KEYWORD_NAME; - sigmatch_table[DETECT_QUIC_VERSION].desc = "match Quic version"; - sigmatch_table[DETECT_QUIC_VERSION].url = "/rules/quic-keywords.html#quic-version"; - sigmatch_table[DETECT_QUIC_VERSION].Setup = DetectQuicVersionSetup; - sigmatch_table[DETECT_QUIC_VERSION].flags |= SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER; -#ifdef UNITTESTS - sigmatch_table[DETECT_QUIC_VERSION].RegisterTests = DetectQuicVersionRegisterTests; -#endif - - DetectAppLayerMpmRegister(BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister, - GetVersionData, ALPROTO_QUIC, 1); - DetectAppLayerMpmRegister(BUFFER_NAME, SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister, - GetVersionData, ALPROTO_QUIC, 1); - - DetectAppLayerInspectEngineRegister(BUFFER_NAME, ALPROTO_QUIC, SIG_FLAG_TOSERVER, 1, - DetectEngineInspectBufferGeneric, GetVersionData); - DetectAppLayerInspectEngineRegister(BUFFER_NAME, ALPROTO_QUIC, SIG_FLAG_TOCLIENT, 1, - DetectEngineInspectBufferGeneric, GetVersionData); - - quic_version_id = DetectBufferTypeGetByName(BUFFER_NAME); -} - -/** - * \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 DetectQuicVersionSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr) -{ - if (SCDetectBufferSetActiveList(de_ctx, s, quic_version_id) < 0) - return -1; - - if (SCDetectSignatureSetAppProto(s, ALPROTO_QUIC) < 0) - return -1; - - return 0; -} - -#ifdef UNITTESTS - -/** - * \test QuicVersionTestParse01 is a test for a valid value - * - * \retval 1 on success - * \retval 0 on failure - */ -static int QuicVersionTestParse01(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - FAIL_IF_NULL(de_ctx); - - Signature *sig = DetectEngineAppendSig( - de_ctx, "alert ip any any -> any any (quic.version; content:\"Q046\"; sid:1; rev:1;)"); - FAIL_IF_NULL(sig); - - sig = DetectEngineAppendSig( - de_ctx, "alert ip any any -> any any (quic.version; content:\"|00|\"; sid:2; rev:1;)"); - FAIL_IF_NULL(sig); - - DetectEngineCtxFree(de_ctx); - - PASS; -} - -/** - * \test QuicVersionTestParse03 is a test for an invalid value - * - * \retval 1 on success - * \retval 0 on failure - */ -static int QuicVersionTestParse03(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - FAIL_IF_NULL(de_ctx); - - Signature *sig = DetectEngineAppendSig( - de_ctx, "alert ip any any -> any any (quic.version:; sid:1; rev:1;)"); - FAIL_IF_NOT_NULL(sig); - - DetectEngineCtxFree(de_ctx); - - PASS; -} - -/** - * \brief this function registers unit tests for QuicVersion - */ -void DetectQuicVersionRegisterTests(void) -{ - UtRegisterTest("QuicVersionTestParse01", QuicVersionTestParse01); - UtRegisterTest("QuicVersionTestParse03", QuicVersionTestParse03); -} - -#endif /* UNITTESTS */ diff --git a/src/detect-quic-version.h b/src/detect-quic-version.h deleted file mode 100644 index 61467d7e08..0000000000 --- a/src/detect-quic-version.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (C) 2021 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 - * - */ - -#ifndef SURICATA_DETECT_QUIC_VERSION_H -#define SURICATA_DETECT_QUIC_VERSION_H - -void DetectQuicVersionRegister(void); - -#endif /* SURICATA_DETECT_QUIC_VERSION_H */