mirror of https://github.com/OISF/suricata
detect/snmp: move keywords to rust
Ticket: 4863 On the way, convert unit test DetectSNMPCommunityTest to a SV test. And also, make snmp.pdu_type use a generic uint32 for detection, allowing operators, instead of just equality.pull/11309/head
parent
4bbe7d92dc
commit
ae72376ebe
@ -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 <chifflier@wzdftpd.net>
|
||||
*
|
||||
* 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;
|
||||
}
|
@ -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 <yourname@domain>
|
||||
*/
|
||||
|
||||
#ifndef SURICATA_DETECT_SNMP_COMMUNITY_H
|
||||
#define SURICATA_DETECT_SNMP_COMMUNITY_H
|
||||
|
||||
void DetectSNMPCommunityRegister(void);
|
||||
|
||||
#endif /* SURICATA_DETECT_SNMP_COMMUNITY_H */
|
@ -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 <chifflier@wzdftpd.net>
|
||||
*/
|
||||
|
||||
#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]:<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 */
|
@ -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 <chifflier@wzdftpd.net>
|
||||
*/
|
||||
|
||||
#ifndef SURICATA_DETECT_SNMP_PDU_TYPE_H
|
||||
#define SURICATA_DETECT_SNMP_PDU_TYPE_H
|
||||
|
||||
void DetectSNMPPduTypeRegister(void);
|
||||
|
||||
#endif /* SURICATA_DETECT_SNMP_PDU_TYPE_H */
|
@ -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");
|
||||
}
|
@ -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 */
|
@ -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 <chifflier@wzdftpd.net>
|
||||
*/
|
||||
|
||||
#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 */
|
@ -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 <chifflier@wzdftpd.net>
|
||||
*/
|
||||
|
||||
#ifndef SURICATA_DETECT_SNMP_VERSION_H
|
||||
#define SURICATA_DETECT_SNMP_VERSION_H
|
||||
|
||||
void DetectSNMPVersionRegister(void);
|
||||
|
||||
#endif /* SURICATA_DETECT_SNMP_VERSION_H */
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue