Coverage Report

Created: 2025-07-23 07:29

/src/suricata7/src/detect-ike-nonce-payload-length.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2020 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17
18
/**
19
 *
20
 * \author Frank Honza <frank.honza@dcso.de>
21
 */
22
23
#include "suricata-common.h"
24
#include "conf.h"
25
#include "detect.h"
26
#include "detect-parse.h"
27
#include "detect-engine.h"
28
#include "detect-engine-content-inspection.h"
29
#include "detect-ike-nonce-payload-length.h"
30
#include "app-layer-parser.h"
31
#include "util-byte.h"
32
#include "detect-engine-uint.h"
33
34
#include "rust-bindings.h"
35
36
/**
37
 *   [ike.nonce_payload_length]:[=|<|>|<=|>=]<length>;
38
 */
39
static int DetectIkeNoncePayloadLengthSetup(DetectEngineCtx *, Signature *s, const char *str);
40
static void DetectIkeNoncePayloadLengthFree(DetectEngineCtx *, void *);
41
static int g_ike_nonce_payload_length_buffer_id = 0;
42
43
static int DetectIkeNoncePayloadLengthMatch(DetectEngineThreadCtx *, Flow *, uint8_t, void *,
44
        void *, const Signature *, const SigMatchCtx *);
45
46
/**
47
 * \brief Registration function for ike.nonce_payload_length keyword.
48
 */
49
void DetectIkeNoncePayloadLengthRegister(void)
50
73
{
51
73
    sigmatch_table[DETECT_AL_IKE_NONCE_PAYLOAD_LENGTH].name = "ike.nonce_payload_length";
52
73
    sigmatch_table[DETECT_AL_IKE_NONCE_PAYLOAD_LENGTH].desc = "match IKE nonce payload length";
53
73
    sigmatch_table[DETECT_AL_IKE_NONCE_PAYLOAD_LENGTH].url =
54
73
            "/rules/ike-keywords.html#ike-nonce-payload-length";
55
73
    sigmatch_table[DETECT_AL_IKE_NONCE_PAYLOAD_LENGTH].AppLayerTxMatch =
56
73
            DetectIkeNoncePayloadLengthMatch;
57
73
    sigmatch_table[DETECT_AL_IKE_NONCE_PAYLOAD_LENGTH].Setup = DetectIkeNoncePayloadLengthSetup;
58
73
    sigmatch_table[DETECT_AL_IKE_NONCE_PAYLOAD_LENGTH].Free = DetectIkeNoncePayloadLengthFree;
59
60
73
    DetectAppLayerInspectEngineRegister2("ike.nonce_payload_length", ALPROTO_IKE, SIG_FLAG_TOSERVER,
61
73
            1, DetectEngineInspectGenericList, NULL);
62
63
73
    DetectAppLayerInspectEngineRegister2("ike.nonce_payload_length", ALPROTO_IKE, SIG_FLAG_TOCLIENT,
64
73
            1, DetectEngineInspectGenericList, NULL);
65
66
73
    g_ike_nonce_payload_length_buffer_id = DetectBufferTypeGetByName("ike.nonce_payload_length");
67
73
}
68
69
/**
70
 * \internal
71
 * \brief Function to match nonce length of a IKE state
72
 *
73
 * \param det_ctx Pointer to the pattern matcher thread.
74
 * \param f       Pointer to the current flow.
75
 * \param flags   Flags.
76
 * \param state   App layer state.
77
 * \param txv     Pointer to the Ike Transaction.
78
 * \param s       Pointer to the Signature.
79
 * \param ctx     Pointer to the sigmatch that we will cast into DetectU32Data.
80
 *
81
 * \retval 0 no match.
82
 * \retval 1 match.
83
 */
84
static int DetectIkeNoncePayloadLengthMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
85
        void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
86
83
{
87
83
    SCEnter();
88
89
83
    uint32_t length;
90
83
    if (!rs_ike_state_get_nonce_payload_length(txv, &length))
91
67
        SCReturnInt(0);
92
16
    const DetectU32Data *du32 = (const DetectU32Data *)ctx;
93
16
    return DetectU32Match(length, du32);
94
83
}
95
96
/**
97
 * \brief Function to add the parsed IKE nonce length field into the current signature.
98
 *
99
 * \param de_ctx Pointer to the Detection Engine Context.
100
 * \param s      Pointer to the Current Signature.
101
 * \param rawstr Pointer to the user provided flags options.
102
 *
103
 * \retval 0 on Success.
104
 * \retval -1 on Failure.
105
 */
106
static int DetectIkeNoncePayloadLengthSetup(
107
        DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
108
603
{
109
603
    if (DetectSignatureSetAppProto(s, ALPROTO_IKE) != 0)
110
14
        return -1;
111
112
589
    DetectU32Data *nonce_payload_length = DetectU32Parse(rawstr);
113
589
    if (nonce_payload_length == NULL)
114
47
        return -1;
115
116
    /* okay so far so good, lets get this into a SigMatch
117
     * and put it in the Signature. */
118
542
    SigMatch *sm = SigMatchAlloc();
119
542
    if (sm == NULL)
120
0
        goto error;
121
122
542
    sm->type = DETECT_AL_IKE_NONCE_PAYLOAD_LENGTH;
123
542
    sm->ctx = (SigMatchCtx *)nonce_payload_length;
124
125
542
    SigMatchAppendSMToList(s, sm, g_ike_nonce_payload_length_buffer_id);
126
542
    return 0;
127
128
0
error:
129
0
    DetectIkeNoncePayloadLengthFree(de_ctx, nonce_payload_length);
130
0
    return -1;
131
542
}
132
133
/**
134
 * \internal
135
 * \brief Function to free memory associated with DetectU32Data.
136
 *
137
 * \param de_ptr Pointer to DetectU32Data.
138
 */
139
static void DetectIkeNoncePayloadLengthFree(DetectEngineCtx *de_ctx, void *ptr)
140
542
{
141
542
    rs_detect_u32_free(ptr);
142
542
}