Coverage Report

Created: 2025-11-16 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/detect-quic-cyu-string.c
Line
Count
Source
1
/* Copyright (C) 2021-2022 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
 * Implements the quic.cyu.string sticky buffer
21
 */
22
23
#include "suricata-common.h"
24
#include "detect.h"
25
#include "detect-parse.h"
26
#include "detect-engine.h"
27
#include "detect-engine-mpm.h"
28
#include "detect-engine-prefilter.h"
29
#include "detect-engine-content-inspection.h"
30
#include "detect-quic-cyu-string.h"
31
#include "detect-engine-build.h"
32
#include "rust.h"
33
#include "util-profiling.h"
34
35
#ifdef UNITTESTS
36
static void DetectQuicCyuStringRegisterTests(void);
37
#endif
38
39
73
#define KEYWORD_NAME "quic.cyu.string"
40
73
#define KEYWORD_DOC  "quic-cyu.html#quic-cyu-string"
41
365
#define BUFFER_NAME  "quic.cyu.string"
42
73
#define BUFFER_DESC  "QUIC CYU String"
43
static int g_buffer_id = 0;
44
45
struct QuicStringGetDataArgs {
46
    uint32_t local_id; /**< used as index into thread inspect array */
47
    void *txv;
48
};
49
50
static int DetectQuicCyuStringSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
51
1.53k
{
52
1.53k
    if (DetectBufferSetActiveList(de_ctx, s, g_buffer_id) < 0)
53
2
        return -1;
54
55
1.53k
    if (DetectSignatureSetAppProto(s, ALPROTO_QUIC) < 0)
56
10
        return -1;
57
58
1.52k
    return 0;
59
1.53k
}
60
61
static InspectionBuffer *QuicStringGetData(DetectEngineThreadCtx *det_ctx,
62
        const DetectEngineTransforms *transforms, Flow *f, struct QuicStringGetDataArgs *cbdata,
63
        int list_id)
64
7
{
65
7
    SCEnter();
66
67
7
    InspectionBuffer *buffer =
68
7
            InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id);
69
7
    if (buffer == NULL)
70
0
        return NULL;
71
7
    if (buffer->initialized)
72
1
        return buffer;
73
74
6
    const uint8_t *data;
75
6
    uint32_t data_len;
76
6
    if (rs_quic_tx_get_cyu_string(cbdata->txv, cbdata->local_id, &data, &data_len) == 0) {
77
4
        InspectionBufferSetupMultiEmpty(buffer);
78
4
        return NULL;
79
4
    }
80
81
2
    InspectionBufferSetupMulti(buffer, transforms, data, data_len);
82
83
2
    SCReturnPtr(buffer, "InspectionBuffer");
