diff --git a/doc/userguide/rules/snmp-keywords.rst b/doc/userguide/rules/snmp-keywords.rst index a5349c2e5056..8429f0d805d7 100644 --- a/doc/userguide/rules/snmp-keywords.rst +++ b/doc/userguide/rules/snmp-keywords.rst @@ -6,6 +6,8 @@ snmp.version SNMP protocol version (integer). Expected values are 1, 2 (for version 2c) or 3. +snmp.version uses an, :ref:` unsigned 32-bits integer `. + Syntax:: snmp.version:[op] @@ -69,6 +71,8 @@ snmp.pdu_type SNMP PDU type (integer). +snmp.pdu_type uses an, :ref:` unsigned 32-bits integer `. + Common values are: - 0: GetRequest diff --git a/rust/src/snmp/detect.rs b/rust/src/snmp/detect.rs index bb4ffd12c3ba..7dee00a707b1 100644 --- a/rust/src/snmp/detect.rs +++ b/rust/src/snmp/detect.rs @@ -17,42 +17,251 @@ // written by Pierre Chifflier -use crate::snmp::snmp::SNMPTransaction; +use super::snmp::{SNMPTransaction, ALPROTO_SNMP}; +use crate::detect::uint::{ + rs_detect_u32_free, rs_detect_u32_match, rs_detect_u32_parse, DetectUintData, +}; +use crate::detect::{ + DetectBufferSetActiveList, DetectHelperBufferMpmRegister, DetectHelperBufferRegister, + DetectHelperGetData, DetectHelperKeywordRegister, DetectSignatureSetAppProto, SCSigTableElmt, + SigMatchAppendSMToList, SIGMATCH_INFO_STICKY_BUFFER, SIGMATCH_NOOPT, +}; +use std::os::raw::{c_int, c_void}; -#[no_mangle] -pub unsafe extern "C" fn rs_snmp_tx_get_version(tx: &mut SNMPTransaction, version: *mut u32) { - debug_assert!(tx.version != 0, "SNMP version is 0"); - *version = tx.version; +static mut G_SNMP_VERSION_KW_ID: c_int = 0; +static mut G_SNMP_VERSION_BUFFER_ID: c_int = 0; +static mut G_SNMP_PDUTYPE_KW_ID: c_int = 0; +static mut G_SNMP_PDUTYPE_BUFFER_ID: c_int = 0; +static mut G_SNMP_USM_BUFFER_ID: c_int = 0; +static mut G_SNMP_COMMUNITY_BUFFER_ID: c_int = 0; + +unsafe extern "C" fn snmp_detect_version_setup( + de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0 { + return -1; + } + let ctx = rs_detect_u32_parse(raw) as *mut c_void; + if ctx.is_null() { + return -1; + } + if SigMatchAppendSMToList(de, s, G_SNMP_VERSION_KW_ID, ctx, G_SNMP_VERSION_BUFFER_ID).is_null() + { + snmp_detect_version_free(std::ptr::null_mut(), ctx); + return -1; + } + return 0; } -#[no_mangle] -pub unsafe extern "C" fn rs_snmp_tx_get_community( - tx: &mut SNMPTransaction, buf: *mut *const u8, len: *mut u32, -) { - if let Some(ref c) = tx.community { - *buf = c.as_ptr(); - *len = c.len() as u32; +unsafe extern "C" fn snmp_detect_version_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, SNMPTransaction); + let ctx = cast_pointer!(ctx, DetectUintData); + return rs_detect_u32_match(tx.version, ctx); +} + +unsafe extern "C" fn snmp_detect_version_free(_de: *mut c_void, ctx: *mut c_void) { + // Just unbox... + let ctx = cast_pointer!(ctx, DetectUintData); + rs_detect_u32_free(ctx); +} + +unsafe extern "C" fn snmp_detect_pdutype_setup( + de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0 { + return -1; } + let ctx = rs_detect_u32_parse(raw) as *mut c_void; + if ctx.is_null() { + return -1; + } + if SigMatchAppendSMToList(de, s, G_SNMP_PDUTYPE_KW_ID, ctx, G_SNMP_PDUTYPE_BUFFER_ID).is_null() + { + snmp_detect_pdutype_free(std::ptr::null_mut(), ctx); + return -1; + } + return 0; } -#[no_mangle] -pub unsafe extern "C" fn rs_snmp_tx_get_pdu_type(tx: &mut SNMPTransaction, pdu_type: *mut u32) { - match tx.info { - Some(ref info) => { - *pdu_type = info.pdu_type.0; - } - None => { - *pdu_type = 0xffffffff; - } +unsafe extern "C" fn snmp_detect_pdutype_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, SNMPTransaction); + let ctx = cast_pointer!(ctx, DetectUintData); + if let Some(ref info) = tx.info { + let pdu_type = info.pdu_type.0; + return rs_detect_u32_match(pdu_type, ctx); + } + return 0; +} + +unsafe extern "C" fn snmp_detect_pdutype_free(_de: *mut c_void, ctx: *mut c_void) { + // Just unbox... + let ctx = cast_pointer!(ctx, DetectUintData); + rs_detect_u32_free(ctx); +} + +pub unsafe extern "C" fn snmp_detect_usm_setup( + de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0 { + return -1; + } + if DetectBufferSetActiveList(de, s, G_SNMP_USM_BUFFER_ID) < 0 { + return -1; } + return 0; } +pub unsafe extern "C" fn snmp_detect_usm_get( + tx: *const c_void, _flow_flags: u8, buffer: *mut *const u8, buffer_len: *mut u32, +) -> bool { + let tx = cast_pointer!(tx, SNMPTransaction); + if let Some(ref c) = tx.usm { + *buffer = c.as_ptr(); + *buffer_len = c.len() as u32; + return true; + } + return false; +} + +pub unsafe extern "C" fn snmp_detect_usm_get_data( + de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8, + tx: *const c_void, list_id: c_int, +) -> *mut c_void { + return DetectHelperGetData( + de, + transforms, + flow, + flow_flags, + tx, + list_id, + snmp_detect_usm_get, + ); +} + +pub unsafe extern "C" fn snmp_detect_community_setup( + de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, +) -> c_int { + if DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0 { + return -1; + } + if DetectBufferSetActiveList(de, s, G_SNMP_COMMUNITY_BUFFER_ID) < 0 { + return -1; + } + return 0; +} + +pub unsafe extern "C" fn snmp_detect_community_get( + tx: *const c_void, _flow_flags: u8, buffer: *mut *const u8, buffer_len: *mut u32, +) -> bool { + let tx = cast_pointer!(tx, SNMPTransaction); + if let Some(ref c) = tx.community { + *buffer = c.as_ptr(); + *buffer_len = c.len() as u32; + return true; + } + return false; +} + +pub unsafe extern "C" fn snmp_detect_community_get_data( + de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8, + tx: *const c_void, list_id: c_int, +) -> *mut c_void { + return DetectHelperGetData( + de, + transforms, + flow, + flow_flags, + tx, + list_id, + snmp_detect_community_get, + ); +} #[no_mangle] -pub unsafe extern "C" fn rs_snmp_tx_get_usm( - tx: &mut SNMPTransaction, buf: *mut *const u8, len: *mut u32, -) { - if let Some(ref c) = tx.usm { - *buf = c.as_ptr(); - *len = c.len() as u32; +pub unsafe extern "C" fn ScDetectSNMPRegister() { + let kw = SCSigTableElmt { + name: b"snmp.version\0".as_ptr() as *const libc::c_char, + desc: b"match SNMP version\0".as_ptr() as *const libc::c_char, + url: b"/rules/snmp-keywords.html#snmp-version\0".as_ptr() as *const libc::c_char, + AppLayerTxMatch: Some(snmp_detect_version_match), + Setup: snmp_detect_version_setup, + Free: Some(snmp_detect_version_free), + flags: 0, + }; + unsafe { + G_SNMP_VERSION_KW_ID = DetectHelperKeywordRegister(&kw); + G_SNMP_VERSION_BUFFER_ID = DetectHelperBufferRegister( + b"snmp.version\0".as_ptr() as *const libc::c_char, + ALPROTO_SNMP, + true, + true, + ); + } + + let kw = SCSigTableElmt { + name: b"snmp.pdu_type\0".as_ptr() as *const libc::c_char, + desc: b"match SNMP PDU type\0".as_ptr() as *const libc::c_char, + url: b"/rules/snmp-keywords.html#snmp-pdu-type\0".as_ptr() as *const libc::c_char, + AppLayerTxMatch: Some(snmp_detect_pdutype_match), + Setup: snmp_detect_pdutype_setup, + Free: Some(snmp_detect_pdutype_free), + flags: 0, + }; + unsafe { + G_SNMP_PDUTYPE_KW_ID = DetectHelperKeywordRegister(&kw); + G_SNMP_PDUTYPE_BUFFER_ID = DetectHelperBufferRegister( + b"snmp.pdu_type\0".as_ptr() as *const libc::c_char, + ALPROTO_SNMP, + true, + true, + ); + } + + let kw = SCSigTableElmt { + name: b"snmp.usm\0".as_ptr() as *const libc::c_char, + desc: b"SNMP content modifier to match on the SNMP usm\0".as_ptr() as *const libc::c_char, + url: b"/rules/snmp-keywords.html#snmp-usm\0".as_ptr() as *const libc::c_char, + Setup: snmp_detect_usm_setup, + flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER, + AppLayerTxMatch: None, + Free: None, + }; + unsafe { + let _g_snmp_usm_kw_id = DetectHelperKeywordRegister(&kw); + G_SNMP_USM_BUFFER_ID = DetectHelperBufferMpmRegister( + b"snmp.usm\0".as_ptr() as *const libc::c_char, + b"SNMP USM\0".as_ptr() as *const libc::c_char, + ALPROTO_SNMP, + true, + true, + snmp_detect_usm_get_data, + ); + } + + let kw = SCSigTableElmt { + name: b"snmp.community\0".as_ptr() as *const libc::c_char, + desc: b"SNMP content modifier to match on the SNMP community\0".as_ptr() + as *const libc::c_char, + url: b"/rules/snmp-keywords.html#snmp-community\0".as_ptr() as *const libc::c_char, + Setup: snmp_detect_community_setup, + flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER, + AppLayerTxMatch: None, + Free: None, + }; + unsafe { + let _g_snmp_community_kw_id = DetectHelperKeywordRegister(&kw); + G_SNMP_COMMUNITY_BUFFER_ID = DetectHelperBufferMpmRegister( + b"snmp.community\0".as_ptr() as *const libc::c_char, + b"SNMP Community identifier\0".as_ptr() as *const libc::c_char, + ALPROTO_SNMP, + true, + true, + snmp_detect_community_get_data, + ); } } diff --git a/rust/src/snmp/snmp.rs b/rust/src/snmp/snmp.rs index 3b78b47f7a1d..51aed9fb883f 100644 --- a/rust/src/snmp/snmp.rs +++ b/rust/src/snmp/snmp.rs @@ -322,7 +322,7 @@ pub extern "C" fn rs_snmp_tx_get_alstate_progress(_tx: *mut std::os::raw::c_void 1 } -static mut ALPROTO_SNMP : AppProto = ALPROTO_UNKNOWN; +pub(super) static mut ALPROTO_SNMP : AppProto = ALPROTO_UNKNOWN; // Read PDU sequence and extract version, if similar to SNMP definition fn parse_pdu_envelope_version(i:&[u8]) -> IResult<&[u8],u32> { diff --git a/src/Makefile.am b/src/Makefile.am index 42921842647b..c0b66a5f1dd5 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -294,10 +294,6 @@ noinst_HEADERS = \ detect-smb-ntlmssp.h \ detect-smb-share.h \ detect-smb-version.h \ - detect-snmp-community.h \ - detect-snmp-pdu_type.h \ - detect-snmp-usm.h \ - detect-snmp-version.h \ detect-dhcp-leasetime.h \ detect-dhcp-rebinding-time.h \ detect-dhcp-renewal-time.h \ @@ -903,10 +899,6 @@ libsuricata_c_a_SOURCES = \ detect-smb-ntlmssp.c \ detect-smb-share.c \ detect-smb-version.c \ - detect-snmp-community.c \ - detect-snmp-pdu_type.c \ - detect-snmp-usm.c \ - detect-snmp-version.c \ detect-dhcp-leasetime.c \ detect-dhcp-rebinding-time.c \ detect-dhcp-renewal-time.c \ @@ -1229,8 +1221,6 @@ EXTRA_DIST = \ tests/detect-http2.c \ tests/detect-icmpv6-mtu.c \ tests/detect-icmpv6hdr.c \ - tests/detect-snmp-pdu_type.c \ - tests/detect-snmp-version.c \ tests/detect-template.c \ tests/detect-transform-pcrexform.c \ tests/detect-transform-xor.c \ diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index c4070f0c5faf..3a096e6bfdaa 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -214,10 +214,6 @@ #include "detect-dhcp-leasetime.h" #include "detect-dhcp-rebinding-time.h" #include "detect-dhcp-renewal-time.h" -#include "detect-snmp-usm.h" -#include "detect-snmp-version.h" -#include "detect-snmp-community.h" -#include "detect-snmp-pdu_type.h" #include "detect-mqtt-type.h" #include "detect-mqtt-flags.h" #include "detect-mqtt-qos.h" @@ -703,10 +699,6 @@ void SigTableSetup(void) DetectDHCPLeaseTimeRegister(); DetectDHCPRebindingTimeRegister(); DetectDHCPRenewalTimeRegister(); - DetectSNMPUsmRegister(); - DetectSNMPVersionRegister(); - DetectSNMPCommunityRegister(); - DetectSNMPPduTypeRegister(); DetectMQTTTypeRegister(); DetectMQTTFlagsRegister(); DetectMQTTQosRegister(); @@ -751,6 +743,8 @@ void SigTableSetup(void) DetectFileHandlerRegister(); + ScDetectSNMPRegister(); + /* close keyword registration */ DetectBufferTypeCloseRegistration(); } diff --git a/src/detect-engine-register.h b/src/detect-engine-register.h index c740588236fa..500d1a4c8293 100644 --- a/src/detect-engine-register.h +++ b/src/detect-engine-register.h @@ -293,10 +293,6 @@ enum DetectKeywordId { DETECT_AL_DHCP_LEASETIME, DETECT_AL_DHCP_REBINDING_TIME, DETECT_AL_DHCP_RENEWAL_TIME, - DETECT_AL_SNMP_USM, - DETECT_AL_SNMP_VERSION, - DETECT_AL_SNMP_COMMUNITY, - DETECT_AL_SNMP_PDU_TYPE, DETECT_AL_MQTT_TYPE, DETECT_AL_MQTT_FLAGS, DETECT_AL_MQTT_QOS, diff --git a/src/detect-snmp-community.c b/src/detect-snmp-community.c deleted file mode 100644 index 76c4bddd0ab6..000000000000 --- a/src/detect-snmp-community.c +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright (C) 2015-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. - */ - -/** - * \file - * - * \author Pierre Chifflier - * - * Set up of the "snmp.community" keyword to allow content - * inspections on the decoded snmp community. - */ - -#include "suricata-common.h" -#include "conf.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-prefilter.h" -#include "detect-engine-content-inspection.h" -#include "detect-snmp-community.h" -#include "app-layer-parser.h" -#include "rust.h" - -static int DetectSNMPCommunitySetup(DetectEngineCtx *, Signature *, - const char *); -static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, - const int list_id); -static int g_snmp_rust_id = 0; - -void DetectSNMPCommunityRegister(void) -{ - sigmatch_table[DETECT_AL_SNMP_COMMUNITY].name = "snmp.community"; - sigmatch_table[DETECT_AL_SNMP_COMMUNITY].desc = - "SNMP content modifier to match on the SNMP community"; - sigmatch_table[DETECT_AL_SNMP_COMMUNITY].Setup = DetectSNMPCommunitySetup; - sigmatch_table[DETECT_AL_SNMP_COMMUNITY].url = "/rules/snmp-keywords.html#snmp-community"; - sigmatch_table[DETECT_AL_SNMP_COMMUNITY].flags |= SIGMATCH_NOOPT|SIGMATCH_INFO_STICKY_BUFFER; - - /* register inspect engines */ - DetectAppLayerInspectEngineRegister("snmp.community", ALPROTO_SNMP, SIG_FLAG_TOSERVER, 0, - DetectEngineInspectBufferGeneric, GetData); - DetectAppLayerMpmRegister("snmp.community", SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister, - GetData, ALPROTO_SNMP, 0); - DetectAppLayerInspectEngineRegister("snmp.community", ALPROTO_SNMP, SIG_FLAG_TOCLIENT, 0, - DetectEngineInspectBufferGeneric, GetData); - DetectAppLayerMpmRegister("snmp.community", SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister, - GetData, ALPROTO_SNMP, 0); - - DetectBufferTypeSetDescriptionByName("snmp.community", "SNMP Community identifier"); - - g_snmp_rust_id = DetectBufferTypeGetByName("snmp.community"); -} - -static int DetectSNMPCommunitySetup(DetectEngineCtx *de_ctx, Signature *s, - const char *str) -{ - if (DetectBufferSetActiveList(de_ctx, s, g_snmp_rust_id) < 0) - return -1; - - if (DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0) - return -1; - - return 0; -} - -static InspectionBuffer *GetData(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 data_len = 0; - const uint8_t *data = NULL; - - rs_snmp_tx_get_community(txv, &data, &data_len); - if (data == NULL || data_len == 0) { - return NULL; - } - - InspectionBufferSetup(det_ctx, list_id, buffer, data, data_len); - InspectionBufferApplyTransforms(buffer, transforms); - } - - return buffer; -} diff --git a/src/detect-snmp-community.h b/src/detect-snmp-community.h deleted file mode 100644 index 082d9c1970f6..000000000000 --- a/src/detect-snmp-community.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2015-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. - */ - -/** - * \file - * - * \author FirstName LastName - */ - -#ifndef SURICATA_DETECT_SNMP_COMMUNITY_H -#define SURICATA_DETECT_SNMP_COMMUNITY_H - -void DetectSNMPCommunityRegister(void); - -#endif /* SURICATA_DETECT_SNMP_COMMUNITY_H */ diff --git a/src/detect-snmp-pdu_type.c b/src/detect-snmp-pdu_type.c deleted file mode 100644 index 331abce7f355..000000000000 --- a/src/detect-snmp-pdu_type.c +++ /dev/null @@ -1,221 +0,0 @@ -/* Copyright (C) 2015-2020 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 Pierre Chifflier - */ - -#include "suricata-common.h" -#include "conf.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-content-inspection.h" -#include "detect-snmp-pdu_type.h" -#include "app-layer-parser.h" -#include "rust.h" - -/** - * [snmp.pdu_type]:; - */ -#define PARSE_REGEX "^\\s*([0-9]+)\\s*$" -static DetectParseRegex parse_regex; - -typedef struct DetectSNMPPduTypeData_ { - uint32_t pdu_type; -} DetectSNMPPduTypeData; - -static DetectSNMPPduTypeData *DetectSNMPPduTypeParse (const char *); -static int DetectSNMPPduTypeSetup (DetectEngineCtx *, Signature *s, const char *str); -static void DetectSNMPPduTypeFree(DetectEngineCtx *, void *); -#ifdef UNITTESTS -static void DetectSNMPPduTypeRegisterTests(void); -#endif -static int g_snmp_pdu_type_buffer_id = 0; - -static int DetectSNMPPduTypeMatch (DetectEngineThreadCtx *, Flow *, - uint8_t, void *, void *, const Signature *, - const SigMatchCtx *); - -void DetectSNMPPduTypeRegister(void) -{ - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].name = "snmp.pdu_type"; - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].desc = "match SNMP PDU type"; - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].url = "/rules/snmp-keywords.html#snmp-pdu-type"; - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].Match = NULL; - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].AppLayerTxMatch = DetectSNMPPduTypeMatch; - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].Setup = DetectSNMPPduTypeSetup; - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].Free = DetectSNMPPduTypeFree; -#ifdef UNITTESTS - sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].RegisterTests = DetectSNMPPduTypeRegisterTests; -#endif - - DetectSetupParseRegexes(PARSE_REGEX, &parse_regex); - - DetectAppLayerInspectEngineRegister("snmp.pdu_type", ALPROTO_SNMP, SIG_FLAG_TOSERVER, 0, - DetectEngineInspectGenericList, NULL); - - DetectAppLayerInspectEngineRegister("snmp.pdu_type", ALPROTO_SNMP, SIG_FLAG_TOCLIENT, 0, - DetectEngineInspectGenericList, NULL); - - g_snmp_pdu_type_buffer_id = DetectBufferTypeGetByName("snmp.pdu_type"); -} - -/** - * \internal - * \brief Function to match pdu_type of a TX - * - * \param t Pointer to thread vars. - * \param det_ctx Pointer to the pattern matcher thread. - * \param f Pointer to the current flow. - * \param flags Flags. - * \param state App layer state. - * \param s Pointer to the Signature. - * \param m Pointer to the sigmatch that we will cast into - * DetectSNMPPduTypeData. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DetectSNMPPduTypeMatch (DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *state, - void *txv, const Signature *s, - const SigMatchCtx *ctx) -{ - SCEnter(); - - const DetectSNMPPduTypeData *dd = (const DetectSNMPPduTypeData *)ctx; - uint32_t pdu_type; - rs_snmp_tx_get_pdu_type(txv, &pdu_type); - SCLogDebug("pdu_type %u ref_pdu_type %d", - pdu_type, dd->pdu_type); - if (pdu_type == dd->pdu_type) - SCReturnInt(1); - SCReturnInt(0); -} - -/** - * \internal - * \brief Function to parse options passed via snmp.pdu_type keywords. - * - * \param rawstr Pointer to the user provided options. - * - * \retval dd pointer to DetectSNMPPduTypeData on success. - * \retval NULL on failure. - */ -static DetectSNMPPduTypeData *DetectSNMPPduTypeParse (const char *rawstr) -{ - DetectSNMPPduTypeData *dd = NULL; - int res = 0; - size_t pcre2len; - char value1[20] = ""; - char *endptr = NULL; - - pcre2_match_data *match = NULL; - int ret = DetectParsePcreExec(&parse_regex, &match, rawstr, 0, 0); - if (ret != 2) { - SCLogError("Parse error %s", rawstr); - goto error; - } - - pcre2len = sizeof(value1); - res = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)value1, &pcre2len); - if (res < 0) { - SCLogError("pcre2_substring_copy_bynumber failed"); - goto error; - } - - dd = SCCalloc(1, sizeof(DetectSNMPPduTypeData)); - if (unlikely(dd == NULL)) - goto error; - - /* set the value */ - dd->pdu_type = strtoul(value1, &endptr, 10); - if (endptr == NULL || *endptr != '\0') { - SCLogError("invalid character as arg " - "to snmp.pdu_type keyword"); - goto error; - } - - pcre2_match_data_free(match); - return dd; - -error: - if (match) { - pcre2_match_data_free(match); - } - if (dd) - SCFree(dd); - return NULL; -} - -/** - * \brief Function to add the parsed snmp pdu_type field 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 flags options. - * \param type Defines if this is notBefore or notAfter. - * - * \retval 0 on Success. - * \retval -1 on Failure. - */ -static int DetectSNMPPduTypeSetup (DetectEngineCtx *de_ctx, Signature *s, - const char *rawstr) -{ - DetectSNMPPduTypeData *dd = NULL; - - if (DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0) - return -1; - - dd = DetectSNMPPduTypeParse(rawstr); - if (dd == NULL) { - SCLogError("Parsing \'%s\' failed", rawstr); - goto error; - } - - /* okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - - SCLogDebug("snmp.pdu_type %d", dd->pdu_type); - if (SigMatchAppendSMToList(de_ctx, s, DETECT_AL_SNMP_PDU_TYPE, (SigMatchCtx *)dd, - g_snmp_pdu_type_buffer_id) == NULL) { - goto error; - } - return 0; - -error: - DetectSNMPPduTypeFree(de_ctx, dd); - return -1; -} - -/** - * \internal - * \brief Function to free memory associated with DetectSNMPPduTypeData. - * - * \param de_ptr Pointer to DetectSNMPPduTypeData. - */ -static void DetectSNMPPduTypeFree(DetectEngineCtx *de_ctx, void *ptr) -{ - SCFree(ptr); -} - -#ifdef UNITTESTS -#include "tests/detect-snmp-pdu_type.c" -#endif /* UNITTESTS */ diff --git a/src/detect-snmp-pdu_type.h b/src/detect-snmp-pdu_type.h deleted file mode 100644 index a01dc98d4580..000000000000 --- a/src/detect-snmp-pdu_type.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2015-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. - */ - -/** - * \file - * - * \author Pierre Chifflier - */ - -#ifndef SURICATA_DETECT_SNMP_PDU_TYPE_H -#define SURICATA_DETECT_SNMP_PDU_TYPE_H - -void DetectSNMPPduTypeRegister(void); - -#endif /* SURICATA_DETECT_SNMP_PDU_TYPE_H */ diff --git a/src/detect-snmp-usm.c b/src/detect-snmp-usm.c deleted file mode 100644 index fd1a814d164d..000000000000 --- a/src/detect-snmp-usm.c +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright (C) 2022 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 "rust.h" -#include "detect-snmp-usm.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-prefilter.h" -#include "detect-parse.h" - -static int g_buffer_id = 0; - -static int DetectSNMPUsmSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str) -{ - if (DetectBufferSetActiveList(de_ctx, s, g_buffer_id) < 0) - return -1; - - if (DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0) - return -1; - - return 0; -} - -static InspectionBuffer *GetData(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 data_len = 0; - const uint8_t *data = NULL; - - rs_snmp_tx_get_usm(txv, &data, &data_len); - if (data == NULL || data_len == 0) { - return NULL; - } - - InspectionBufferSetup(det_ctx, list_id, buffer, data, data_len); - InspectionBufferApplyTransforms(buffer, transforms); - } - - return buffer; -} - -void DetectSNMPUsmRegister(void) -{ - sigmatch_table[DETECT_AL_SNMP_USM].name = "snmp.usm"; - sigmatch_table[DETECT_AL_SNMP_USM].desc = "SNMP content modifier to match on the SNMP usm"; - sigmatch_table[DETECT_AL_SNMP_USM].Setup = DetectSNMPUsmSetup; - - sigmatch_table[DETECT_AL_SNMP_USM].flags |= SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER; - - /* register inspect engines */ - DetectAppLayerInspectEngineRegister("snmp.usm", ALPROTO_SNMP, SIG_FLAG_TOSERVER, 0, - DetectEngineInspectBufferGeneric, GetData); - DetectAppLayerMpmRegister("snmp.usm", SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister, - GetData, ALPROTO_SNMP, 0); - DetectAppLayerInspectEngineRegister("snmp.usm", ALPROTO_SNMP, SIG_FLAG_TOCLIENT, 0, - DetectEngineInspectBufferGeneric, GetData); - DetectAppLayerMpmRegister("snmp.usm", SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister, - GetData, ALPROTO_SNMP, 0); - - DetectBufferTypeSetDescriptionByName("snmp.usm", "SNMP USM"); - - g_buffer_id = DetectBufferTypeGetByName("snmp.usm"); -} diff --git a/src/detect-snmp-usm.h b/src/detect-snmp-usm.h deleted file mode 100644 index 9c86dad807b7..000000000000 --- a/src/detect-snmp-usm.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (C) 2022 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_SNMP_USM_H -#define SURICATA_DETECT_SNMP_USM_H - -void DetectSNMPUsmRegister(void); - -#endif /* SURICATA_DETECT_SNMP_USM_H */ diff --git a/src/detect-snmp-version.c b/src/detect-snmp-version.c deleted file mode 100644 index cde70f251024..000000000000 --- a/src/detect-snmp-version.c +++ /dev/null @@ -1,174 +0,0 @@ -/* Copyright (C) 2015-2020 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 Pierre Chifflier - */ - -#include "suricata-common.h" -#include "conf.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-content-inspection.h" -#include "detect-snmp-version.h" -#include "detect-engine-uint.h" -#include "app-layer-parser.h" -#include "rust.h" - - -static int DetectSNMPVersionSetup (DetectEngineCtx *, Signature *s, const char *str); -static void DetectSNMPVersionFree(DetectEngineCtx *, void *); -#ifdef UNITTESTS -static void DetectSNMPVersionRegisterTests(void); -#endif -static int g_snmp_version_buffer_id = 0; - -static int DetectSNMPVersionMatch (DetectEngineThreadCtx *, Flow *, - uint8_t, void *, void *, const Signature *, - const SigMatchCtx *); - -/** - * \brief Registration function for snmp.procedure keyword. - */ -void DetectSNMPVersionRegister (void) -{ - sigmatch_table[DETECT_AL_SNMP_VERSION].name = "snmp.version"; - sigmatch_table[DETECT_AL_SNMP_VERSION].desc = "match SNMP version"; - sigmatch_table[DETECT_AL_SNMP_VERSION].url = "/rules/snmp-keywords.html#snmp-version"; - sigmatch_table[DETECT_AL_SNMP_VERSION].Match = NULL; - sigmatch_table[DETECT_AL_SNMP_VERSION].AppLayerTxMatch = DetectSNMPVersionMatch; - sigmatch_table[DETECT_AL_SNMP_VERSION].Setup = DetectSNMPVersionSetup; - sigmatch_table[DETECT_AL_SNMP_VERSION].Free = DetectSNMPVersionFree; -#ifdef UNITTESTS - sigmatch_table[DETECT_AL_SNMP_VERSION].RegisterTests = DetectSNMPVersionRegisterTests; -#endif - - DetectAppLayerInspectEngineRegister("snmp.version", ALPROTO_SNMP, SIG_FLAG_TOSERVER, 0, - DetectEngineInspectGenericList, NULL); - - DetectAppLayerInspectEngineRegister("snmp.version", ALPROTO_SNMP, SIG_FLAG_TOCLIENT, 0, - DetectEngineInspectGenericList, NULL); - - g_snmp_version_buffer_id = DetectBufferTypeGetByName("snmp.version"); -} - -/** - * \internal - * \brief Function to match version of a TX - * - * \param t Pointer to thread vars. - * \param det_ctx Pointer to the pattern matcher thread. - * \param f Pointer to the current flow. - * \param flags Flags. - * \param state App layer state. - * \param s Pointer to the Signature. - * \param m Pointer to the sigmatch that we will cast into - * DetectU32Data. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DetectSNMPVersionMatch (DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *state, - void *txv, const Signature *s, - const SigMatchCtx *ctx) -{ - SCEnter(); - - const DetectU32Data *dd = (const DetectU32Data *)ctx; - uint32_t version; - rs_snmp_tx_get_version(txv, &version); - SCLogDebug("version %u mode %u ref_version %d", version, dd->mode, dd->arg1); - if (DetectU32Match(version, dd)) - SCReturnInt(1); - SCReturnInt(0); -} - -/** - * \internal - * \brief Function to parse options passed via snmp.version keywords. - * - * \param rawstr Pointer to the user provided options. - * - * \retval dd pointer to DetectU32Data on success. - * \retval NULL on failure. - */ -static DetectU32Data *DetectSNMPVersionParse(const char *rawstr) -{ - return DetectU32Parse(rawstr); -} - - - -/** - * \brief Function to add the parsed snmp version field 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 flags options. - * \param type Defines if this is notBefore or notAfter. - * - * \retval 0 on Success. - * \retval -1 on Failure. - */ -static int DetectSNMPVersionSetup (DetectEngineCtx *de_ctx, Signature *s, - const char *rawstr) -{ - DetectU32Data *dd = NULL; - - if (DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0) - return -1; - - dd = DetectSNMPVersionParse(rawstr); - if (dd == NULL) { - SCLogError("Parsing \'%s\' failed", rawstr); - goto error; - } - - /* okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - - SCLogDebug("snmp.version %d", dd->arg1); - if (SigMatchAppendSMToList(de_ctx, s, DETECT_AL_SNMP_VERSION, (SigMatchCtx *)dd, - g_snmp_version_buffer_id) == NULL) { - goto error; - } - return 0; - -error: - DetectSNMPVersionFree(de_ctx, dd); - return -1; -} - -/** - * \internal - * \brief Function to free memory associated with DetectU32Data. - * - * \param de_ptr Pointer to DetectU32Data. - */ -static void DetectSNMPVersionFree(DetectEngineCtx *de_ctx, void *ptr) -{ - rs_detect_u32_free(ptr); -} - - -#ifdef UNITTESTS -#include "tests/detect-snmp-version.c" -#endif /* UNITTESTS */ diff --git a/src/detect-snmp-version.h b/src/detect-snmp-version.h deleted file mode 100644 index cd71b59a245c..000000000000 --- a/src/detect-snmp-version.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2015-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. - */ - -/** - * \file - * - * \author Pierre Chifflier - */ - -#ifndef SURICATA_DETECT_SNMP_VERSION_H -#define SURICATA_DETECT_SNMP_VERSION_H - -void DetectSNMPVersionRegister(void); - -#endif /* SURICATA_DETECT_SNMP_VERSION_H */ diff --git a/src/tests/detect-snmp-pdu_type.c b/src/tests/detect-snmp-pdu_type.c deleted file mode 100644 index 0e7693bcc625..000000000000 --- a/src/tests/detect-snmp-pdu_type.c +++ /dev/null @@ -1,40 +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 "util-unittest.h" -#include "util-unittest-helper.h" - -/** - * \test This is a test for a valid value 2. - * - * \retval 1 on success. - * \retval 0 on failure. - */ -static int SNMPValidityTestParse01 (void) -{ - DetectSNMPPduTypeData *dd = NULL; - dd = DetectSNMPPduTypeParse("2"); - FAIL_IF_NULL(dd); - FAIL_IF_NOT(dd->pdu_type == 2); - DetectSNMPPduTypeFree(NULL, dd); - PASS; -} - -static void DetectSNMPPduTypeRegisterTests(void) -{ - UtRegisterTest("SNMPValidityTestParse01", SNMPValidityTestParse01); -} diff --git a/src/tests/detect-snmp-version.c b/src/tests/detect-snmp-version.c deleted file mode 100644 index 5da24b1b8700..000000000000 --- a/src/tests/detect-snmp-version.c +++ /dev/null @@ -1,57 +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 "util-unittest.h" -#include "util-unittest-helper.h" - -/** - * \test This is a test for a valid value 2. - * - * \retval 1 on success. - * \retval 0 on failure. - */ -static int SNMPValidityTestParse01 (void) -{ - DetectU32Data *dd = NULL; - dd = DetectSNMPVersionParse("2"); - FAIL_IF_NULL(dd); - FAIL_IF_NOT(dd->arg1 == 2 && dd->mode == DETECT_UINT_EQ); - DetectSNMPVersionFree(NULL, dd); - PASS; -} - -/** - * \test This is a test for a valid value >2. - * - * \retval 1 on success. - * \retval 0 on failure. - */ -static int SNMPValidityTestParse02 (void) -{ - DetectU32Data *dd = NULL; - dd = DetectSNMPVersionParse(">2"); - FAIL_IF_NULL(dd); - FAIL_IF_NOT(dd->arg1 == 2 && dd->mode == DETECT_UINT_GT); - DetectSNMPVersionFree(NULL, dd); - PASS; -} - -static void DetectSNMPVersionRegisterTests(void) -{ - UtRegisterTest("SNMPValidityTestParse01", SNMPValidityTestParse01); - UtRegisterTest("SNMPValidityTestParse02", SNMPValidityTestParse02); -}