Coverage Report

Created: 2026-06-30 07:20

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
34
{
51
34
    sigmatch_table[DETECT_AL_IKE_KEY_EXCHANGE_PAYLOAD_LENGTH].name =
52
34
            "ike.key_exchange_payload_length";
53
34
    sigmatch_table[DETECT_AL_IKE_KEY_EXCHANGE_PAYLOAD_LENGTH].desc =
54
34
            "match IKE key exchange payload length";
55
34
    sigmatch_table[DETECT_AL_IKE_KEY_EXCHANGE_PAYLOAD_LENGTH].url =
56
34
            "/rules/ike-keywords.html#ike-key-exchange-payload-length";
57
34
    sigmatch_table[DETECT_AL_IKE_KEY_EXCHANGE_PAYLOAD_LENGTH].AppLayerTxMatch =
58
34
            DetectIkeKeyExchangePayloadLengthMatch;
59
34
    sigmatch_table[DETECT_AL_IKE_KEY_EXCHANGE_PAYLOAD_LENGTH].Setup =
60
34
            DetectIkeKeyExchangePayloadLengthSetup;
61
34
    sigmatch_table[DETECT_AL_IKE_KEY_EXCHANGE_PAYLOAD_LENGTH].Free =
62
34
            DetectIkeKeyExchangePayloadLengthFree;
63
64
34
    DetectAppLayerInspectEngineRegister2("ike.key_exchange_payload_length", ALPROTO_IKE,
65
34
            SIG_FLAG_TOSERVER, 1, DetectEngineInspectGenericList, NULL);
66
67
34
    DetectAppLayerInspectEngineRegister2("ike.key_exchange_payload_length", ALPROTO_IKE,
68
34
            SIG_FLAG_TOCLIENT, 1, DetectEngineInspectGenericList, NULL);
69
70
34
    g_ike_key_exch_payload_length_buffer_id =
71
34
            DetectBufferTypeGetByName("ike.key_exchange_payload_length");
72
34
}
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
37
{
92
37
    SCEnter();
93
94
37
    uint32_t length;
95
37
    if (!rs_ike_state_get_key_exchange_payload_length(txv, &length))
96
30
        SCReturnInt(0);
97
7
    const DetectU32Data *du32 = (const DetectU32Data *)ctx;
98
7
    return DetectU32Match(length, du32);
99
37
}
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
822
{
115
822
    if (DetectSignatureSetAppProto(s, ALPROTO_IKE) != 0)
116
273
        return -1;
117
118
549
    DetectU32Data *key_exchange_payload_length = DetectU32Parse(rawstr);
119
549
    if (key_exchange_payload_length == NULL)
120
20
        return -1;
121
122
    /* okay so far so good, lets get this into a SigMatch
123
     * and put it in the Signature. */
124
529
    SigMatch *sm = SigMatchAlloc();
125
529
    if (sm == NULL)
126
0
        goto error;
127
128
529
    sm->type = DETECT_AL_IKE_KEY_EXCHANGE_PAYLOAD_LENGTH;
129
529
    sm->ctx = (SigMatchCtx *)key_exchange_payload_length;
130
131
529
    SigMatchAppendSMToList(s, sm, g_ike_key_exch_payload_length_buffer_id);
132
529
    return 0;
133
134
0
error:
135
0
    DetectIkeKeyExchangePayloadLengthFree(de_ctx, key_exchange_payload_length);
136
0
    return -1;
137
529
}
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
529
{
147
529
    rs_detect_u32_free(ptr);
148
529
}