detect: rust helper to register sticky buffer

pull/13053/head
Philippe Antoine 9 months ago committed by Victor Julien
parent 96afdce283
commit aa7f926ff4

@ -36,6 +36,7 @@ pub mod vlan;
pub mod datasets;
use std::os::raw::{c_char, c_int, c_void};
use std::ffi::CString;
use suricata_sys::sys::AppProto;
@ -55,6 +56,61 @@ pub trait EnumString<T> {
fn from_str(s: &str) -> Option<Self> where Self: Sized;
}
/// Rust app-layer light version of SigTableElmt for simple sticky buffer
pub struct SigTableElmtStickyBuffer {
/// keyword name
pub name: String,
/// keyword description
pub desc: String,
/// keyword documentation url
pub url: String,
/// function callback to parse and setup keyword in rule
pub setup: unsafe extern "C" fn(
de: *mut c_void,
s: *mut c_void,
raw: *const std::os::raw::c_char,
) -> c_int,
}
pub fn helper_keyword_register_sticky_buffer(kw: &SigTableElmtStickyBuffer) -> c_int {
let name = CString::new(kw.name.as_bytes()).unwrap().into_raw();
let desc = CString::new(kw.desc.as_bytes()).unwrap().into_raw();
let url = CString::new(kw.url.as_bytes()).unwrap().into_raw();
let st = SCSigTableAppLiteElmt {
name,
desc,
url,
Setup: kw.setup,
flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER,
AppLayerTxMatch: None,
Free: None,
};
unsafe {
let r = DetectHelperKeywordRegister(&st);
DetectHelperKeywordSetCleanCString(r);
return r;
}
}
#[repr(C)]
#[allow(non_snake_case)]
/// Names of SigTableElmt for release by rust
pub struct SCSigTableNamesElmt {
/// keyword name
pub name: *mut libc::c_char,
/// keyword description
pub desc: *mut libc::c_char,
/// keyword documentation url
pub url: *mut libc::c_char,
}
#[no_mangle]
pub unsafe extern "C" fn SCDetectSigMatchNamesFree(kw: &mut SCSigTableNamesElmt) {
let _ = CString::from_raw(kw.name);
let _ = CString::from_raw(kw.desc);
let _ = CString::from_raw(kw.url);
}
#[repr(C)]
#[allow(non_snake_case)]
/// App-layer light version of SigTableElmt
@ -95,6 +151,7 @@ pub const SIGMATCH_INFO_STICKY_BUFFER: u16 = 0x200; // BIT_U16(9)
/// cbindgen:ignore
extern "C" {
pub fn DetectHelperKeywordSetCleanCString(id: c_int);
pub fn DetectBufferSetActiveList(de: *mut c_void, s: *mut c_void, bufid: c_int) -> c_int;
pub fn DetectHelperGetData(
de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8,

@ -21,10 +21,10 @@ use crate::detect::uint::{
SCDetectU8Parse,
};
use crate::detect::{
DetectBufferSetActiveList, DetectHelperBufferRegister, DetectHelperGetMultiData,
DetectHelperKeywordAliasRegister, DetectHelperKeywordRegister,
helper_keyword_register_sticky_buffer, DetectBufferSetActiveList, DetectHelperBufferRegister,
DetectHelperGetMultiData, DetectHelperKeywordAliasRegister, DetectHelperKeywordRegister,
DetectHelperMultiBufferProgressMpmRegister, DetectSignatureSetAppProto, SCSigTableAppLiteElmt,
SigMatchAppendSMToList, SIGMATCH_INFO_STICKY_BUFFER, SIGMATCH_NOOPT,
SigMatchAppendSMToList, SigTableElmtStickyBuffer,
};
use crate::direction::Direction;
use std::ffi::CStr;
@ -366,16 +366,13 @@ unsafe extern "C" fn dns_query_get_data_wrapper(
#[no_mangle]
pub unsafe extern "C" fn SCDetectDNSRegister() {
let kw = SCSigTableAppLiteElmt {
name: b"dns.answer.name\0".as_ptr() as *const libc::c_char,
desc: b"DNS answer name sticky buffer\0".as_ptr() as *const libc::c_char,
url: b"/rules/dns-keywords.html#dns-answer-name\0".as_ptr() as *const libc::c_char,
Setup: dns_detect_answer_name_setup,
flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER,
AppLayerTxMatch: None,
Free: None,
let kw = SigTableElmtStickyBuffer {
name: String::from("dns.answer.name"),
desc: String::from("DNS answer name sticky buffer"),
url: String::from("/rules/dns-keywords.html#dns-answer-name"),
setup: dns_detect_answer_name_setup,
};
let _g_dns_answer_name_kw_id = DetectHelperKeywordRegister(&kw);
let _g_dns_answer_name_kw_id = helper_keyword_register_sticky_buffer(&kw);
G_DNS_ANSWER_NAME_BUFFER_ID = DetectHelperMultiBufferProgressMpmRegister(
b"dns.answer.name\0".as_ptr() as *const libc::c_char,
b"dns answer name\0".as_ptr() as *const libc::c_char,
@ -403,16 +400,13 @@ pub unsafe extern "C" fn SCDetectDNSRegister() {
true,
true,
);
let kw = SCSigTableAppLiteElmt {
name: b"dns.query.name\0".as_ptr() as *const libc::c_char,
desc: b"DNS query name sticky buffer\0".as_ptr() as *const libc::c_char,
url: b"/rules/dns-keywords.html#dns-query-name\0".as_ptr() as *const libc::c_char,
Setup: dns_detect_query_name_setup,
flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER,
AppLayerTxMatch: None,
Free: None,
let kw = SigTableElmtStickyBuffer {
name: String::from("dns.query.name"),
desc: String::from("DNS query name sticky buffer"),
url: String::from("/rules/dns-keywords.html#dns-query-name"),
setup: dns_detect_query_name_setup,
};
let _g_dns_query_name_kw_id = DetectHelperKeywordRegister(&kw);
let _g_dns_query_name_kw_id = helper_keyword_register_sticky_buffer(&kw);
G_DNS_QUERY_NAME_BUFFER_ID = DetectHelperMultiBufferProgressMpmRegister(
b"dns.query.name\0".as_ptr() as *const libc::c_char,
b"dns query name\0".as_ptr() as *const libc::c_char,
@ -456,16 +450,13 @@ pub unsafe extern "C" fn SCDetectDNSRegister() {
true,
true,
);
let kw = SCSigTableAppLiteElmt {
name: b"dns.query\0".as_ptr() as *const libc::c_char,
desc: b"sticky buffer to match DNS query-buffer\0".as_ptr() as *const libc::c_char,
url: b"/rules/dns-keywords.html#dns-query\0".as_ptr() as *const libc::c_char,
Setup: dns_detect_query_setup,
flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER,
AppLayerTxMatch: None,
Free: None,
let kw = SigTableElmtStickyBuffer {
name: String::from("dns.query"),
desc: String::from("sticky buffer to match DNS query-buffer"),
url: String::from("/rules/dns-keywords.html#dns-query"),
setup: dns_detect_query_setup,
};
let g_dns_query_name_kw_id = DetectHelperKeywordRegister(&kw);
let g_dns_query_name_kw_id = helper_keyword_register_sticky_buffer(&kw);
DetectHelperKeywordAliasRegister(
g_dns_query_name_kw_id,
b"dns_query\0".as_ptr() as *const libc::c_char,

@ -447,9 +447,30 @@ static void DetectFileHandlerRegister(void)
}
}
static void SigCleanCString(SigTableElmt *base)
{
SCSigTableNamesElmt kw;
// remove const for mut to release
kw.name = (char *)base->name;
kw.desc = (char *)base->desc;
kw.url = (char *)base->url;
SCDetectSigMatchNamesFree(&kw);
}
void DetectHelperKeywordSetCleanCString(int id)
{
sigmatch_table[id].Cleanup = SigCleanCString;
}
void SigTableCleanup(void)
{
if (sigmatch_table != NULL) {
for (int i = 0; i < DETECT_TBLSIZE; i++) {
if ((sigmatch_table[i].Cleanup) == NULL) {
continue;
}
sigmatch_table[i].Cleanup(&sigmatch_table[i]);
}
SCFree(sigmatch_table);
sigmatch_table = NULL;
DETECT_TBLSIZE = 0;

@ -349,5 +349,6 @@ void SigTableSetup(void);
int SCSigTablePreRegister(void (*KeywordsRegister)(void));
void SigTableRegisterTests(void);
bool SigTableHasKeyword(const char *keyword);
void DetectHelperKeywordSetCleanCString(int id);
#endif /* SURICATA_DETECT_ENGINE_REGISTER_H */

@ -1404,6 +1404,8 @@ typedef struct SigTableElmt_ {
const char *desc;
const char *url;
// Cleanup function for freeing rust allocated name or such
void (*Cleanup)(struct SigTableElmt_ *);
} SigTableElmt;
/* event code */

Loading…
Cancel
Save