1 /* $Id$ */
2 /*
3 ** Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
4 ** Copyright (C) 2002-2013 Sourcefire, Inc.
5 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
6 **
7 ** This program is free software; you can redistribute it and/or modify
8 ** it under the terms of the GNU General Public License Version 2 as
9 ** published by the Free Software Foundation. You may not use, modify or
10 ** distribute this program under any other version of the GNU General
11 ** Public License.
12 **
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ** GNU General Public License for more details.
17 **
18 ** You should have received a copy of the GNU General Public License
19 ** along with this program; if not, write to the Free Software
20 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23 #ifndef __SP_PATTERN_MATCH_H__
24 #define __SP_PATTERN_MATCH_H__
25
26 #include <ctype.h>
27
28 #include "snort.h"
29 #include "snort_debug.h"
30 #include "rules.h" /* needed for OptTreeNode defintion */
31 #include "treenodes.h"
32 #include "detection_util.h"
33 #include "hashstring.h"
34
35 /********************************************************************
36 * Macros
37 ********************************************************************/
38 #define CHECK_AND_PATTERN_MATCH 1
39 #define CHECK_URI_PATTERN_MATCH 2
40 #define PMD_WITHIN_UNDEFINED ((unsigned) -1)
41
42 /********************************************************************
43 * Data structures
44 ********************************************************************/
45 typedef struct _PatternMatchData
46 {
47 int offset; /* pattern search start offset */
48 int depth; /* pattern search depth */
49
50 int distance; /* offset to start from based on last match */
51 u_int within; /* this pattern must be found
52 within X bytes of last match*/
53
54 int8_t offset_var; /* byte_extract variable indices for offset, */
55 int8_t depth_var; /* depth, distance, within */
56 int8_t distance_var;
57 int8_t within_var;
58
59 int rawbytes; /* Search the raw bytes rather than any decoded app
60 buffer */
61 int replace_depth; /* >=0 is offset to start of replace */
62
63 int nocase; /* Toggle case insensitity */
64 int use_doe; /* Use the doe_ptr for relative pattern searching */
65 HTTP_BUFFER http_buffer;/* Index of the URI buffer */
66 int buffer_func; /* buffer function CheckAND or CheckUri */
67 u_int pattern_size; /* size of app layer pattern */
68 u_int replace_size; /* size of app layer replace pattern */
69 char *replace_buf; /* app layer pattern to replace with */
70 char *pattern_buf; /* app layer pattern to match on */
71 int (*search)(const char *, int, struct _PatternMatchData *); /* search function */
72 int *skip_stride; /* B-M skip array */
73 int *shift_stride; /* B-M shift array */
74 u_int pattern_max_jump_size; /* Maximum distance we can jump to search for
75 * this pattern again. */
76 OptFpList *fpl; /* Pointer to the OTN FPList for this pattern */
77 /* Needed to be able to set the isRelative flag */
78
79 /* Set if fast pattern matcher found a content in the packet,
80 but the rule option specifies a negated content. Only
81 applies to negative contents that are not relative */
82 struct
83 {
84 struct timeval ts;
85 uint64_t packet_number;
86 uint32_t rebuild_flag;
87
88 } last_check;
89
90 /* For fast_pattern arguments */
91 uint8_t fp;
92 uint8_t fp_only;
93 uint16_t fp_offset;
94 uint16_t fp_length;
95
96 uint8_t exception_flag; /* search for "not this pattern" */
97
98 /* Used in ds_list - do not try to iterate after parsing a rule
99 * since the detection option tree will eliminate duplicates and
100 * the list may have missing pmds */
101 struct _PatternMatchData *prev; /* ptr to previous match struct */
102 struct _PatternMatchData *next; /* ptr to next match struct */
103
104 Secure_Hash_Type pattern_type;
105 int protected_length;
106 bool protected_pattern;
107 } PatternMatchData;
108
109 /********************************************************************
110 * Public function prototypes
111 ********************************************************************/
112 void SetupPatternMatch(void);
113 PatternMatchData * NewNode(OptTreeNode *, int);
114 void PatternMatchFree(void *d);
115 uint32_t PatternMatchHash(void *d);
116 int PatternMatchCompare(void *l, void *r);
117 void FinalizeContentUniqueness(struct _SnortConfig *sc, OptTreeNode *otn);
118 void ValidateFastPattern(OptTreeNode *otn);
119 void make_precomp(PatternMatchData *);
120 void ParsePattern(char *, OptTreeNode *, int);
121 void ParseProtectedPattern(char *, OptTreeNode *, int);
122 int uniSearchCI(const char *, int, PatternMatchData *);
123 int CheckANDPatternMatch(void *, Packet *);
124 int CheckUriPatternMatch(void *, Packet *);
125 void PatternMatchDuplicatePmd(void *, PatternMatchData *);
126 int PatternMatchAdjustRelativeOffsets(PatternMatchData *orig_pmd, PatternMatchData *dup_pmd,
127 const uint8_t *current_cursor, const uint8_t *orig_cursor);
128
129 #if 0
130 /* Not implemented */
131 int CheckORPatternMatch(Packet *, OptTreeNode *, OptFpList *);
132 #endif
133
IsHttpBufFpEligible(HTTP_BUFFER http_buffer)134 static inline bool IsHttpBufFpEligible (HTTP_BUFFER http_buffer)
135 {
136 switch ( http_buffer )
137 {
138 case HTTP_BUFFER_URI:
139 case HTTP_BUFFER_HEADER:
140 case HTTP_BUFFER_CLIENT_BODY:
141 return true;
142 default:
143 break;
144 }
145 return false;
146 }
147
RemovePmdFromList(PatternMatchData * pmd)148 static inline PatternMatchData * RemovePmdFromList(PatternMatchData *pmd)
149 {
150 if (pmd == NULL)
151 return NULL;
152
153 if (pmd->prev)
154 pmd->prev->next = pmd->next;
155 if (pmd->next)
156 pmd->next->prev = pmd->prev;
157
158 pmd->next = NULL;
159 pmd->prev = NULL;
160
161 return pmd;
162 }
163
InsertPmdAtFront(PatternMatchData ** head,PatternMatchData * ins)164 static inline int InsertPmdAtFront(PatternMatchData **head, PatternMatchData *ins)
165 {
166 if (head == NULL)
167 return -1;
168
169 if (ins == NULL)
170 return 0;
171
172 ins->next = *head;
173 if (*head != NULL)
174 (*head)->prev = ins;
175 *head = ins;
176
177 return 0;
178 }
179
AppendPmdToList(PatternMatchData ** head,PatternMatchData * ins)180 static inline int AppendPmdToList(PatternMatchData **head, PatternMatchData *ins)
181 {
182 PatternMatchData *tmp;
183
184 if (head == NULL)
185 return -1;
186
187 if (ins == NULL)
188 return 0;
189
190 if (*head == NULL)
191 {
192 *head = ins;
193 ins->prev = NULL;
194 return 0;
195 }
196
197 for (tmp = *head; tmp->next != NULL; tmp = tmp->next);
198 tmp->next = ins;
199 ins->prev = tmp;
200
201 return 0;
202 }
203
204
FreePmdList(PatternMatchData * pmd_list)205 static inline void FreePmdList(PatternMatchData *pmd_list)
206 {
207 if (pmd_list == NULL)
208 return;
209
210 while (pmd_list != NULL)
211 {
212 PatternMatchData *tmp = pmd_list->next;
213 PatternMatchFree((void *)pmd_list);
214 pmd_list = tmp;
215 }
216 }
217
218 #endif /* __SP_PATTERN_MATCH_H__ */
219