detect/quic: move quic.version to rust

Ticket: 8255
pull/14750/head
Philippe Antoine 5 months ago committed by Victor Julien
parent 45a36e961f
commit 907e71a984

@ -15,11 +15,16 @@
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use super::quic::ALPROTO_QUIC;
use crate::core::{STREAM_TOCLIENT, STREAM_TOSERVER}; use crate::core::{STREAM_TOCLIENT, STREAM_TOSERVER};
use crate::detect::{helper_keyword_register_sticky_buffer, SigTableElmtStickyBuffer};
use crate::quic::quic::QuicTransaction; use crate::quic::quic::QuicTransaction;
use std::os::raw::c_void; use std::os::raw::{c_int, c_void};
use std::ptr; use std::ptr;
use suricata_sys::sys::DetectEngineThreadCtx; use suricata_sys::sys::{
DetectEngineCtx, DetectEngineThreadCtx, SCDetectBufferSetActiveList,
SCDetectHelperBufferMpmRegister, SCDetectSignatureSetAppProto, Signature,
};
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn SCQuicTxGetUa( pub unsafe extern "C" fn SCQuicTxGetUa(
@ -85,19 +90,19 @@ pub unsafe extern "C" fn SCQuicTxGetJa4(
} }
} }
#[no_mangle] unsafe extern "C" fn quic_tx_get_version(
pub unsafe extern "C" fn SCQuicTxGetVersion( tx: *const c_void, _flags: u8, buffer: *mut *const u8, buffer_len: *mut u32,
tx: &QuicTransaction, buffer: *mut *const u8, buffer_len: *mut u32, ) -> bool {
) -> u8 { let tx = cast_pointer!(tx, QuicTransaction);
if tx.header.flags.is_long { if tx.header.flags.is_long {
let s = &tx.header.version_buf; let s = &tx.header.version_buf;
*buffer = s.as_ptr(); *buffer = s.as_ptr();
*buffer_len = s.len() as u32; *buffer_len = s.len() as u32;
1 true
} else { } else {
*buffer = ptr::null(); *buffer = ptr::null();
*buffer_len = 0; *buffer_len = 0;
0 false
} }
} }
@ -145,3 +150,35 @@ pub unsafe extern "C" fn SCQuicTxGetCyuString(
false 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),
);
}

@ -43,7 +43,7 @@ use suricata_sys::sys::{
}; };
use tls_parser::TlsExtensionType; 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 = static mut ENCRYPTION_BYPASS_ENABLED: EncryptionHandling =
EncryptionHandling::ENCRYPTION_HANDLING_TRACK_ONLY; EncryptionHandling::ENCRYPTION_HANDLING_TRACK_ONLY;

@ -268,7 +268,6 @@ noinst_HEADERS = \
detect-quic-cyu-string.h \ detect-quic-cyu-string.h \
detect-quic-sni.h \ detect-quic-sni.h \
detect-quic-ua.h \ detect-quic-ua.h \
detect-quic-version.h \
detect-rawbytes.h \ detect-rawbytes.h \
detect-reference.h \ detect-reference.h \
detect-replace.h \ detect-replace.h \
@ -860,7 +859,6 @@ libsuricata_c_a_SOURCES = \
detect-quic-cyu-string.c \ detect-quic-cyu-string.c \
detect-quic-sni.c \ detect-quic-sni.c \
detect-quic-ua.c \ detect-quic-ua.c \
detect-quic-version.c \
detect-rawbytes.c \ detect-rawbytes.c \
detect-reference.c \ detect-reference.c \
detect-replace.c \ detect-replace.c \

@ -205,7 +205,6 @@
#include "detect-target.h" #include "detect-target.h"
#include "detect-quic-sni.h" #include "detect-quic-sni.h"
#include "detect-quic-ua.h" #include "detect-quic-ua.h"
#include "detect-quic-version.h"
#include "detect-quic-cyu-hash.h" #include "detect-quic-cyu-hash.h"
#include "detect-quic-cyu-string.h" #include "detect-quic-cyu-string.h"
#include "detect-ja4-hash.h" #include "detect-ja4-hash.h"
@ -737,7 +736,6 @@ void SigTableSetup(void)
DetectTargetRegister(); DetectTargetRegister();
DetectQuicSniRegister(); DetectQuicSniRegister();
DetectQuicUaRegister(); DetectQuicUaRegister();
DetectQuicVersionRegister();
DetectQuicCyuHashRegister(); DetectQuicCyuHashRegister();
DetectQuicCyuStringRegister(); DetectQuicCyuStringRegister();
DetectJa4HashRegister(); DetectJa4HashRegister();
@ -788,6 +786,7 @@ void SigTableSetup(void)
SCDetectDNSRegister(); SCDetectDNSRegister();
SCDetectPgsqlRegister(); SCDetectPgsqlRegister();
SCDetectSshRegister(); SCDetectSshRegister();
SCDetectQuicRegister();
for (size_t i = 0; i < preregistered_callbacks_nb; i++) { for (size_t i = 0; i < preregistered_callbacks_nb; i++) {
PreregisteredCallbacks[i](); PreregisteredCallbacks[i]();

@ -283,7 +283,6 @@ enum DetectKeywordId {
DETECT_TCP_WSCALE, DETECT_TCP_WSCALE,
DETECT_FTPDATA, DETECT_FTPDATA,
DETECT_TARGET, DETECT_TARGET,
DETECT_QUIC_VERSION,
DETECT_QUIC_SNI, DETECT_QUIC_SNI,
DETECT_QUIC_UA, DETECT_QUIC_UA,
DETECT_QUIC_CYU_HASH, DETECT_QUIC_CYU_HASH,

@ -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 */

@ -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 */
Loading…
Cancel
Save