From 9814b698c871e1e41850050c895cc55df94470f3 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Sun, 26 Jan 2025 15:16:03 +0100 Subject: [PATCH] detect/dns: move keywords to rust Ticket: 7529 Ticket: 3725 Adds url for dns.opcode on the way --- rust/src/detect/mod.rs | 3 +- rust/src/dns/detect.rs | 389 +++++++++++++++++++++++++++++++++-- rust/src/dns/dns.rs | 2 +- src/Makefile.am | 8 - src/detect-dns-opcode.c | 89 -------- src/detect-dns-opcode.h | 23 --- src/detect-dns-query.c | 131 ------------ src/detect-dns-query.h | 29 --- src/detect-dns-rcode.c | 85 -------- src/detect-dns-rcode.h | 23 --- src/detect-dns-rrtype.c | 85 -------- src/detect-dns-rrtype.h | 23 --- src/detect-engine-helper.c | 5 + src/detect-engine-helper.h | 1 + src/detect-engine-register.c | 9 +- src/detect-engine-register.h | 4 - 16 files changed, 381 insertions(+), 528 deletions(-) delete mode 100644 src/detect-dns-opcode.c delete mode 100644 src/detect-dns-opcode.h delete mode 100644 src/detect-dns-query.c delete mode 100644 src/detect-dns-query.h delete mode 100644 src/detect-dns-rcode.c delete mode 100644 src/detect-dns-rcode.h delete mode 100644 src/detect-dns-rrtype.c delete mode 100644 src/detect-dns-rrtype.h diff --git a/rust/src/detect/mod.rs b/rust/src/detect/mod.rs index dc79f61393..f02eed9074 100644 --- a/rust/src/detect/mod.rs +++ b/rust/src/detect/mod.rs @@ -35,7 +35,7 @@ pub mod tojson; pub mod vlan; pub mod datasets; -use std::os::raw::{c_int, c_void}; +use std::os::raw::{c_char, c_int, c_void}; use suricata_sys::sys::AppProto; @@ -106,6 +106,7 @@ extern "C" { ) -> *mut c_void, ) -> c_int; pub fn DetectHelperKeywordRegister(kw: *const SCSigTableElmt) -> c_int; + pub fn DetectHelperKeywordAliasRegister(kwid: c_int, alias: *const c_char); pub fn DetectHelperBufferRegister( name: *const libc::c_char, alproto: AppProto, toclient: bool, toserver: bool, ) -> c_int; diff --git a/rust/src/dns/detect.rs b/rust/src/dns/detect.rs index 2eb81c6ba3..0c07296f4e 100644 --- a/rust/src/dns/detect.rs +++ b/rust/src/dns/detect.rs @@ -15,17 +15,29 @@ * 02110-1301, USA. */ -use super::dns::DNSTransaction; +use super::dns::{DNSTransaction, ALPROTO_DNS}; +use crate::detect::uint::{ + detect_match_uint, DetectUintData, SCDetectU16Free, SCDetectU16Parse, SCDetectU8Free, + SCDetectU8Parse, +}; +use crate::detect::{ + DetectBufferSetActiveList, DetectHelperBufferRegister, DetectHelperGetMultiData, + DetectHelperKeywordAliasRegister, DetectHelperKeywordRegister, + DetectHelperMultiBufferProgressMpmRegister, DetectSignatureSetAppProto, SCSigTableElmt, + SigMatchAppendSMToList, SIGMATCH_INFO_STICKY_BUFFER, SIGMATCH_NOOPT, +}; use crate::direction::Direction; -use crate::detect::uint::{detect_match_uint, DetectUintData}; +use std::os::raw::{c_int, c_void}; /// Perform the DNS opcode match. /// /// 1 will be returned on match, otherwise 0 will be returned. -#[no_mangle] -pub extern "C" fn SCDnsDetectOpcodeMatch( - tx: &mut DNSTransaction, detect: &mut DetectUintData, flags: u8, -) -> u8 { +unsafe extern "C" fn dns_opcode_match( + _de: *mut c_void, _f: *mut c_void, flags: u8, _state: *mut c_void, tx: *mut c_void, + _sig: *const c_void, ctx: *const c_void, +) -> c_int { + let tx = cast_pointer!(tx, DNSTransaction); + let ctx = cast_pointer!(ctx, DetectUintData); let header_flags = if flags & Direction::ToServer as u8 != 0 { if let Some(request) = &tx.request { request.header.flags @@ -44,7 +56,7 @@ pub extern "C" fn SCDnsDetectOpcodeMatch( }; let opcode = ((header_flags >> 11) & 0xf) as u8; - if detect_match_uint(detect, opcode) { + if detect_match_uint(ctx, opcode) { return 1; } return 0; @@ -53,10 +65,12 @@ pub extern "C" fn SCDnsDetectOpcodeMatch( /// Perform the DNS rcode match. /// /// 1 will be returned on match, otherwise 0 will be returned. -#[no_mangle] -pub extern "C" fn SCDnsDetectRcodeMatch( - tx: &mut DNSTransaction, detect: &mut DetectUintData, flags: u8, -) -> u8 { +unsafe extern "C" fn dns_rcode_match( + _de: *mut c_void, _f: *mut c_void, flags: u8, _state: *mut c_void, tx: *mut c_void, + _sig: *const c_void, ctx: *const c_void, +) -> c_int { + let tx = cast_pointer!(tx, DNSTransaction); + let ctx = cast_pointer!(ctx, DetectUintData); let header_flags = if flags & Direction::ToServer as u8 != 0 { if let Some(request) = &tx.request { request.header.flags @@ -71,7 +85,7 @@ pub extern "C" fn SCDnsDetectRcodeMatch( let rcode = (header_flags & 0xf) as u8; - if detect_match_uint(detect, rcode) { + if detect_match_uint(ctx, rcode) { return 1; } return 0; @@ -79,14 +93,17 @@ pub extern "C" fn SCDnsDetectRcodeMatch( /// Perform the DNS rrtype match. /// 1 will be returned on match, otherwise 0 will be returned. -#[no_mangle] -pub extern "C" fn SCDnsDetectRrtypeMatch( - tx: &mut DNSTransaction, detect: &mut DetectUintData, flags: u8, -) -> u16 { +unsafe extern "C" fn dns_rrtype_match( + _de: *mut c_void, _f: *mut c_void, flags: u8, _state: *mut c_void, tx: *mut c_void, + _sig: *const c_void, ctx: *const c_void, +) -> c_int { + let tx = cast_pointer!(tx, DNSTransaction); + let ctx = cast_pointer!(ctx, DetectUintData); + if flags & Direction::ToServer as u8 != 0 { if let Some(request) = &tx.request { for i in 0..request.queries.len() { - if detect_match_uint(detect, request.queries[i].rrtype) { + if detect_match_uint(ctx, request.queries[i].rrtype) { return 1; } } @@ -94,7 +111,7 @@ pub extern "C" fn SCDnsDetectRrtypeMatch( } else if flags & Direction::ToClient as u8 != 0 { if let Some(response) = &tx.response { for i in 0..response.answers.len() { - if detect_match_uint(detect, response.answers[i].rrtype) { + if detect_match_uint(ctx, response.answers[i].rrtype) { return 1; } } @@ -103,6 +120,342 @@ pub extern "C" fn SCDnsDetectRrtypeMatch( return 0; } +static mut G_DNS_ANSWER_NAME_BUFFER_ID: c_int = 0; +static mut G_DNS_QUERY_NAME_BUFFER_ID: c_int = 0; +static mut G_DNS_QUERY_BUFFER_ID: c_int = 0; +static mut G_DNS_OPCODE_KW_ID: c_int = 0; +static mut G_DNS_OPCODE_BUFFER_ID: c_int = 0; +static mut G_DNS_RCODE_KW_ID: c_int = 0; +static mut G_DNS_RCODE_BUFFER_ID: c_int = 0; +static mut G_DNS_RRTYPE_KW_ID: c_int = 0; +static mut G_DNS_RRTYPE_BUFFER_ID: c_int = 0; + +unsafe extern "C" fn dns_opcode_setup( + de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0 { + return -1; + } + let ctx = SCDetectU8Parse(raw) as *mut c_void; + if ctx.is_null() { + return -1; + } + if SigMatchAppendSMToList(de, s, G_DNS_OPCODE_KW_ID, ctx, G_DNS_OPCODE_BUFFER_ID).is_null() { + dns_opcode_free(std::ptr::null_mut(), ctx); + return -1; + } + return 0; +} + +unsafe extern "C" fn dns_opcode_free(_de: *mut c_void, ctx: *mut c_void) { + // Just unbox... + let ctx = cast_pointer!(ctx, DetectUintData); + SCDetectU8Free(ctx); +} + +unsafe extern "C" fn dns_rcode_setup( + de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0 { + return -1; + } + let ctx = SCDetectU8Parse(raw) as *mut c_void; + if ctx.is_null() { + return -1; + } + if SigMatchAppendSMToList(de, s, G_DNS_RCODE_KW_ID, ctx, G_DNS_RCODE_BUFFER_ID).is_null() { + dns_rcode_free(std::ptr::null_mut(), ctx); + return -1; + } + return 0; +} + +unsafe extern "C" fn dns_rcode_free(_de: *mut c_void, ctx: *mut c_void) { + // Just unbox... + let ctx = cast_pointer!(ctx, DetectUintData); + SCDetectU8Free(ctx); +} + +unsafe extern "C" fn dns_rrtype_setup( + de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0 { + return -1; + } + let ctx = SCDetectU16Parse(raw) as *mut c_void; + if ctx.is_null() { + return -1; + } + if SigMatchAppendSMToList(de, s, G_DNS_RRTYPE_KW_ID, ctx, G_DNS_RRTYPE_BUFFER_ID).is_null() { + dns_rrtype_free(std::ptr::null_mut(), ctx); + return -1; + } + return 0; +} + +unsafe extern "C" fn dns_rrtype_free(_de: *mut c_void, ctx: *mut c_void) { + // Just unbox... + let ctx = cast_pointer!(ctx, DetectUintData); + SCDetectU16Free(ctx); +} + +unsafe extern "C" fn dns_detect_answer_name_setup( + de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0 { + return -1; + } + if DetectBufferSetActiveList(de, s, G_DNS_ANSWER_NAME_BUFFER_ID) < 0 { + return -1; + } + return 0; +} + +/// Get the DNS response answer name and index i. +unsafe extern "C" fn dns_tx_get_answer_name( + tx: *const c_void, flags: u8, i: u32, buf: *mut *const u8, len: *mut u32, +) -> bool { + let tx = cast_pointer!(tx, DNSTransaction); + let answers = if flags & Direction::ToClient as u8 != 0 { + tx.response.as_ref().map(|response| &response.answers) + } else { + tx.request.as_ref().map(|request| &request.answers) + }; + let index = i as usize; + + if let Some(answers) = answers { + if let Some(answer) = answers.get(index) { + if !answer.name.value.is_empty() { + *buf = answer.name.value.as_ptr(); + *len = answer.name.value.len() as u32; + return true; + } + } + } + + false +} + +unsafe extern "C" fn dns_answer_name_get_data_wrapper( + de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8, + tx: *const c_void, list_id: c_int, local_id: u32, +) -> *mut c_void { + return DetectHelperGetMultiData( + de, + transforms, + flow, + flow_flags, + tx, + list_id, + local_id, + dns_tx_get_answer_name, + ); +} + +unsafe extern "C" fn dns_detect_query_name_setup( + de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0 { + return -1; + } + if DetectBufferSetActiveList(de, s, G_DNS_QUERY_NAME_BUFFER_ID) < 0 { + return -1; + } + return 0; +} + +/// Get the DNS response answer name and index i. +unsafe extern "C" fn dns_tx_get_query_name( + tx: *const c_void, flags: u8, i: u32, buf: *mut *const u8, len: *mut u32, +) -> bool { + let tx = cast_pointer!(tx, DNSTransaction); + let queries = if flags & Direction::ToClient as u8 != 0 { + tx.response.as_ref().map(|response| &response.queries) + } else { + tx.request.as_ref().map(|request| &request.queries) + }; + let index = i as usize; + + if let Some(queries) = queries { + if let Some(query) = queries.get(index) { + if !query.name.value.is_empty() { + *buf = query.name.value.as_ptr(); + *len = query.name.value.len() as u32; + return true; + } + } + } + + false +} + +unsafe extern "C" fn dns_tx_get_query( + tx: *const c_void, _flags: u8, i: u32, buf: *mut *const u8, len: *mut u32, +) -> bool { + return dns_tx_get_query_name(tx, Direction::ToServer as u8, i, buf, len); +} + +unsafe extern "C" fn dns_detect_query_setup( + de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0 { + return -1; + } + if DetectBufferSetActiveList(de, s, G_DNS_QUERY_BUFFER_ID) < 0 { + return -1; + } + return 0; +} + +unsafe extern "C" fn dns_query_name_get_data_wrapper( + de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8, + tx: *const c_void, list_id: c_int, local_id: u32, +) -> *mut c_void { + return DetectHelperGetMultiData( + de, + transforms, + flow, + flow_flags, + tx, + list_id, + local_id, + dns_tx_get_query_name, + ); +} + +unsafe extern "C" fn dns_query_get_data_wrapper( + de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8, + tx: *const c_void, list_id: c_int, local_id: u32, +) -> *mut c_void { + return DetectHelperGetMultiData( + de, + transforms, + flow, + flow_flags, + tx, + list_id, + local_id, + dns_tx_get_query, + ); +} + +#[no_mangle] +pub unsafe extern "C" fn SCDetectDNSRegister() { + let kw = SCSigTableElmt { + 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 _g_dns_answer_name_kw_id = DetectHelperKeywordRegister(&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, + ALPROTO_DNS, + true, + /* Register also in the TO_SERVER direction, even though this is not + normal, it could be provided as part of a request. */ + true, + dns_answer_name_get_data_wrapper, + 1, // response complete + ); + let kw = SCSigTableElmt { + name: b"dns.opcode\0".as_ptr() as *const libc::c_char, + desc: b"Match the DNS header opcode flag.\0".as_ptr() as *const libc::c_char, + url: b"rules/dns-keywords.html#dns-opcode\0".as_ptr() as *const libc::c_char, + AppLayerTxMatch: Some(dns_opcode_match), + Setup: dns_opcode_setup, + Free: Some(dns_opcode_free), + flags: 0, + }; + G_DNS_OPCODE_KW_ID = DetectHelperKeywordRegister(&kw); + G_DNS_OPCODE_BUFFER_ID = DetectHelperBufferRegister( + b"dns.opcode\0".as_ptr() as *const libc::c_char, + ALPROTO_DNS, + true, + true, + ); + let kw = SCSigTableElmt { + 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 _g_dns_query_name_kw_id = DetectHelperKeywordRegister(&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, + ALPROTO_DNS, + true, + /* Register in both directions as the query is usually echoed back + in the response. */ + true, + dns_query_name_get_data_wrapper, + 1, // request or response complete + ); + let kw = SCSigTableElmt { + name: b"dns.rcode\0".as_ptr() as *const libc::c_char, + desc: b"Match the DNS header rcode flag.\0".as_ptr() as *const libc::c_char, + url: b"rules/dns-keywords.html#dns-rcode\0".as_ptr() as *const libc::c_char, + AppLayerTxMatch: Some(dns_rcode_match), + Setup: dns_rcode_setup, + Free: Some(dns_rcode_free), + flags: 0, + }; + G_DNS_RCODE_KW_ID = DetectHelperKeywordRegister(&kw); + G_DNS_RCODE_BUFFER_ID = DetectHelperBufferRegister( + b"dns.rcode\0".as_ptr() as *const libc::c_char, + ALPROTO_DNS, + true, + true, + ); + let kw = SCSigTableElmt { + name: b"dns.rrtype\0".as_ptr() as *const libc::c_char, + desc: b"Match the DNS rrtype in message body.\0".as_ptr() as *const libc::c_char, + url: b"rules/dns-keywords.html#dns-rrtype\0".as_ptr() as *const libc::c_char, + AppLayerTxMatch: Some(dns_rrtype_match), + Setup: dns_rrtype_setup, + Free: Some(dns_rrtype_free), + flags: 0, + }; + G_DNS_RRTYPE_KW_ID = DetectHelperKeywordRegister(&kw); + G_DNS_RRTYPE_BUFFER_ID = DetectHelperBufferRegister( + b"dns.rrtype\0".as_ptr() as *const libc::c_char, + ALPROTO_DNS, + true, + true, + ); + let kw = SCSigTableElmt { + 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 g_dns_query_name_kw_id = DetectHelperKeywordRegister(&kw); + DetectHelperKeywordAliasRegister( + g_dns_query_name_kw_id, + b"dns_query\0".as_ptr() as *const libc::c_char, + ); + G_DNS_QUERY_BUFFER_ID = DetectHelperMultiBufferProgressMpmRegister( + b"dns_query\0".as_ptr() as *const libc::c_char, + b"dns request query\0".as_ptr() as *const libc::c_char, + ALPROTO_DNS, + false, // only toserver + true, + dns_query_get_data_wrapper, // reuse, will be called only toserver + 1, // request complete + ); +} + #[cfg(test)] mod test { use super::*; diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index 48698ab1e8..05603bd2a9 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -116,7 +116,7 @@ pub const DNS_RCODE_BADNAME: u16 = 20; pub const DNS_RCODE_BADALG: u16 = 21; pub const DNS_RCODE_BADTRUNC: u16 = 22; -static mut ALPROTO_DNS: AppProto = ALPROTO_UNKNOWN; +pub(super) static mut ALPROTO_DNS: AppProto = ALPROTO_UNKNOWN; #[derive(AppLayerFrameType)] enum DnsFrameType { diff --git a/src/Makefile.am b/src/Makefile.am index 5b0fe7506b..ec42d43854 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -113,11 +113,7 @@ noinst_HEADERS = \ detect-distance.h \ detect-dnp3.h \ detect-dns-name.h \ - detect-dns-opcode.h \ - detect-dns-rcode.h \ detect-dns-response.h \ - detect-dns-rrtype.h \ - detect-dns-query.h \ detect-dsize.h \ detect-engine-address.h \ detect-engine-address-ipv4.h \ @@ -702,11 +698,7 @@ libsuricata_c_a_SOURCES = \ detect-distance.c \ detect-dnp3.c \ detect-dns-name.c \ - detect-dns-opcode.c \ - detect-dns-rcode.c \ detect-dns-response.c \ - detect-dns-rrtype.c \ - detect-dns-query.c \ detect-dsize.c \ detect-engine-address.c \ detect-engine-address-ipv4.c \ diff --git a/src/detect-dns-opcode.c b/src/detect-dns-opcode.c deleted file mode 100644 index 4db35d508b..0000000000 --- a/src/detect-dns-opcode.c +++ /dev/null @@ -1,89 +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. - */ - -#include "suricata-common.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-uint.h" -#include "detect-dns-opcode.h" -#include "rust.h" - -static int dns_opcode_list_id = 0; - -static void DetectDnsOpcodeFree(DetectEngineCtx *, void *ptr); - -static int DetectDnsOpcodeSetup(DetectEngineCtx *de_ctx, Signature *s, - const char *str) -{ - SCEnter(); - - if (DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0) { - return -1; - } - - void *detect = DetectU8Parse(str); - if (detect == NULL) { - SCLogError("failed to parse dns.opcode: %s", str); - return -1; - } - - if (SigMatchAppendSMToList( - de_ctx, s, DETECT_DNS_OPCODE, (SigMatchCtx *)detect, dns_opcode_list_id) == NULL) { - goto error; - } - - SCReturnInt(0); - -error: - DetectDnsOpcodeFree(de_ctx, detect); - SCReturnInt(-1); -} - -static void DetectDnsOpcodeFree(DetectEngineCtx *de_ctx, void *ptr) -{ - SCEnter(); - if (ptr != NULL) { - SCDetectU8Free(ptr); - } - SCReturn; -} - -static int DetectDnsOpcodeMatch(DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *state, void *txv, const Signature *s, - const SigMatchCtx *ctx) -{ - return SCDnsDetectOpcodeMatch(txv, (void *)ctx, flags); -} - -void DetectDnsOpcodeRegister(void) -{ - sigmatch_table[DETECT_DNS_OPCODE].name = "dns.opcode"; - sigmatch_table[DETECT_DNS_OPCODE].desc = "Match the DNS header opcode flag."; - sigmatch_table[DETECT_DNS_OPCODE].Setup = DetectDnsOpcodeSetup; - sigmatch_table[DETECT_DNS_OPCODE].Free = DetectDnsOpcodeFree; - sigmatch_table[DETECT_DNS_OPCODE].Match = NULL; - sigmatch_table[DETECT_DNS_OPCODE].AppLayerTxMatch = DetectDnsOpcodeMatch; - - DetectAppLayerInspectEngineRegister( - "dns.opcode", ALPROTO_DNS, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL); - - DetectAppLayerInspectEngineRegister( - "dns.opcode", ALPROTO_DNS, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectGenericList, NULL); - - dns_opcode_list_id = DetectBufferTypeGetByName("dns.opcode"); -} diff --git a/src/detect-dns-opcode.h b/src/detect-dns-opcode.h deleted file mode 100644 index a26a39e711..0000000000 --- a/src/detect-dns-opcode.h +++ /dev/null @@ -1,23 +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. - */ - -#ifndef SURICATA_DETECT_DNS_OPCODE_H -#define SURICATA_DETECT_DNS_OPCODE_H - -void DetectDnsOpcodeRegister(void); - -#endif /* SURICATA_DETECT_DNS_OPCODE_H */ diff --git a/src/detect-dns-query.c b/src/detect-dns-query.c deleted file mode 100644 index ef73d58418..0000000000 --- a/src/detect-dns-query.c +++ /dev/null @@ -1,131 +0,0 @@ -/* Copyright (C) 2013-2023 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. - */ - -/** - * \ingroup dnslayer - * - * @{ - */ - - -/** - * \file - * - * \author Victor Julien - */ - -#include "suricata-common.h" -#include "threads.h" -#include "decode.h" -#include "detect.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-build.h" -#include "detect-engine-mpm.h" -#include "detect-engine-prefilter.h" -#include "detect-engine-content-inspection.h" -#include "detect-content.h" -#include "detect-pcre.h" - -#include "flow.h" -#include "flow-util.h" -#include "flow-var.h" - -#include "util-debug.h" -#include "util-spm.h" -#include "util-print.h" - -#include "stream-tcp.h" - -#include "app-layer.h" -#include "app-layer-parser.h" -#include "detect-dns-query.h" - -#include "util-profiling.h" -#include "rust.h" - -static int DetectDnsQuerySetup(DetectEngineCtx *, Signature *, const char *); -static int g_dns_query_buffer_id = 0; - -static InspectionBuffer *DnsQueryGetData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv, - int list_id, uint32_t local_id) -{ - SCEnter(); - - InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, local_id); - if (buffer == NULL) - return NULL; - if (buffer->initialized) - return buffer; - - const uint8_t *data; - uint32_t data_len; - if (SCDnsTxGetQueryName(txv, false, local_id, &data, &data_len) == 0) { - InspectionBufferSetupMultiEmpty(buffer); - return NULL; - } - InspectionBufferSetupMulti(det_ctx, buffer, transforms, data, data_len); - buffer->flags = DETECT_CI_FLAGS_SINGLE; - - SCReturnPtr(buffer, "InspectionBuffer"); -} - -/** - * \brief Registration function for keyword: dns_query - */ -void DetectDnsQueryRegister (void) -{ - sigmatch_table[DETECT_DNS_QUERY].name = "dns.query"; - sigmatch_table[DETECT_DNS_QUERY].alias = "dns_query"; - sigmatch_table[DETECT_DNS_QUERY].desc = "sticky buffer to match DNS query-buffer"; - sigmatch_table[DETECT_DNS_QUERY].url = "/rules/dns-keywords.html#dns-query"; - sigmatch_table[DETECT_DNS_QUERY].Setup = DetectDnsQuerySetup; - sigmatch_table[DETECT_DNS_QUERY].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_DNS_QUERY].flags |= SIGMATCH_INFO_STICKY_BUFFER; - - DetectAppLayerMultiRegister( - "dns_query", ALPROTO_DNS, SIG_FLAG_TOSERVER, 1, DnsQueryGetData, 2, 1); - - DetectBufferTypeSetDescriptionByName("dns_query", - "dns request query"); - DetectBufferTypeSupportsMultiInstance("dns_query"); - - g_dns_query_buffer_id = DetectBufferTypeGetByName("dns_query"); -} - - -/** - * \brief setup the dns_query sticky buffer keyword used in the rule - * - * \param de_ctx Pointer to the Detection Engine Context - * \param s Pointer to the Signature to which the current keyword belongs - * \param str Should hold an empty string always - * - * \retval 0 On success - * \retval -1 On failure - */ - -static int DetectDnsQuerySetup(DetectEngineCtx *de_ctx, Signature *s, const char *str) -{ - if (DetectBufferSetActiveList(de_ctx, s, g_dns_query_buffer_id) < 0) - return -1; - if (DetectSignatureSetAppProto(s, ALPROTO_DNS) < 0) - return -1; - return 0; -} diff --git a/src/detect-dns-query.h b/src/detect-dns-query.h deleted file mode 100644 index 33270432c2..0000000000 --- a/src/detect-dns-query.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2013 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 Victor Julien - */ - -#ifndef SURICATA_DETECT_DNS_QUERY_H -#define SURICATA_DETECT_DNS_QUERY_H - -void DetectDnsQueryRegister (void); - -#endif /* SURICATA_DETECT_DNS_QUERY_H */ diff --git a/src/detect-dns-rcode.c b/src/detect-dns-rcode.c deleted file mode 100644 index 2f4412d895..0000000000 --- a/src/detect-dns-rcode.c +++ /dev/null @@ -1,85 +0,0 @@ -/* 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. - */ - -#include "suricata-common.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-dns-rcode.h" -#include "rust.h" -#include "detect-engine-uint.h" - -static int dns_rcode_list_id = 0; - -static void DetectDnsRcodeFree(DetectEngineCtx *, void *ptr); - -static int DetectDnsRcodeSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str) -{ - SCEnter(); - - if (DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0) { - SCReturnInt(-1); - } - - void *detect = DetectU8Parse(str); - if (detect == NULL) { - SCLogError("failed to parse dns.rcode: %s", str); - SCReturnInt(-1); - } - - if (SigMatchAppendSMToList( - de_ctx, s, DETECT_DNS_RCODE, (SigMatchCtx *)detect, dns_rcode_list_id) == NULL) { - DetectDnsRcodeFree(de_ctx, detect); - SCReturnInt(-1); - } - - SCReturnInt(0); -} - -static void DetectDnsRcodeFree(DetectEngineCtx *de_ctx, void *ptr) -{ - SCEnter(); - if (ptr != NULL) { - SCDetectU8Free(ptr); - } - SCReturn; -} - -static int DetectDnsRcodeMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state, - void *txv, const Signature *s, const SigMatchCtx *ctx) -{ - return SCDnsDetectRcodeMatch(txv, (void *)ctx, flags); -} - -void DetectDnsRcodeRegister(void) -{ - sigmatch_table[DETECT_DNS_RCODE].name = "dns.rcode"; - sigmatch_table[DETECT_DNS_RCODE].desc = "Match the DNS header rcode flag."; - sigmatch_table[DETECT_DNS_RCODE].url = "/rules/dns-keywords.html#dns-rcode"; - sigmatch_table[DETECT_DNS_RCODE].Setup = DetectDnsRcodeSetup; - sigmatch_table[DETECT_DNS_RCODE].Free = DetectDnsRcodeFree; - sigmatch_table[DETECT_DNS_RCODE].Match = NULL; - sigmatch_table[DETECT_DNS_RCODE].AppLayerTxMatch = DetectDnsRcodeMatch; - - DetectAppLayerInspectEngineRegister( - "dns.rcode", ALPROTO_DNS, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL); - - DetectAppLayerInspectEngineRegister( - "dns.rcode", ALPROTO_DNS, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectGenericList, NULL); - - dns_rcode_list_id = DetectBufferTypeGetByName("dns.rcode"); -} \ No newline at end of file diff --git a/src/detect-dns-rcode.h b/src/detect-dns-rcode.h deleted file mode 100644 index cd4188eb36..0000000000 --- a/src/detect-dns-rcode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* 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. - */ - -#ifndef SURICATA_DETECT_DNS_RCODE_H -#define SURICATA_DETECT_DNS_RCODE_H - -void DetectDnsRcodeRegister(void); - -#endif /* SURICATA_DETECT_DNS_RCODE_H */ \ No newline at end of file diff --git a/src/detect-dns-rrtype.c b/src/detect-dns-rrtype.c deleted file mode 100644 index 0c55412638..0000000000 --- a/src/detect-dns-rrtype.c +++ /dev/null @@ -1,85 +0,0 @@ -/* 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. - */ - -#include "suricata-common.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-dns-rrtype.h" -#include "rust.h" -#include "detect-engine-uint.h" - -static int dns_rrtype_list_id = 0; - -static void DetectDnsRrtypeFree(DetectEngineCtx *, void *ptr); - -static int DetectDnsRrtypeSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str) -{ - SCEnter(); - - if (DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0) { - SCReturnInt(-1); - } - - void *detect = DetectU16Parse(str); - if (detect == NULL) { - SCLogError("failed to parse dns.rrtype: %s", str); - SCReturnInt(-1); - } - - if (SigMatchAppendSMToList( - de_ctx, s, DETECT_DNS_RRTYPE, (SigMatchCtx *)detect, dns_rrtype_list_id) == NULL) { - DetectDnsRrtypeFree(de_ctx, detect); - SCReturnInt(-1); - } - - SCReturnInt(0); -} - -static void DetectDnsRrtypeFree(DetectEngineCtx *de_ctx, void *ptr) -{ - SCEnter(); - if (ptr != NULL) { - SCDetectU16Free(ptr); - } - SCReturn; -} - -static int DetectDnsRrtypeMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state, - void *txv, const Signature *s, const SigMatchCtx *ctx) -{ - return SCDnsDetectRrtypeMatch(txv, (void *)ctx, flags); -} - -void DetectDnsRrtypeRegister(void) -{ - sigmatch_table[DETECT_DNS_RRTYPE].name = "dns.rrtype"; - sigmatch_table[DETECT_DNS_RRTYPE].desc = "Match the DNS rrtype in message body."; - sigmatch_table[DETECT_DNS_RRTYPE].url = "/rules/dns-keywords.html#dns-rrtype"; - sigmatch_table[DETECT_DNS_RRTYPE].Setup = DetectDnsRrtypeSetup; - sigmatch_table[DETECT_DNS_RRTYPE].Free = DetectDnsRrtypeFree; - sigmatch_table[DETECT_DNS_RRTYPE].Match = NULL; - sigmatch_table[DETECT_DNS_RRTYPE].AppLayerTxMatch = DetectDnsRrtypeMatch; - - DetectAppLayerInspectEngineRegister( - "dns.rrtype", ALPROTO_DNS, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL); - - DetectAppLayerInspectEngineRegister( - "dns.rrtype", ALPROTO_DNS, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectGenericList, NULL); - - dns_rrtype_list_id = DetectBufferTypeGetByName("dns.rrtype"); -} \ No newline at end of file diff --git a/src/detect-dns-rrtype.h b/src/detect-dns-rrtype.h deleted file mode 100644 index e2913b4a1c..0000000000 --- a/src/detect-dns-rrtype.h +++ /dev/null @@ -1,23 +0,0 @@ -/* 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. - */ - -#ifndef SURICATA_DETECT_DNS_RRTYPE_H -#define SURICATA_DETECT_DNS_RRTYPE_H - -void DetectDnsRrtypeRegister(void); - -#endif /* SURICATA_DETECT_DNS_RRTYPE_H */ diff --git a/src/detect-engine-helper.c b/src/detect-engine-helper.c index 79d2128f11..3a4fc493b6 100644 --- a/src/detect-engine-helper.c +++ b/src/detect-engine-helper.c @@ -141,6 +141,11 @@ int DetectHelperKeywordRegister(const SCSigTableElmt *kw) return keyword_id; } +void DetectHelperKeywordAliasRegister(int kwid, const char *alias) +{ + sigmatch_table[kwid].alias = alias; +} + int DetectHelperTransformRegister(const SCTransformTableElmt *kw) { int transform_id = SCDetectHelperNewKeywordId(); diff --git a/src/detect-engine-helper.h b/src/detect-engine-helper.h index ed4de944d2..e85305259d 100644 --- a/src/detect-engine-helper.h +++ b/src/detect-engine-helper.h @@ -31,6 +31,7 @@ int SCDetectHelperNewKeywordId(void); int DetectHelperKeywordRegister(const SCSigTableElmt *kw); +void DetectHelperKeywordAliasRegister(int kwid, const char *alias); int DetectHelperBufferRegister(const char *name, AppProto alproto, bool toclient, bool toserver); typedef bool (*SimpleGetTxBuffer)(void *, uint8_t, const uint8_t **, uint32_t *); diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index 784640527c..cb3d1bf4c4 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -47,10 +47,6 @@ #include "detect-engine-payload.h" #include "detect-engine-dcepayload.h" -#include "detect-dns-opcode.h" -#include "detect-dns-rcode.h" -#include "detect-dns-rrtype.h" -#include "detect-dns-query.h" #include "detect-dns-name.h" #include "detect-dns-response.h" #include "detect-tls-sni.h" @@ -566,10 +562,6 @@ void SigTableSetup(void) DetectHttpStatCodeRegister(); DetectHttp2Register(); - DetectDnsQueryRegister(); - DetectDnsOpcodeRegister(); - DetectDnsRcodeRegister(); - DetectDnsRrtypeRegister(); DetectDnsNameRegister(); DetectDnsResponseRegister(); DetectModbusRegister(); @@ -763,6 +755,7 @@ void SigTableSetup(void) SCDetectTemplateRegister(); SCDetectLdapRegister(); SCDetectSdpRegister(); + SCDetectDNSRegister(); 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 396783c5a2..ad726bb3cd 100644 --- a/src/detect-engine-register.h +++ b/src/detect-engine-register.h @@ -242,11 +242,7 @@ enum DetectKeywordId { DETECT_L3PROTO, DETECT_IPREP, - DETECT_DNS_QUERY, - DETECT_DNS_OPCODE, - DETECT_DNS_RCODE, DETECT_DNS_RESPONSE, - DETECT_DNS_RRTYPE, DETECT_TLS_SNI, DETECT_TLS_CERTS, DETECT_TLS_CERT_ISSUER, -- 2.47.2