Coverage Report

Created: 2026-09-28 07:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata8/src/detect-base64-data.c
Line
Count
Source
1
/* Copyright (C) 2015 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
#include "suricata-common.h"
19
#include "detect.h"
20
#include "detect-engine.h"
21
#include "detect-engine-content-inspection.h"
22
#include "detect-parse.h"
23
#include "detect-base64-data.h"
24
#include "detect-engine-build.h"
25
26
#include "util-unittest.h"
27
28
static int DetectBase64DataSetup(DetectEngineCtx *, Signature *, const char *);
29
#ifdef UNITTESTS
30
static void DetectBase64DataRegisterTests(void);
31
#endif
32
33
void DetectBase64DataRegister(void)
34
79
{
35
79
    sigmatch_table[DETECT_BASE64_DATA].name = "base64_data";
36
79
    sigmatch_table[DETECT_BASE64_DATA].desc =
37
79
        "Content match base64 decoded data.";
38
79
    sigmatch_table[DETECT_BASE64_DATA].url =
39
79
        "/rules/base64-keywords.html#base64-data";
40
79
    sigmatch_table[DETECT_BASE64_DATA].Setup = DetectBase64DataSetup;
41
#ifdef UNITTESTS
42
    sigmatch_table[DETECT_BASE64_DATA].RegisterTests =
43
        DetectBase64DataRegisterTests;
44
#endif
45
79
    sigmatch_table[DETECT_BASE64_DATA].flags |= SIGMATCH_NOOPT;
46
79
}
47
48
static int DetectBase64DataSetup(DetectEngineCtx *de_ctx, Signature *s,
49
    const char *str)
50
6.64k
{
51
6.64k
    SigMatch *pm = NULL;
52
53
    /* Check for a preceding base64_decode. */
54
6.64k
    pm = DetectGetLastSMFromLists(s, DETECT_BASE64_DECODE, -1);
55
6.64k
    if (pm == NULL) {
56
259
        SCLogError("\"base64_data\" keyword seen without preceding base64_decode.");
57
259
        return -1;
58
259
    }
59
60
6.38k
    s->init_data->list = DETECT_SM_LIST_BASE64_DATA;
61
6.38k
    return 0;
62
6.64k
}
63
64
#ifdef UNITTESTS
65
66
static int g_file_data_buffer_id = 0;
67
68
static int DetectBase64DataSetupTest01(void)
69
{
70
    DetectEngineCtx *de_ctx = NULL;
71
    SigMatch *sm;
72
    int retval = 0;
73
74
    de_ctx = DetectEngineCtxInit();
75
    if (de_ctx == NULL) {
76
        goto end;
77
    }
78
79
    de_ctx->flags |= DE_QUIET;
80
    de_ctx->sig_list = SigInit(de_ctx,
81
        "alert smtp any any -> any any (msg:\"DetectBase64DataSetupTest\"; "
82
        "base64_decode; base64_data; content:\"content\"; sid:1; rev:1;)");
83
    if (de_ctx->sig_list == NULL) {
84
        printf("SigInit failed: ");
85
        goto end;
86
    }
87
88
    sm = de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH];
89
    if (sm == NULL) {
90
        printf("DETECT_SM_LIST_PMATCH should not be NULL: ");
91
        goto end;
92
    }
93
    if (sm->type != DETECT_BASE64_DECODE) {
94
        printf("sm->type should be DETECT_BASE64_DECODE: ");
95
        goto end;
96
    }
97
98
    if (de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_BASE64_DATA] == NULL) {
99
        printf("DETECT_SM_LIST_BASE64_DATA should not be NULL: ");
100
       goto end;
101
    }
102
103
    retval = 1;
104
end:
105
    if (de_ctx != NULL) {
106
        SigGroupCleanup(de_ctx);
107
        SigCleanSignatures(de_ctx);
108
        DetectEngineCtxFree(de_ctx);
109
    }
110
    return retval;
111
}
112
113
/**
114
 * \test Test that the list can be changed to post-detection lists
115
 *     after the base64 keyword.
116
 */
117
static int DetectBase64DataSetupTest04(void)
118
{
119
    DetectEngineCtx *de_ctx = NULL;
120
    int retval = 0;
121
122
    de_ctx = DetectEngineCtxInit();
123
    if (de_ctx == NULL) {
124
        goto end;
125
    }
126
127
    de_ctx->flags |= DE_QUIET;
128
    de_ctx->sig_list = SigInit(de_ctx,
129
        "alert tcp any any -> any any (msg:\"some b64thing\"; flow:established,from_server; file_data; content:\"sometext\"; fast_pattern; base64_decode:relative; base64_data; content:\"foobar\"; nocase; tag:session,120,seconds; sid:1111111; rev:1;)");
130
    if (de_ctx->sig_list == NULL) {
131
        printf("SigInit failed: ");
132
        goto end;
133
    }
134
135
    retval = 1;
136
end:
137
    if (de_ctx != NULL) {
138
        SigGroupCleanup(de_ctx);
139
        SigCleanSignatures(de_ctx);
140
        DetectEngineCtxFree(de_ctx);
141
    }
142
    return retval;
143
}
144
145
static void DetectBase64DataRegisterTests(void)
146
{
147
    g_file_data_buffer_id = DetectBufferTypeGetByName("file_data");
148
149
    UtRegisterTest("DetectBase64DataSetupTest01", DetectBase64DataSetupTest01);
150
    UtRegisterTest("DetectBase64DataSetupTest04", DetectBase64DataSetupTest04);
151
}
152
#endif /* UNITTESTS */