Coverage Report

Created: 2026-02-14 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/detect-template-rust-buffer.c
Line
Count
Source
1
/* Copyright (C) 2015-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
 * TODO: Update the \author in this file and detect-template.h.
20
 * TODO: Update description in the \file section below.
21
 * TODO: Remove SCLogNotice statements or convert to debug.
22
 */
23
24
/**
25
 * \file
26
 *
27
 * \author FirstName LastName <yourname@domain>
28
 *
29
 * Set up of the "template_rust" keyword to allow content
30
 * inspections on the decoded template application layer buffers.
31
 */
32
33
#include "suricata-common.h"
34
#include "conf.h"
35
#include "detect.h"
36
#include "detect-parse.h"
37
#include "detect-engine.h"
38
#include "detect-engine-content-inspection.h"
39
#include "detect-template-rust-buffer.h"
40
#include "app-layer-parser.h"
41
#include "detect-engine-build.h"
42
#include "rust.h"
43
44
static int DetectTemplateRustBufferSetup(DetectEngineCtx *, Signature *, const char *);
45
static uint8_t DetectEngineInspectTemplateRustBuffer(DetectEngineCtx *de_ctx,
46
        DetectEngineThreadCtx *det_ctx, const struct DetectEngineAppInspectionEngine_ *engine,
47
        const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id);
48
#ifdef UNITTESTS
49
static void DetectTemplateRustBufferRegisterTests(void);
50
#endif
51
static int g_template_rust_id = 0;
52
53
void DetectTemplateRustBufferRegister(void)
54
34
{
55
    /* TEMPLATE_START_REMOVE */
56
34
    if (ConfGetNode("app-layer.protocols.template") == NULL) {
57
2
        return;
58
2
    }
59
    /* TEMPLATE_END_REMOVE */
60
32
    sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].name = "template.buffer";
61
32
    sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].desc =
62
32
            "Template content modifier to match on the template buffers";
63
32
    sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].Setup = DetectTemplateRustBufferSetup;
64
#ifdef UNITTESTS
65
    sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].RegisterTests = DetectTemplateRustBufferRegisterTests;
66
#endif
67
32
    sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].flags |= SIGMATCH_NOOPT;
68
69
    /* register inspect engines */
70
32
    DetectAppLayerInspectEngineRegister2("template_buffer", ALPROTO_TEMPLATE, SIG_FLAG_TOSERVER, 0,
71
32
            DetectEngineInspectTemplateRustBuffer, NULL);
72
32
    DetectAppLayerInspectEngineRegister2("template_buffer", ALPROTO_TEMPLATE, SIG_FLAG_TOCLIENT, 0,
73
32
            DetectEngineInspectTemplateRustBuffer, NULL);
74
75
32
    g_template_rust_id = DetectBufferTypeGetByName("template_buffer");
76
77
32
    SCLogNotice("Template application layer detect registered.");
78
32
}
79
80
static int DetectTemplateRustBufferSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
81
23
{
82
23
    s->init_data->list = g_template_rust_id;
83
84
23
    if (DetectSignatureSetAppProto(s, ALPROTO_TEMPLATE) != 0)
85
1
        return -1;
86
87
22
    return 0;
88
23
}
89
90
static uint8_t DetectEngineInspectTemplateRustBuffer(DetectEngineCtx *de_ctx,
91
        DetectEngineThreadCtx *det_ctx, const struct DetectEngineAppInspectionEngine_ *engine,
92
        const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
93
7
{
94
7
    uint8_t ret = 0;
95
7
    const uint8_t *data = NULL;
96
7
    uint32_t data_len = 0;
97
98
7
    if (flags & STREAM_TOSERVER) {
99
2
        rs_template_get_request_buffer(txv, &data, &data_len);
100
5
    } else if (flags & STREAM_TOCLIENT) {
101
5
        rs_template_get_response_buffer(txv, &data, &data_len);
102
5
    }
103
104
7
    if (data != NULL) {
105
2
        ret = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f,
106
2
                (uint8_t *)data, data_len, 0, DETECT_CI_FLAGS_SINGLE,
107
2
                DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE);
108
2
    }
109
110
7
    SCLogNotice("Returning %d.", ret);
111
7
    return ret;
112
7
}
113
114
#ifdef UNITTESTS
115
116
#include "util-unittest.h"
117
#include "util-unittest-helper.h"
118
#include "flow-util.h"
119
#include "stream-tcp.h"
120
#include "detect-engine-alert.h"
121
122
static int DetectTemplateRustBufferTest(void)
123
{
124
    AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
125
    DetectEngineThreadCtx *det_ctx = NULL;
126
    DetectEngineCtx *de_ctx = NULL;
127
    Flow f;
128
    Packet *p;
129
    TcpSession tcp;
130
    ThreadVars tv;
131
    Signature *s;
132
133
    uint8_t request[] = "12:Hello World!";
134
135
    /* Setup flow. */
136
    memset(&f, 0, sizeof(Flow));
137
    memset(&tcp, 0, sizeof(TcpSession));
138
    memset(&tv, 0, sizeof(ThreadVars));
139
    p = UTHBuildPacket(request, sizeof(request), IPPROTO_TCP);
140
    FLOW_INITIALIZE(&f);
141
    f.alproto = ALPROTO_TEMPLATE;
142
    f.protoctx = (void *)&tcp;
143
    f.proto = IPPROTO_TCP;
144
    f.flags |= FLOW_IPV4;
145
    p->flow = &f;
146
    p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
147
    p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED;
148
    StreamTcpInitConfig(true);
149
150
    de_ctx = DetectEngineCtxInit();
151
    FAIL_IF_NULL(de_ctx);
152
153
    /* This rule should match. */
154
    s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any ("
155
                                      "msg:\"TEMPLATE Test Rule\"; "
156
                                      "template.buffer; content:\"World!\"; "
157
                                      "sid:1; rev:1;)");
158
    FAIL_IF_NULL(s);
159
160
    /* This rule should not match. */
161
    s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any ("
162
                                      "msg:\"TEMPLATE Test Rule\"; "
163
                                      "template.buffer; content:\"W0rld!\"; "
164
                                      "sid:2; rev:1;)");
165
    FAIL_IF_NULL(s);
166
167
    SigGroupBuild(de_ctx);
168
    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
169
170
    AppLayerParserParse(
171
            NULL, alp_tctx, &f, ALPROTO_TEMPLATE, STREAM_TOSERVER, request, sizeof(request));
172
173
    /* Check that we have app-layer state. */
174
    FAIL_IF_NULL(f.alstate);
175
176
    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
177
    FAIL_IF(!PacketAlertCheck(p, 1));
178
    FAIL_IF(PacketAlertCheck(p, 2));
179
180
    /* Cleanup. */
181
    if (alp_tctx != NULL)
182
        AppLayerParserThreadCtxFree(alp_tctx);
183
    if (det_ctx != NULL)
184
        DetectEngineThreadCtxDeinit(&tv, det_ctx);
185
    if (de_ctx != NULL)
186
        SigGroupCleanup(de_ctx);
187
    if (de_ctx != NULL)
188
        DetectEngineCtxFree(de_ctx);
189
    StreamTcpFreeConfig(true);
190
    FLOW_DESTROY(&f);
191
    UTHFreePacket(p);
192
193
    PASS;
194
}
195
196
static void DetectTemplateRustBufferRegisterTests(void)
197
{
198
    UtRegisterTest("DetectTemplateRustBufferTest",
199
        DetectTemplateRustBufferTest);
200
}
201
#endif /* UNITTESTS */