84
6
}
85
86
static uint8_t DetectEngineInspectQuicString(DetectEngineCtx *de_ctx,
87
        DetectEngineThreadCtx *det_ctx, const DetectEngineAppInspectionEngine *engine,
88
        const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
89
1
{
90
1
    uint32_t local_id = 0;
91
92
1
    const DetectEngineTransforms *transforms = NULL;
93
1
    if (!engine->mpm) {
94
0
        transforms = engine->v2.transforms;
95
0
    }
96
97
1
    while (1) {
98
1
        struct QuicStringGetDataArgs cbdata = {
99
1
            local_id,
100
1
            txv,
101
1
        };
102
1
        InspectionBuffer *buffer =
103
1
                QuicStringGetData(det_ctx, transforms, f, &cbdata, engine->sm_list);
104
1
        if (buffer == NULL || buffer->inspect == NULL)
105
0
            break;
106
107
1
        det_ctx->buffer_offset = 0;
108
1
        det_ctx->discontinue_matching = 0;
109
1
        det_ctx->inspection_recursion_counter = 0;
110
111
1
        const int match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f,
112
1
                (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset,
113
1
                DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE);
114
1
        if (match == 1) {
115
1
            return DETECT_ENGINE_INSPECT_SIG_MATCH;
116
1
        }
117
0
        local_id++;
118
0
    }
119
0
    return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
120
1
}
121
122
/** \brief QuicString Mpm prefilter callback
123
 *
124
 *  \param det_ctx detection engine thread ctx
125
 *  \param p packet to inspect
126
 *  \param f flow to inspect
127
 *  \param txv tx to inspect
128
 *  \param pectx inspection context
129
 */
130
static void PrefilterTxQuicString(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p,
131
        Flow *f, void *txv, const uint64_t idx, const AppLayerTxData *_txd, const uint8_t flags)
132
4
{
133
4
    SCEnter();
134
135
4
    const PrefilterMpmListId *ctx = (const PrefilterMpmListId *)pectx;
136
4
    const MpmCtx *mpm_ctx = ctx->mpm_ctx;
137
4
    const int list_id = ctx->list_id;
138
139
4
    uint32_t local_id = 0;
140
6
    while (1) {
141
        // loop until we get a NULL
142
143
6
        struct QuicStringGetDataArgs cbdata = { local_id, txv };
144
6
        InspectionBuffer *buffer = QuicStringGetData(det_ctx, ctx->transforms, f, &cbdata, list_id);
145
6
        if (buffer == NULL)
146
4
            break;
147
148
2
        if (buffer->inspect_len >= mpm_ctx->minlen) {
149
2
            (void)mpm_table[mpm_ctx->mpm_type].Search(
150
2
                    mpm_ctx, &det_ctx->mtcu, &det_ctx->pmq, buffer->inspect, buffer->inspect_len);
151
2
            PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len);
152
2
        }
153
154
2
        local_id++;
155
2
    }
156
4
}
157
158
static void PrefilterMpmListIdFree(void *ptr)
159
18
{
160
18
    SCFree(ptr);
161
18
}
162
163
static int PrefilterMpmListIdRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx,
164
        const DetectBufferMpmRegistry *mpm_reg, int list_id)
165
18
{
166
18
    PrefilterMpmListId *pectx = SCCalloc(1, sizeof(*pectx));
167
18
    if (pectx == NULL)
168
0
        return -1;
169
18
    pectx->list_id = list_id;
170
18
    pectx->mpm_ctx = mpm_ctx;
171
18
    pectx->transforms = &mpm_reg->transforms;
172
173
18
    return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxQuicString, mpm_reg->app_v2.alproto,
174
18
            mpm_reg->app_v2.tx_min_progress, pectx, PrefilterMpmListIdFree, mpm_reg->pname);
175
18
}
176
177
void DetectQuicCyuStringRegister(void)
178
73
{
179
    /* quic.cyu.string sticky buffer */
180
73
    sigmatch_table[DETECT_AL_QUIC_CYU_STRING].name = KEYWORD_NAME;
181
73
    sigmatch_table[DETECT_AL_QUIC_CYU_STRING].desc =
182
73
            "sticky buffer to match on the QUIC CYU string";
183
73
    sigmatch_table[DETECT_AL_QUIC_CYU_STRING].url = "/rules/" KEYWORD_DOC;
184
73
    sigmatch_table[DETECT_AL_QUIC_CYU_STRING].Setup = DetectQuicCyuStringSetup;
185
73
    sigmatch_table[DETECT_AL_QUIC_CYU_STRING].flags |= SIGMATCH_NOOPT;
186
#ifdef UNITTESTS
187
    sigmatch_table[DETECT_AL_QUIC_CYU_STRING].RegisterTests = DetectQuicCyuStringRegisterTests;
188
#endif
189
190
73
    DetectAppLayerMpmRegister2(
191
73
            BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterMpmListIdRegister, NULL, ALPROTO_QUIC, 1);
192
193
73
    DetectAppLayerInspectEngineRegister2(
194
73
            BUFFER_NAME, ALPROTO_QUIC, SIG_FLAG_TOSERVER, 0, DetectEngineInspectQuicString, NULL);
195
196
73
    DetectBufferTypeSetDescriptionByName(BUFFER_NAME, BUFFER_DESC);
197
198
73
    g_buffer_id = DetectBufferTypeGetByName(BUFFER_NAME);
199
200
73
    DetectBufferTypeSupportsMultiInstance(BUFFER_NAME);
201
202
73
    SCLogDebug("registering " BUFFER_NAME " rule option");
203
73
}
204
205
#ifdef UNITTESTS
206
#include "app-layer-parser.h"
207
#include "util-unittest.h"
208
#include "util-unittest-helper.h"
209
#include "flow-util.h"
210
#include "detect-engine-alert.h"
211
212
/**
213
 * \test DetectQuicCyuStringTest01 is a test for a valid quic packet, matching
214
 *   on the cyu string
215
 *
216
 *  \retval 1 on success
217
 *  \retval 0 on failure
218
 */
