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