detect/dcerpc: move opnum keyword to rust

Ticket: 8391
pull/15240/head
Philippe Antoine 6 months ago committed by Victor Julien
parent a36af353bc
commit 67379b009a

@ -16,12 +16,21 @@
*/
use super::dcerpc::{
DCERPCState, DCERPCTransaction, DCERPC_TYPE_REQUEST, DCERPC_TYPE_RESPONSE,
DCERPCState, DCERPCTransaction, ALPROTO_DCERPC, DCERPC_TYPE_REQUEST, DCERPC_TYPE_RESPONSE,
DCERPC_UUID_ENTRY_FLAG_FF,
};
use crate::core::{STREAM_TOCLIENT, STREAM_TOSERVER};
use crate::detect::uint::{detect_match_uint, detect_parse_uint, DetectUintData};
use crate::smb::detect::smb_tx_match_dce_opnum;
use crate::smb::smb::ALPROTO_SMB;
use std::ffi::CStr;
use std::os::raw::{c_char, c_void};
use std::os::raw::{c_char, c_int, c_void};
use suricata_sys::sys::{
DetectEngineCtx, DetectEngineThreadCtx, SCDetectHelperBufferProgressRegister,
SCDetectHelperKeywordAliasRegister, SCDetectHelperKeywordRegister,
SCDetectSignatureSetAppProto, SCFlowGetAppProtocol, SCSigMatchAppendSMToList,
SCSigTableAppLiteElmt, SigMatchCtx, Signature,
};
use uuid::Uuid;
pub const DETECT_DCE_OPNUM_RANGE_UNINITIALIZED: u32 = 100000;
@ -213,7 +222,7 @@ pub extern "C" fn SCDcerpcIfaceMatch(
}
if !(tx.req_cmd == DCERPC_TYPE_REQUEST || tx.resp_cmd == DCERPC_TYPE_RESPONSE) {
return 0;
return 0;
}
return match_backuuid(tx, state, if_data);
@ -244,10 +253,10 @@ pub unsafe extern "C" fn SCDcerpcIfaceFree(ptr: *mut c_void) {
}
}
#[no_mangle]
pub unsafe extern "C" fn SCDcerpcOpnumMatch(
tx: &DCERPCTransaction, opnum_data: &mut DCEOpnumData,
) -> u8 {
unsafe extern "C" fn dcerpc_tx_match_dce_opnum(tx: *mut c_void, ctx: *const SigMatchCtx) -> c_int {
let tx = cast_pointer!(tx, DCERPCTransaction);
let opnum_data = cast_pointer!(ctx, DCEOpnumData);
let first_req_seen = tx.get_first_req_seen();
if first_req_seen == 0 {
return 0;
@ -266,31 +275,95 @@ pub unsafe extern "C" fn SCDcerpcOpnumMatch(
0
}
#[no_mangle]
pub unsafe extern "C" fn SCDcerpcOpnumParse(carg: *const c_char) -> *mut c_void {
if carg.is_null() {
return std::ptr::null_mut();
unsafe extern "C" fn dcerpc_opnum_parse(carg: *const c_char) -> *mut c_void {
if let Ok(arg) = CStr::from_ptr(carg).to_str() {
return match parse_opnum_data(arg) {
Ok(detect) => Box::into_raw(Box::new(detect)) as *mut _,
Err(_) => std::ptr::null_mut(),
};
}
let arg = match CStr::from_ptr(carg).to_str() {
Ok(arg) => arg,
_ => {
return std::ptr::null_mut();
}
};
return std::ptr::null_mut();
}
match parse_opnum_data(arg) {
Ok(detect) => Box::into_raw(Box::new(detect)) as *mut _,
Err(_) => std::ptr::null_mut(),
unsafe extern "C" fn dcerpc_opnum_setup(
de: *mut DetectEngineCtx, s: *mut Signature, raw: *const libc::c_char,
) -> c_int {
if SCDetectSignatureSetAppProto(s, ALPROTO_DCERPC) != 0 {
return -1;
}
let ctx = dcerpc_opnum_parse(raw) as *mut c_void;
if ctx.is_null() {
return -1;
}
if SCSigMatchAppendSMToList(
de,
s,
G_DCERPC_OPNUM_KW_ID,
ctx as *mut SigMatchCtx,
G_DCERPC_OPNUM_BUFFER_ID,
)
.is_null()
{
dcerpc_opnum_free(std::ptr::null_mut(), ctx);
return -1;
}
return 0;
}
#[no_mangle]
pub unsafe extern "C" fn SCDcerpcOpnumFree(ptr: *mut c_void) {
unsafe extern "C" fn dcerpc_opnum_match(
_de: *mut DetectEngineThreadCtx, f: *mut crate::flow::Flow, _flags: u8, _state: *mut c_void,
tx: *mut c_void, _sig: *const Signature, ctx: *const SigMatchCtx,
) -> c_int {
if SCFlowGetAppProtocol(f) == ALPROTO_DCERPC {
return dcerpc_tx_match_dce_opnum(tx, ctx);
}
if smb_tx_match_dce_opnum(tx, ctx) != 1 {
return 0;
}
return 1;
}
unsafe extern "C" fn dcerpc_opnum_free(_de: *mut DetectEngineCtx, ptr: *mut c_void) {
if !ptr.is_null() {
std::mem::drop(Box::from_raw(ptr as *mut DCEOpnumData));
}
}
static mut G_DCERPC_OPNUM_KW_ID: u16 = 0;
static mut G_DCERPC_OPNUM_BUFFER_ID: c_int = 0;
#[no_mangle]
pub unsafe extern "C" fn SCDetectDcerpcRegister() {
let kw = SCSigTableAppLiteElmt {
name: b"dcerpc.opnum\0".as_ptr() as *const libc::c_char,
desc: b"match on one or many operation numbers within the interface in a DCERPC header\0"
.as_ptr() as *const libc::c_char,
url: b"/rules/dcerpc-keywords.html#dcerpc-opnum\0".as_ptr() as *const libc::c_char,
AppLayerTxMatch: Some(dcerpc_opnum_match),
Setup: Some(dcerpc_opnum_setup),
Free: Some(dcerpc_opnum_free),
flags: 0,
};
G_DCERPC_OPNUM_KW_ID = SCDetectHelperKeywordRegister(&kw);
G_DCERPC_OPNUM_BUFFER_ID = SCDetectHelperBufferProgressRegister(
b"dcerpc_opnum\0".as_ptr() as *const libc::c_char,
ALPROTO_DCERPC,
STREAM_TOSERVER | STREAM_TOCLIENT,
0,
);
_ = SCDetectHelperBufferProgressRegister(
b"dcerpc_opnum\0".as_ptr() as *const libc::c_char,
ALPROTO_SMB,
STREAM_TOSERVER | STREAM_TOCLIENT,
0,
);
SCDetectHelperKeywordAliasRegister(
G_DCERPC_OPNUM_KW_ID,
b"dce_opnum\0".as_ptr() as *const libc::c_char,
);
}
#[cfg(test)]
mod test {
use super::*;

@ -92,9 +92,13 @@ pub unsafe extern "C" fn SCSmbTxGetStubData(
return 0;
}
#[no_mangle]
pub extern "C" fn SCSmbTxMatchDceOpnum(tx: &SMBTransaction, dce_data: &mut DCEOpnumData) -> u8 {
SCLogDebug!("SCSmbTxMatchDceOpnum: start");
pub(crate) unsafe extern "C" fn smb_tx_match_dce_opnum(
tx: *mut c_void, ctx: *const SigMatchCtx,
) -> u8 {
let tx = cast_pointer!(tx, SMBTransaction);
let dce_data = cast_pointer!(ctx, DCEOpnumData);
SCLogDebug!("smb_tx_match_dce_opnum: start");
if let Some(SMBTransactionTypeData::DCERPC(ref x)) = tx.type_data {
if x.req_cmd == DCERPC_TYPE_REQUEST {
for range in dce_data.data.iter() {

@ -103,7 +103,7 @@ pub static mut SMB_CFG_MAX_SSN2VEC_CACHE_SIZE: usize = 512;
pub static mut SMB_DCERPC_MAX_STUB_SIZE: u32 = 1048576;
pub(super) static mut ALPROTO_SMB: AppProto = ALPROTO_UNKNOWN;
pub(crate) static mut ALPROTO_SMB: AppProto = ALPROTO_UNKNOWN;
static mut SMB_MAX_TX: usize = 1024;

@ -118,7 +118,6 @@ noinst_HEADERS = \
detect-datarep.h \
detect-dataset.h \
detect-dce-iface.h \
detect-dce-opnum.h \
detect-dce-stub-data.h \
detect-depth.h \
detect-detection-filter.h \
@ -699,7 +698,6 @@ libsuricata_c_a_SOURCES = \
detect-datarep.c \
detect-dataset.c \
detect-dce-iface.c \
detect-dce-opnum.c \
detect-dce-stub-data.c \
detect-depth.c \
detect-detection-filter.c \

File diff suppressed because it is too large Load Diff

@ -1,29 +0,0 @@
/* Copyright (C) 2007-2010 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 Anoop Saldanha <anoopsaldanha@gmail.com>
*/
#ifndef SURICATA_DETECT_DCE_OPNUM_H
#define SURICATA_DETECT_DCE_OPNUM_H
void DetectDceOpnumRegister(void);
#endif /* SURICATA_DETECT_DCE_OPNUM_H */

@ -157,7 +157,6 @@
#include "detect-igmphdr.h"
#include "detect-igmp-type.h"
#include "detect-dce-iface.h"
#include "detect-dce-opnum.h"
#include "detect-dce-stub-data.h"
#include "detect-urilen.h"
#include "detect-bsize.h"
@ -669,7 +668,6 @@ void SigTableSetup(void)
DetectIGMPHdrRegister();
DetectIGMPTypeRegister();
DetectDceIfaceRegister();
DetectDceOpnumRegister();
DetectDceStubDataRegister();
DetectTlsRegister();
DetectTlsValidityRegister();
@ -762,6 +760,7 @@ void SigTableSetup(void)
SCDetectQuicRegister();
SCDetectSmbRegister();
SCDetectIkeRegister();
SCDetectDcerpcRegister();
for (size_t i = 0; i < preregistered_callbacks_nb; i++) {
PreregisteredCallbacks[i]();

@ -210,7 +210,6 @@ enum DetectKeywordId {
DETECT_HTTP_RESPONSE_HEADER,
DETECT_DCE_IFACE,
DETECT_DCE_OPNUM,
DETECT_DCE_STUB_DATA,
DETECT_ENGINE_EVENT,

Loading…
Cancel
Save