/src/suricata7/src/detect-ike-vendor.c
Line | Count | Source |
1 | | /* Copyright (C) 2020-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 | | * \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-prefilter.h" |
29 | | #include "detect-engine-content-inspection.h" |
30 | | #include "detect-engine-mpm.h" |
31 | | #include "detect-ike-vendor.h" |
32 | | #include "app-layer-parser.h" |
33 | | #include "util-byte.h" |
34 | | |
35 | | #include "rust-bindings.h" |
36 | | #include "util-profiling.h" |
37 | | |
38 | | static int DetectIkeVendorSetup(DetectEngineCtx *, Signature *, const char *); |
39 | | |
40 | | typedef struct { |
41 | | char *vendor; |
42 | | } DetectIkeVendorData; |
43 | | |
44 | | struct IkeVendorGetDataArgs { |
45 | | uint32_t local_id; |
46 | | void *txv; |
47 | | }; |
48 | | |
49 | | typedef struct PrefilterMpmIkeVendor { |
50 | | int list_id; |
51 | | const MpmCtx *mpm_ctx; |
52 | | const DetectEngineTransforms *transforms; |
53 | | } PrefilterMpmIkeVendor; |
54 | | |
55 | | static int g_ike_vendor_buffer_id = 0; |
56 | | |
57 | | static InspectionBuffer *IkeVendorGetData(DetectEngineThreadCtx *det_ctx, |
58 | | const DetectEngineTransforms *transforms, Flow *f, struct IkeVendorGetDataArgs *cbdata, |
59 | | int list_id) |
60 | 120 | { |
61 | 120 | SCEnter(); |
62 | | |
63 | 120 | InspectionBuffer *buffer = |
64 | 120 | InspectionBufferMultipleForListGet(det_ctx, list_id, cbdata->local_id); |
65 | 120 | if (buffer == NULL) |
66 | 0 | return NULL; |
67 | 120 | if (buffer->initialized) |
68 | 14 | return buffer; |
69 | | |
70 | 106 | const uint8_t *data; |
71 | 106 | uint32_t data_len; |
72 | 106 | if (rs_ike_tx_get_vendor(cbdata->txv, cbdata->local_id, &data, &data_len) == 0) { |
73 | 36 | InspectionBufferSetupMultiEmpty(buffer); |
74 | 36 | return NULL; |
75 | 36 | } |
76 | | |
77 | 70 | InspectionBufferSetupMulti(buffer, transforms, data, data_len); |
78 | | |
79 | 70 | SCReturnPtr(buffer, "InspectionBuffer"); |
80 | 106 | } |
81 | | |
82 | | /** \brief IkeVendor Mpm prefilter callback |
83 | | * |
84 | | * \param det_ctx detection engine thread ctx |
85 | | * \param p packet to inspect |
86 | | * \param f flow to inspect |
87 | | * \param txv tx to inspect |
88 | | * \param pectx inspection context |
89 | | */ |
90 | | static void PrefilterTxIkeVendor(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, |
91 | | Flow *f, void *txv, const uint64_t idx, const AppLayerTxData *_txd, const uint8_t flags) |
92 | 36 | { |
93 | 36 | SCEnter(); |
94 | | |
95 | 36 | const PrefilterMpmIkeVendor *ctx = (const PrefilterMpmIkeVendor *)pectx; |
96 | 36 | const MpmCtx *mpm_ctx = ctx->mpm_ctx; |
97 | 36 | const int list_id = ctx->list_id; |
98 | | |
99 | 36 | uint32_t local_id = 0; |
100 | 106 | while (1) { |
101 | 106 | struct IkeVendorGetDataArgs cbdata = { local_id, txv }; |
102 | 106 | InspectionBuffer *buffer = IkeVendorGetData(det_ctx, ctx->transforms, f, &cbdata, list_id); |
103 | 106 | if (buffer == NULL) |
104 | 36 | break; |
105 | | |
106 | 70 | if (buffer->inspect_len >= mpm_ctx->minlen) { |
107 | 49 | (void)mpm_table[mpm_ctx->mpm_type].Search( |
108 | 49 | mpm_ctx, &det_ctx->mtcu, &det_ctx->pmq, buffer->inspect, buffer->inspect_len); |
109 | 49 | PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len); |
110 | 49 | } |
111 | 70 | local_id++; |
112 | 70 | } |
113 | | |
114 | 36 | SCReturn; |
115 | 36 | } |
116 | | |
117 | | static void PrefilterMpmIkeVendorFree(void *ptr) |
118 | 133 | { |
119 | 133 | if (ptr != NULL) |
120 | 133 | SCFree(ptr); |
121 | 133 | } |
122 | | |
123 | | static int PrefilterMpmIkeVendorRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, |
124 | | MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id) |
125 | 133 | { |
126 | 133 | PrefilterMpmIkeVendor *pectx = SCCalloc(1, sizeof(*pectx)); |
127 | 133 | if (pectx == NULL) |
128 | 0 | return -1; |
129 | 133 | pectx->list_id = list_id; |
130 | 133 | pectx->mpm_ctx = mpm_ctx; |
131 | 133 | pectx->transforms = &mpm_reg->transforms; |
132 | | |
133 | 133 | return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxIkeVendor, mpm_reg->app_v2.alproto, |
134 | 133 | mpm_reg->app_v2.tx_min_progress, pectx, PrefilterMpmIkeVendorFree, mpm_reg->pname); |
135 | 133 | } |
136 | | |
137 | | static uint8_t DetectEngineInspectIkeVendor(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, |
138 | | const DetectEngineAppInspectionEngine *engine, const Signature *s, Flow *f, uint8_t flags, |
139 | | void *alstate, void *txv, uint64_t tx_id) |
140 | 14 | { |
141 | 14 | uint32_t local_id = 0; |
142 | | |
143 | 14 | const DetectEngineTransforms *transforms = NULL; |
144 | 14 | if (!engine->mpm) { |
145 | 0 | transforms = engine->v2.transforms; |
146 | 0 | } |
147 | | |
148 | 14 | while (1) { |
149 | 14 | struct IkeVendorGetDataArgs cbdata = { |
150 | 14 | local_id, |
151 | 14 | txv, |
152 | 14 | }; |
153 | 14 | InspectionBuffer *buffer = |
154 | 14 | IkeVendorGetData(det_ctx, transforms, f, &cbdata, engine->sm_list); |
155 | 14 | if (buffer == NULL || buffer->inspect == NULL) |
156 | 0 | break; |
157 | | |
158 | 14 | det_ctx->buffer_offset = 0; |
159 | 14 | det_ctx->discontinue_matching = 0; |
160 | 14 | det_ctx->inspection_recursion_counter = 0; |
161 | | |
162 | 14 | const int match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, |
163 | 14 | (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, |
164 | 14 | DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); |
165 | 14 | if (match == 1) { |
166 | 14 | return DETECT_ENGINE_INSPECT_SIG_MATCH; |
167 | 14 | } |
168 | 0 | local_id++; |
169 | 0 | } |
170 | 0 | return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; |
171 | 14 | } |
172 | | |
173 | | /** |
174 | | * \brief Registration function for ike.vendor keyword. |
175 | | */ |
176 | | void DetectIkeVendorRegister(void) |
177 | 73 | { |
178 | 73 | sigmatch_table[DETECT_AL_IKE_VENDOR].name = "ike.vendor"; |
179 | 73 | sigmatch_table[DETECT_AL_IKE_VENDOR].desc = "match IKE Vendor"; |
180 | 73 | sigmatch_table[DETECT_AL_IKE_VENDOR].url = "/rules/ike-keywords.html#ike-vendor"; |
181 | 73 | sigmatch_table[DETECT_AL_IKE_VENDOR].Setup = DetectIkeVendorSetup; |
182 | 73 | sigmatch_table[DETECT_AL_IKE_VENDOR].flags |= SIGMATCH_NOOPT; |
183 | 73 | sigmatch_table[DETECT_AL_IKE_VENDOR].flags |= SIGMATCH_INFO_STICKY_BUFFER; |
184 | | |
185 | 73 | DetectAppLayerMpmRegister2("ike.vendor", SIG_FLAG_TOSERVER, 1, PrefilterMpmIkeVendorRegister, |
186 | 73 | NULL, ALPROTO_IKE, 1); |
187 | | |
188 | 73 | DetectAppLayerInspectEngineRegister2( |
189 | 73 | "ike.vendor", ALPROTO_IKE, SIG_FLAG_TOSERVER, 1, DetectEngineInspectIkeVendor, NULL); |
190 | | |
191 | 73 | g_ike_vendor_buffer_id = DetectBufferTypeGetByName("ike.vendor"); |
192 | | |
193 | 73 | DetectBufferTypeSupportsMultiInstance("ike.vendor"); |
194 | 73 | } |
195 | | |
196 | | /** |
197 | | * \brief setup the sticky buffer keyword used in the rule |
198 | | * |
199 | | * \param de_ctx Pointer to the Detection Engine Context |
200 | | * \param s Pointer to the Signature to which the current keyword belongs |
201 | | * \param str Should hold an empty string always |
202 | | * |
203 | | * \retval 0 On success |
204 | | * \retval -1 On failure |
205 | | */ |
206 | | |
207 | | static int DetectIkeVendorSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str) |
208 | 1.46k | { |
209 | 1.46k | if (DetectBufferSetActiveList(de_ctx, s, g_ike_vendor_buffer_id) < 0) |
210 | 76 | return -1; |
211 | 1.38k | if (DetectSignatureSetAppProto(s, ALPROTO_IKE) < 0) |
212 | 120 | return -1; |
213 | 1.26k | return 0; |
214 | 1.38k | } |