219
static int DetectQuicCyuStringTest01(void)
220
{
221
    /* quic packet */
222
    uint8_t buf[] = { 0xc3, 0x51, 0x30, 0x34, 0x36, 0x50, 0x76, 0xd8, 0x63, 0xb7, 0x54, 0xf7, 0xab,
223
        0x32, 0x00, 0x00, 0x00, 0x01, 0x54, 0xfd, 0xf4, 0x79, 0x48, 0x76, 0xd0, 0x87, 0x58, 0x8d,
224
        0x26, 0x8f, 0xa0, 0x01, 0x04, 0x00, 0x43, 0x48, 0x4c, 0x4f, 0x11, 0x00, 0x00, 0x00, 0x50,
225
        0x41, 0x44, 0x00, 0xe4, 0x02, 0x00, 0x00, 0x53, 0x4e, 0x49, 0x00, 0xf7, 0x02, 0x00, 0x00,
226
        0x56, 0x45, 0x52, 0x00, 0xfb, 0x02, 0x00, 0x00, 0x43, 0x43, 0x53, 0x00, 0x0b, 0x03, 0x00,
227
        0x00, 0x55, 0x41, 0x49, 0x44, 0x2c, 0x03, 0x00, 0x00, 0x54, 0x43, 0x49, 0x44, 0x30, 0x03,
228
        0x00, 0x00, 0x50, 0x44, 0x4d, 0x44, 0x34, 0x03, 0x00, 0x00, 0x53, 0x4d, 0x48, 0x4c, 0x38,
229
        0x03, 0x00, 0x00, 0x49, 0x43, 0x53, 0x4c, 0x3c, 0x03, 0x00, 0x00, 0x4e, 0x4f, 0x4e, 0x50,
230
        0x5c, 0x03, 0x00, 0x00, 0x4d, 0x49, 0x44, 0x53, 0x60, 0x03, 0x00, 0x00, 0x53, 0x43, 0x4c,
231
        0x53, 0x64, 0x03, 0x00, 0x00, 0x43, 0x53, 0x43, 0x54, 0x64, 0x03, 0x00, 0x00, 0x43, 0x4f,
232
        0x50, 0x54, 0x64, 0x03, 0x00, 0x00, 0x49, 0x52, 0x54, 0x54, 0x68, 0x03, 0x00, 0x00, 0x43,
233
        0x46, 0x43, 0x57, 0x6c, 0x03, 0x00, 0x00, 0x53, 0x46, 0x43, 0x57, 0x70, 0x03, 0x00, 0x00,
234
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
235
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
236
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
237
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
238
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
239
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
240
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
241
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
242
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
243
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
244
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
245
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
246
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
247
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
248
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
249
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
250
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
251
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
252
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
253
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
254
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
255
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
256
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
257
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
258
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
259
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
260
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
261
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
262
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
263
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
264
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
265
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
266
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
267
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
268
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
269
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
270
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
271
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
272
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
273
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
274
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
275
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
276
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
277
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
278
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
279
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
280
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
281
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
282
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
283
        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x31, 0x2e, 0x67,
284
        0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x51, 0x30, 0x34, 0x36, 0x01, 0xe8,
285
        0x81, 0x60, 0x92, 0x92, 0x1a, 0xe8, 0x7e, 0xed, 0x80, 0x86, 0xa2, 0x15, 0x82, 0x91, 0x43,
286
        0x68, 0x72, 0x6f, 0x6d, 0x65, 0x2f, 0x37, 0x39, 0x2e, 0x30, 0x2e, 0x33, 0x39, 0x34, 0x35,
287
        0x2e, 0x31, 0x31, 0x37, 0x20, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x78, 0x38, 0x36, 0x5f,
288
        0x36, 0x34, 0x00, 0x00, 0x00, 0x00, 0x58, 0x35, 0x30, 0x39, 0x01, 0x00, 0x00, 0x00, 0x1e,
289
        0x00, 0x00, 0x00, 0x82, 0x88, 0x09, 0x00, 0xfa, 0x0f, 0xde, 0xb7, 0x2e, 0x7e, 0x6c, 0x78,
290
        0xcc, 0x09, 0x65, 0xab, 0x06, 0x0c, 0x31, 0x05, 0xfa, 0xd9, 0xa2, 0x0b, 0xdd, 0x74, 0x5c,
291
        0x28, 0xdf, 0x7b, 0x74, 0x23, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1d, 0x43,
292
        0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
298
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
304
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312
        0x00, 0x00 };
313
314
    Flow f;
315
    void *quic_state = NULL;
316
    Packet *p = NULL;
317
    Signature *s = NULL;
318
    ThreadVars tv;
319
    DetectEngineThreadCtx *det_ctx = NULL;
320
    AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
321
322
    memset(&tv, 0, sizeof(ThreadVars));
323
    memset(&f, 0, sizeof(Flow));
324
325
    p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP, "192.168.1.5", "192.168.1.1", 41424, 443);
