Coverage Report

Created: 2025-12-31 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/detect-ike-key-exchange-payload-length.c
Line
Count
Source
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-key-exchange-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.key_exchange_payload_length]:[=|<|>|<=|>=]<length>;
38
 */
39
static int DetectIkeKeyExchangePayloadLengthSetup(DetectEngineCtx *, Signature *s, const char *str);
40
static void DetectIkeKeyExchangePayloadLengthFree(DetectEngineCtx *, void *);
41
static int g_ike_key_exch_payload_length_buffer_id = 0;
42
43
static int DetectIkeKeyExchangePayloadLengthMatch(DetectEngineThreadCtx *, Flow *, uint8_t, void *,
44
        void *, const Signature *, const SigMatchCtx *);
45
46
/**
47
 * \brief Registration function for ike.key_exchange_payload_length keyword.
48
 */
49
void DetectIkeKeyExchangePayloadLengthRegister(void)
50
73
{
51
73
    sigmatch_table[DETECT_AL_IKE_KEY_EXCHANGE_PAYLOAD_LENGTH].name =
52
73
            "ike.key_exchange_payload_length";
53
73
    sigmatch_table[DETECT_AL_IKE_KEY_EXCHANGE_PAYLOAD_LENGTH].desc =
54
73
            "match IKE key exchange payload length";
55
73
    sigmatch_table[DETECT_AL_IKE_KEY_EXCHANGE_PAYLOAD_LENGTH].url =
56
73
            "/rules/ike-keywords.html#ike-key-exchange-payload-length";
57
73
    sigmatch_table[DETECT_AL_IKE_KEY_EXCHANGE_PAYLOAD_LENGTH].AppLayerTxMatch =
58
73
            DetectIkeKeyExchangePayloadLengthMatch;
59
73
    sigmatch_table[DETECT_AL_IKE_KEY_EXCHANGE_PAYLOAD_LENGTH].Setup =
60
73
            DetectIkeKeyExchangePayloadLengthSetup;
61
73
    sigmatch_table[DETECT_AL_IKE_KEY_EXCHANGE_PAYLOAD_LENGTH].Free =
62
73
            DetectIkeKeyExchangePayloadLengthFree;
63
64
73
    DetectAppLayerInspectEngineRegister2("ike.key_exchange_payload_length", ALPROTO_IKE,
65
73
            SIG_FLAG_TOSERVER, 1, DetectEngineInspectGenericList, NULL);
66
67
73
    DetectAppLayerInspectEngineRegister2("ike.key_exchange_payload_length", ALPROTO_IKE,
68
73
            SIG_FLAG_TOCLIENT, 1, DetectEngineInspectGenericList, NULL);
69
70
73
    g_ike_key_exch_payload_length_buffer_id =
71
73
            DetectBufferTypeGetByName("ike.key_exchange_payload_length");
72
73
}
73
74
/**
75
 * \internal
76
 * \brief Function to match key exchange payload length of a IKE state
77
 *
78
 * \param det_ctx Pointer to the pattern matcher thread.
79
 * \param f       Pointer to the current flow.
80
 * \param flags   Flags.
81
 * \param state   App layer state.
82
 * \param txv     Pointer to the Ike Transaction.
83
 * \param s       Pointer to the Signature.
84
 * \param ctx     Pointer to the sigmatch that we will cast into DetectU32Data.
85
 *
86
 * \retval 0 no match.
87
 * \retval 1 match.
88
 */
89
static int DetectIkeKeyExchangePayloadLengthMatch(DetectEngineThreadCtx *det_ctx, Flow *f,
90
        uint8_t flags, void *state, void *txv, const Signature *s, const SigMatchCtx *ctx)
91
54
{
92
54
    SCEnter();
93
94
54
    uint32_t length;
95
54
    if (!rs_ike_state_get_key_exchange_payload_length(txv, &length))
96
39
        SCReturnInt(0);
97
15
    const DetectU32Data *du32 = (const DetectU32Data *)ctx;
98
15
    return DetectU32Match(length, du32);
99
54
}
100
101
/**
102
 * \brief Function to add the parsed IKE key exchange payload length query into the current
103
 * signature.
104
 *
105
 * \param de_ctx Pointer to the Detection Engine Context.
106
 * \param s      Pointer to the Current Signature.
107
 * \param rawstr Pointer to the user provided flags options.
108
 *
109
 * \retval 0 on Success.
110
 * \retval -1 on Failure.
111
 */
112
static int DetectIkeKeyExchangePayloadLengthSetup(
113
        DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
114
1.67k
{
115
1.67k
    if (DetectSignatureSetAppProto(s, ALPROTO_IKE) != 0)
116
878
        return -1;
117
118
801
    DetectU32Data *key_exchange_payload_length = DetectU32Parse(rawstr);
119
801
    if (key_exchange_payload_length == NULL)
120
267
        return -1;
121
122
    /* okay so far so good, lets get this into a SigMatch
123
     * and put it in the Signature. */
124
534
    SigMatch *sm = SigMatchAlloc();
125
534
    if (sm == NULL)
126
0
        goto error;
127
128
534
    sm->type = DETECT_AL_IKE_KEY_EXCHANGE_PAYLOAD_LENGTH;
129
534
    sm->ctx = (SigMatchCtx *)key_exchange_payload_length;
130
131
534
    SigMatchAppendSMToList(s, sm, g_ike_key_exch_payload_length_buffer_id);
132
534
    return 0;
133
134
0
error:
135
0
    DetectIkeKeyExchangePayloadLengthFree(de_ctx, key_exchange_payload_length);
136
0
    return -1;
137
534
}
138
139
/**
140
 * \internal
141
 * \brief Function to free memory associated with DetectU32Data.
142
 *
143
 * \param de_ptr Pointer to DetectU32Data.
144
 */
145
static void DetectIkeKeyExchangePayloadLengthFree(DetectEngineCtx *de_ctx, void *ptr)
146
534
{
147
534
    rs_detect_u32_free(ptr);
148
534
}