diff --git a/rust/src/mqtt/detect.rs b/rust/src/mqtt/detect.rs index df0c78e8497f..b4ee22992b55 100644 --- a/rust/src/mqtt/detect.rs +++ b/rust/src/mqtt/detect.rs @@ -168,15 +168,15 @@ pub unsafe extern "C" fn rs_mqtt_tx_get_connect_username( #[no_mangle] pub unsafe extern "C" fn rs_mqtt_tx_get_connect_password( - tx: &MQTTTransaction, buffer: *mut *const u8, buffer_len: *mut u32, -) -> u8 { + tx: &MQTTTransaction, _flow_flags: u8, buffer: *mut *const u8, buffer_len: *mut u32, +) -> bool { for msg in tx.msg.iter() { if let MQTTOperation::CONNECT(ref cv) = msg.op { if let Some(p) = &cv.password { if !p.is_empty() { *buffer = p.as_ptr(); *buffer_len = p.len() as u32; - return 1; + return true; } } } @@ -184,7 +184,7 @@ pub unsafe extern "C" fn rs_mqtt_tx_get_connect_password( *buffer = ptr::null(); *buffer_len = 0; - return 0; + return false; } #[no_mangle] diff --git a/src/Makefile.am b/src/Makefile.am index 1d5188474483..7ab0b06bc6b9 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -137,6 +137,7 @@ noinst_HEADERS = \ detect-engine-file.h \ detect-engine-frame.h \ detect-engine.h \ + detect-engine-helper.h \ detect-engine-iponly.h \ detect-engine-loader.h \ detect-engine-mpm.h \ @@ -741,6 +742,7 @@ libsuricata_c_a_SOURCES = \ detect-engine-event.c \ detect-engine-file.c \ detect-engine-frame.c \ + detect-engine-helper.c \ detect-engine-iponly.c \ detect-engine-loader.c \ detect-engine-mpm.c \ diff --git a/src/detect-engine-helper.c b/src/detect-engine-helper.c new file mode 100644 index 000000000000..634afd3f1c40 --- /dev/null +++ b/src/detect-engine-helper.c @@ -0,0 +1,110 @@ +/* Copyright (C) 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. + */ + +/** + * \file + * + * \author Philippe Antoine + * + */ + +#include "suricata-common.h" +#include "detect-engine.h" +#include "detect-engine-helper.h" +#include "detect-engine-mpm.h" +#include "detect-engine-prefilter.h" +#include "detect-parse.h" + +int DetectHelperBufferRegister(const char *name, AppProto alproto, bool toclient, bool toserver) +{ + if (toserver) { + DetectAppLayerInspectEngineRegister2( + name, alproto, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL); + } + if (toclient) { + DetectAppLayerInspectEngineRegister2( + name, alproto, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectGenericList, NULL); + } + return DetectBufferTypeRegister(name); +} + +InspectionBuffer *DetectHelperGetData(struct DetectEngineThreadCtx_ *det_ctx, + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, + const int list_id, + bool (*GetBuf)(void *txv, const uint8_t flow_flags, const uint8_t **buf, uint32_t *buf_len)) +{ + InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); + if (buffer->inspect == NULL) { + const uint8_t *b = NULL; + uint32_t b_len = 0; + + if (!GetBuf(txv, flow_flags, &b, &b_len)) + return NULL; + + InspectionBufferSetup(det_ctx, list_id, buffer, b, b_len); + InspectionBufferApplyTransforms(buffer, transforms); + } + return buffer; +} + +int DetectHelperBufferMpmRegister(const char *name, const char *desc, AppProto alproto, + bool toclient, bool toserver, InspectionBufferGetDataPtr GetData) +{ + if (toserver) { + DetectAppLayerInspectEngineRegister2( + name, alproto, SIG_FLAG_TOSERVER, 0, DetectEngineInspectBufferGeneric, GetData); + DetectAppLayerMpmRegister2( + name, SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister, GetData, alproto, 0); + } + if (toclient) { + DetectAppLayerInspectEngineRegister2( + name, alproto, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectBufferGeneric, GetData); + DetectAppLayerMpmRegister2( + name, SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister, GetData, alproto, 0); + } + DetectBufferTypeSetDescriptionByName(name, desc); + return DetectBufferTypeGetByName(name); +} + +int DetectHelperKeywordRegister(const SCPluginSigTableElmt *kw) +{ + if (DETECT_TBLSIZE_IDX < DETECT_TBLSIZE) { + sigmatch_table[DETECT_TBLSIZE_IDX].name = kw->name; + sigmatch_table[DETECT_TBLSIZE_IDX].desc = kw->desc; + sigmatch_table[DETECT_TBLSIZE_IDX].flags = kw->flags; + sigmatch_table[DETECT_TBLSIZE_IDX].AppLayerTxMatch = kw->AppLayerTxMatch; + sigmatch_table[DETECT_TBLSIZE_IDX].Setup = kw->Setup; + sigmatch_table[DETECT_TBLSIZE_IDX].Free = kw->Free; + DETECT_TBLSIZE_IDX++; + return DETECT_TBLSIZE_IDX - 1; + } + return -1; +} + +int DetectHelperKeywordSetup(DetectEngineCtx *de_ctx, AppProto alproto, uint16_t kw_id, int buf_id, + Signature *s, void *ctx) +{ + if (DetectSignatureSetAppProto(s, alproto) != 0) + return -1; + + /* okay so far so good, lets get this into a SigMatch + * and put it in the Signature. */ + if (SigMatchAppendSMToList(de_ctx, s, kw_id, (SigMatchCtx *)ctx, buf_id) == NULL) { + return -1; + } + return 0; +} diff --git a/src/detect-engine-helper.h b/src/detect-engine-helper.h new file mode 100644 index 000000000000..9291c0f1e27e --- /dev/null +++ b/src/detect-engine-helper.h @@ -0,0 +1,54 @@ +/* Copyright (C) 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. + */ + +/** + * \file + * + * \author Philippe Antoine + */ + +#ifndef __DETECT_ENGINE_HELPER_H +#define __DETECT_ENGINE_HELPER_H + +#include "app-layer-protos.h" +#include "detect.h" + +// Structure for keyword dynamic registration by plugin +typedef struct SCPluginSigTableElmt { + const char *name; + const char *desc; + uint16_t flags; + int (*Setup)(DetectEngineCtx *, Signature *, const char *); + void (*Free)(DetectEngineCtx *, void *); + int (*AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, + const Signature *, const SigMatchCtx *); +} SCPluginSigTableElmt; + +int DetectHelperKeywordRegister(const SCPluginSigTableElmt *kw); +int DetectHelperBufferRegister(const char *name, AppProto alproto, bool toclient, bool toserver); + +typedef bool (*SimpleGetTxBuffer)(void *, uint8_t, const uint8_t **, uint32_t *); + +int DetectHelperKeywordSetup(DetectEngineCtx *de_ctx, AppProto alproto, uint16_t kw_id, int buf_id, + Signature *s, void *ctx); +InspectionBuffer *DetectHelperGetData(struct DetectEngineThreadCtx_ *det_ctx, + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, + const int list_id, SimpleGetTxBuffer GetBuf); +int DetectHelperBufferMpmRegister(const char *name, const char *desc, AppProto alproto, + bool toclient, bool toserver, InspectionBufferGetDataPtr GetData); + +#endif /* __DETECT_ENGINE_HELPER_H */ diff --git a/src/detect-mqtt-connect-password.c b/src/detect-mqtt-connect-password.c index c08390748fe0..6749629a017e 100644 --- a/src/detect-mqtt-connect-password.c +++ b/src/detect-mqtt-connect-password.c @@ -26,6 +26,7 @@ #include "detect.h" #include "detect-parse.h" #include "detect-engine.h" +#include "detect-engine-helper.h" #include "detect-engine-mpm.h" #include "detect-engine-prefilter.h" #include "detect-mqtt-connect-password.h" @@ -49,24 +50,11 @@ static int DetectMQTTConnectPasswordSetup(DetectEngineCtx *de_ctx, Signature *s, } static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, - Flow *_f, const uint8_t _flow_flags, - void *txv, const int list_id) + 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) { - const uint8_t *b = NULL; - uint32_t b_len = 0; - - if (rs_mqtt_tx_get_connect_password(txv, &b, &b_len) != 1) - return NULL; - if (b == NULL || b_len == 0) - return NULL; - - InspectionBufferSetup(det_ctx, list_id, buffer, b, b_len); - InspectionBufferApplyTransforms(buffer, transforms); - } - return buffer; + return DetectHelperGetData(det_ctx, transforms, _f, flow_flags, txv, list_id, + (SimpleGetTxBuffer)rs_mqtt_tx_get_connect_password); } void DetectMQTTConnectPasswordRegister(void) @@ -78,17 +66,8 @@ void DetectMQTTConnectPasswordRegister(void) sigmatch_table[DETECT_AL_MQTT_CONNECT_PASSWORD].Setup = DetectMQTTConnectPasswordSetup; sigmatch_table[DETECT_AL_MQTT_CONNECT_PASSWORD].flags |= SIGMATCH_NOOPT; - DetectAppLayerInspectEngineRegister2(BUFFER_NAME, ALPROTO_MQTT, - SIG_FLAG_TOSERVER, 0, - DetectEngineInspectBufferGeneric, GetData); - - DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOSERVER, 2, - PrefilterGenericMpmRegister, GetData, ALPROTO_MQTT, - 1); - - DetectBufferTypeSetDescriptionByName(BUFFER_NAME, BUFFER_DESC); - - g_buffer_id = DetectBufferTypeGetByName(BUFFER_NAME); + g_buffer_id = DetectHelperBufferMpmRegister( + BUFFER_NAME, BUFFER_DESC, ALPROTO_MQTT, false, true, GetData); SCLogDebug("registering " BUFFER_NAME " rule option"); } diff --git a/src/detect-snmp-version.c b/src/detect-snmp-version.c index 64029659381e..3400452e7d0b 100644 --- a/src/detect-snmp-version.c +++ b/src/detect-snmp-version.c @@ -29,6 +29,7 @@ #include "detect-engine-content-inspection.h" #include "detect-snmp-version.h" #include "detect-engine-uint.h" +#include "detect-engine-helper.h" #include "app-layer-parser.h" #include "rust.h" @@ -60,13 +61,7 @@ void DetectSNMPVersionRegister (void) sigmatch_table[DETECT_AL_SNMP_VERSION].RegisterTests = DetectSNMPVersionRegisterTests; #endif - DetectAppLayerInspectEngineRegister2("snmp.version", ALPROTO_SNMP, SIG_FLAG_TOSERVER, 0, - DetectEngineInspectGenericList, NULL); - - DetectAppLayerInspectEngineRegister2("snmp.version", ALPROTO_SNMP, SIG_FLAG_TOCLIENT, 0, - DetectEngineInspectGenericList, NULL); - - g_snmp_version_buffer_id = DetectBufferTypeGetByName("snmp.version"); + g_snmp_version_buffer_id = DetectHelperBufferRegister("snmp.version", ALPROTO_SNMP, true, true); } /** @@ -131,30 +126,18 @@ static DetectU32Data *DetectSNMPVersionParse(const char *rawstr) 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); + DetectU32Data *dd = DetectSNMPVersionParse(rawstr); if (dd == NULL) { SCLogError("Parsing \'%s\' failed", rawstr); - goto error; + return -1; } - - /* 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; + if (DetectHelperKeywordSetup(de_ctx, ALPROTO_SNMP, DETECT_AL_SNMP_VERSION, + g_snmp_version_buffer_id, s, dd) < 0) { + DetectSNMPVersionFree(de_ctx, dd); + return -1; } + SCLogDebug("snmp.version %d", dd->arg1); return 0; - -error: - DetectSNMPVersionFree(de_ctx, dd); - return -1; } /**