326
327
    FLOW_INITIALIZE(&f);
328
    f.flags |= FLOW_IPV4;
329
    f.proto = IPPROTO_UDP;
330
    f.protomap = FlowGetProtoMapping(f.proto);
331
332
    p->flow = &f;
333
    p->flags |= PKT_HAS_FLOW;
334
    p->flowflags |= FLOW_PKT_TOSERVER;
335
    f.alproto = ALPROTO_QUIC;
336
337
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
338
    FAIL_IF_NULL(de_ctx);
339
    de_ctx->mpm_matcher = mpm_default_matcher;
340
    de_ctx->flags |= DE_QUIET;
341
342
    s = DetectEngineAppendSig(de_ctx, "alert quic any any -> any any "
343
                                      "(msg:\"Test QUIC CYU string\"; "
344
                                      "quic.cyu.string; "
345
                                      "content:\"46,PAD-SNI-VER-CCS-UAID-TCID-PDMD-SMHL-ICSL-NONP-"
346
                                      "MIDS-SCLS-CSCT-COPT-IRTT-CFCW-SFCW\"; "
347
                                      "sid:1;)");
348
    FAIL_IF_NULL(s);
349
350
    SigGroupBuild(de_ctx);
351
    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
352
353
    int r = AppLayerParserParse(
354
            NULL, alp_tctx, &f, ALPROTO_QUIC, STREAM_TOSERVER, buf, sizeof(buf));
355
    if (r != 0) {
356
        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
357
        FAIL;
358
    }
359
360
    quic_state = f.alstate;
361
    FAIL_IF_NULL(quic_state);
362
363
    /* do detect */
364
    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
365
366
    if (!(PacketAlertCheck(p, 1))) {
367
        printf("sig 1 didn't alert, but it should have: ");
368
        FAIL;
369
    }
370
371
    if (alp_tctx != NULL)
372
        AppLayerParserThreadCtxFree(alp_tctx);
373
    if (det_ctx != NULL)
374
        DetectEngineThreadCtxDeinit(&tv, det_ctx);
375
    if (de_ctx != NULL)
376
        SigGroupCleanup(de_ctx);
377
    if (de_ctx != NULL)
378
        DetectEngineCtxFree(de_ctx);
379
380
    FLOW_DESTROY(&f);
381
    UTHFreePacket(p);
382
    PASS;
383
}
384
385
/**
386
 * \brief this function registers unit tests for Quic Cyu String
387
 */
388
static void DetectQuicCyuStringRegisterTests(void)
389
{
390
    UtRegisterTest("DetectQuicCyuStringTest01", DetectQuicCyuStringTest01);
391
}
392
393
#endif /* UNITTESTS */