1 /*
2 ** Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 ** Copyright (C) 2002-2013 Sourcefire, Inc.
4 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License Version 2 as
8 ** published by the Free Software Foundation. You may not use, modify or
9 ** distribute this program under any other version of the GNU General
10 ** Public License.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software
19 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 **
21 ** Description
22 ** This file contains the utility functions used by rule options.
23 **
24 */
25
26 #ifndef __DETECTION_UTIL_H__
27 #define __DETECTION_UTIL_H__
28
29 #include <assert.h>
30
31 #include "sf_types.h"
32 #include "decode.h"
33 #include "detect.h"
34 #include "snort.h"
35 #include "snort_debug.h"
36 #include "treenodes.h"
37
38 #ifndef DECODE_BLEN
39 #define DECODE_BLEN 65535
40
41 #define MAX_URI 8192
42
43 // NOTE - if you change these, you must also change:
44 // dynamic-plugins/sf_dynamic_common.h
45 // dynamic-plugins/sf_dynamic_define.h
46 // dynamic-plugins/sf_engine/sf_snort_plugin_api.h
47 // detection-plugins/sp_pcre.h
48 typedef enum
49 {
50 HTTP_BUFFER_NONE,
51 HTTP_BUFFER_URI,
52 HTTP_BUFFER_HEADER,
53 HTTP_BUFFER_CLIENT_BODY,
54 HTTP_BUFFER_METHOD,
55 HTTP_BUFFER_COOKIE,
56 HTTP_BUFFER_STAT_CODE,
57 HTTP_BUFFER_STAT_MSG,
58 HTTP_BUFFER_RAW_URI,
59 HTTP_BUFFER_RAW_HEADER,
60 HTTP_BUFFER_RAW_COOKIE,
61 HTTP_BUFFER_MAX
62 } HTTP_BUFFER;
63 #endif
64
65 typedef enum {
66 FLAG_ALT_DECODE = 0x0001,
67 FLAG_ALT_DETECT = 0x0002,
68 FLAG_DETECT_ALL = 0xffff
69 } DetectFlagType;
70
71 #define DOE_BUF_URI 0x01
72 #define DOE_BUF_STD 0x02
73
74 #define HTTPURI_PIPELINE_REQ 0x01
75
76 #define HTTP_ENCODE_TYPE__UTF8_UNICODE 0x00000001
77 #define HTTP_ENCODE_TYPE__DOUBLE_ENCODE 0x00000002
78 #define HTTP_ENCODE_TYPE__NONASCII 0x00000004
79 #define HTTP_ENCODE_TYPE__BASE36 0x00000008
80 #define HTTP_ENCODE_TYPE__UENCODE 0x00000010
81 #define HTTP_ENCODE_TYPE__BARE_BYTE 0x00000020
82 #define HTTP_ENCODE_TYPE__IIS_UNICODE 0x00000040
83 #define HTTP_ENCODE_TYPE__ASCII 0x00000080
84
85 typedef struct
86 {
87 const uint8_t* buf;
88 uint16_t length;
89 uint32_t encode_type;
90 } HttpBuffer;
91
92 typedef struct {
93 const uint8_t *data;
94 uint16_t len;
95 } DataPointer;
96
97
98 typedef struct {
99 uint8_t data[DECODE_BLEN];
100 uint16_t len;
101 } DataBuffer;
102
103 extern uint8_t base64_decode_buf[DECODE_BLEN];
104 extern uint32_t base64_decode_size;
105
106 extern uint8_t mime_present;
107
108 extern uint8_t doe_buf_flags;
109 extern const uint8_t *doe_ptr;
110
111 extern void *global_ssl_callback;
112
113 extern uint16_t detect_flags;
114
115 extern uint32_t http_mask;
116 extern HttpBuffer http_buffer[HTTP_BUFFER_MAX];
117 extern const char* http_buffer_name[HTTP_BUFFER_MAX];
118
119 extern DataPointer DetectBuffer;
120 extern DataPointer file_data_ptr;
121 extern DataBuffer DecodeBuffer;
122
ClearHttpBuffers(void)123 static inline void ClearHttpBuffers (void)
124 {
125 http_mask = 0;
126 }
127
GetHttpBufferMask(void)128 static inline uint32_t GetHttpBufferMask (void)
129 {
130 return http_mask;
131 }
132
GetHttpBuffer(HTTP_BUFFER b)133 static inline const HttpBuffer* GetHttpBuffer (HTTP_BUFFER b)
134 {
135 if ( !((1 << b) & http_mask) )
136 return NULL;
137
138 return http_buffer + b;
139 }
140
SetHttpBufferEncoding(HTTP_BUFFER b,const uint8_t * buf,unsigned len,uint32_t enc)141 static inline void SetHttpBufferEncoding (
142 HTTP_BUFFER b, const uint8_t* buf, unsigned len, uint32_t enc)
143 {
144 HttpBuffer* hb = http_buffer + b;
145 assert(b < HTTP_BUFFER_MAX && buf);
146
147 hb->buf = buf;
148 hb->length = len;
149 hb->encode_type = enc;
150 http_mask |= (1 << b);
151 }
152
SetHttpBuffer(HTTP_BUFFER b,const uint8_t * buf,unsigned len)153 static inline void SetHttpBuffer (HTTP_BUFFER b, const uint8_t* buf, unsigned len)
154 {
155 SetHttpBufferEncoding(b, buf, len, 0);
156 }
157
158 #define SetDetectLimit(pktPtr, altLen) \
159 { \
160 pktPtr->alt_dsize = altLen; \
161 }
162
163 #define IsLimitedDetect(pktPtr) (pktPtr->packet_flags & PKT_HTTP_DECODE)
164
165 /*
166 * Function: setFileDataPtr
167 *
168 * Purpose: Sets the file data pointer used by
169 * file_data rule option.
170 *
171 * Arguments: ptr => pointer to the body data
172 *
173 * Returns: void
174 *
175 */
176
setFileDataPtr(const uint8_t * ptr,uint16_t decode_size)177 static inline void setFileDataPtr(const uint8_t *ptr, uint16_t decode_size)
178 {
179 file_data_ptr.data = ptr;
180 file_data_ptr.len = decode_size;
181 }
182
183 /*
184 * Function: IsBase64DecodeBuf
185 *
186 * Purpose: Checks if there is base64 decoded buffer.
187 *
188 * Arguments: p => doe_ptr
189 *
190 * Returns: Returns 1 if there is base64 decoded data
191 * and if the doe_ptr is within the buffer.
192 * Returns 0 otherwise.
193 *
194 */
195
IsBase64DecodeBuf(const uint8_t * p)196 static inline int IsBase64DecodeBuf(const uint8_t *p)
197 {
198 if( base64_decode_size && p )
199 {
200 if ((p >= base64_decode_buf) &&
201 (p < (base64_decode_buf + base64_decode_size)))
202 {
203 return 1;
204 }
205 else
206 return 0;
207 }
208 else
209 return 0;
210 }
211
212 /*
213 * Function: SetDoePtr(const uint8_t *ptr, uint8_t type)
214 *
215 * Purpose: This function set the doe_ptr and sets the type of
216 * buffer to which doe_ptr points.
217 *
218 * Arguments: ptr => pointer
219 * type => type of buffer
220 *
221 * Returns: void
222 *
223 */
224
SetDoePtr(const uint8_t * ptr,uint8_t type)225 static inline void SetDoePtr(const uint8_t *ptr, uint8_t type)
226 {
227 doe_ptr = ptr;
228 doe_buf_flags = type;
229 }
230
231 /*
232 * Function: UpdateDoePtr(const uint8_t *ptr, uint8_t update)
233 *
234 * Purpose: This function updates the doe_ptr and resets the type of
235 * buffer to which doe_ptr points based on the update value.
236 *
237 * Arguments: ptr => pointer
238 * update => reset the buf flag if update is not zero.
239 *
240 * Returns: void
241 *
242 */
243
UpdateDoePtr(const uint8_t * ptr,uint8_t update)244 static inline void UpdateDoePtr(const uint8_t *ptr, uint8_t update)
245 {
246 doe_ptr = ptr;
247 if(update)
248 doe_buf_flags = DOE_BUF_STD;
249 }
250
251 void EventTrace_Init(void);
252 void EventTrace_Term(void);
253
254 void EventTrace_Log(const Packet*, OptTreeNode*, int action);
255
EventTrace_IsEnabled(void)256 static inline int EventTrace_IsEnabled (void)
257 {
258 return ( snort_conf->event_trace_max > 0 );
259 }
260
DetectFlag_Enable(DetectFlagType df)261 static inline void DetectFlag_Enable(DetectFlagType df)
262 {
263 detect_flags |= df;
264 }
265
DetectFlag_Disable(DetectFlagType df)266 static inline void DetectFlag_Disable(DetectFlagType df)
267 {
268 detect_flags &= ~df;
269 }
270
Is_DetectFlag(DetectFlagType df)271 static inline int Is_DetectFlag(DetectFlagType df)
272 {
273 return ( (detect_flags & df) != 0 );
274 }
275
Get_DetectFlags(void)276 static inline uint16_t Get_DetectFlags(void)
277 {
278 return detect_flags;
279 }
280
Reset_DetectFlags(uint16_t dflags)281 static inline void Reset_DetectFlags(uint16_t dflags)
282 {
283 detect_flags = dflags;
284 }
285
SetSSLCallback(void * p)286 static inline void SetSSLCallback(void *p)
287 {
288 global_ssl_callback = p;
289 }
290
GetSSLCallback(void)291 static inline void *GetSSLCallback(void)
292 {
293 return global_ssl_callback;
294 }
295
GetAltDetect(uint8_t ** bufPtr,uint16_t * altLenPtr)296 static inline int GetAltDetect(uint8_t **bufPtr, uint16_t *altLenPtr)
297 {
298 if ( Is_DetectFlag(FLAG_ALT_DETECT) )
299 {
300 *bufPtr = (uint8_t*) DetectBuffer.data;
301 *altLenPtr = DetectBuffer.len;
302 return 1;
303 }
304
305 return 0;
306 }
307
SetAltDetect(const uint8_t * buf,uint16_t altLen)308 static inline void SetAltDetect(const uint8_t *buf, uint16_t altLen)
309 {
310 DetectFlag_Enable(FLAG_ALT_DETECT);
311 DetectBuffer.data = buf;
312 DetectBuffer.len = altLen;
313 }
314
SetAltDecode(uint16_t altLen)315 static inline void SetAltDecode(uint16_t altLen)
316 {
317 DetectFlag_Enable(FLAG_ALT_DECODE);
318 DecodeBuffer.len = altLen;
319 }
320
DetectReset(const uint8_t * buf,uint16_t altLen)321 static inline void DetectReset(const uint8_t *buf, uint16_t altLen)
322 {
323 DetectBuffer.data = buf;
324 DetectBuffer.len = altLen;
325
326 DetectFlag_Disable(FLAG_DETECT_ALL);
327
328 /* Reset the values */
329
330 file_data_ptr.data = NULL;
331 file_data_ptr.len = 0;
332 base64_decode_size = 0;
333 doe_buf_flags = 0;
334 mime_present = 0;
335 DecodeBuffer.len = 0;
336 }
337
338
339 #endif
340
341