1 /*
2 ** Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 ** Copyright (C) 1998-2013 Sourcefire, Inc.
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License Version 2 as
7 ** published by the Free Software Foundation. You may not use, modify or
8 ** distribute this program under any other version of the GNU General
9 ** Public License.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21 /* sp_file_data
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <sys/types.h>
30 #include <stdlib.h>
31 #include <ctype.h>
32 #ifdef HAVE_STRINGS_H
33 #include <strings.h>
34 #endif
35 #include <errno.h>
36
37 #include "sf_types.h"
38 #include "snort_bounds.h"
39 #include "rules.h"
40 #include "decode.h"
41 #include "plugbase.h"
42 #include "parser.h"
43 #include "snort_debug.h"
44 #include "util.h"
45 #include "mstring.h"
46
47 #include "snort.h"
48 #include "profiler.h"
49 #include "sp_file_data.h"
50 #ifdef PERF_PROFILING
51 PreprocStats fileDataPerfStats;
52 extern PreprocStats ruleOTNEvalPerfStats;
53 #endif
54
55 #include "detection_options.h"
56 #include "detection_util.h"
57
58 extern char *file_name; /* this is the file name from rules.c, generally used
59 for error messages */
60
61 extern int file_line; /* this is the file line number from rules.c that is
62 used to indicate file lines for error messages */
63
64 static void FileDataInit(struct _SnortConfig *, char *, OptTreeNode *, int);
65 void FileDataParse(char *, FileData *, OptTreeNode *);
66 int FileDataEval(void *option_data, Packet *p);
67
FileDataHash(void * d)68 uint32_t FileDataHash(void *d)
69 {
70 uint32_t a,b,c;
71
72 FileData *data = (FileData *)d;
73
74 a = data->mime_decode_flag;
75 b = RULE_OPTION_TYPE_FILE_DATA;
76 c = 0;
77
78 final(a,b,c);
79
80 return c;
81 }
82
FileDataCompare(void * l,void * r)83 int FileDataCompare(void *l, void *r)
84 {
85 FileData *left = (FileData *)l;
86 FileData *right = (FileData *)r;
87 if (!left || !right)
88 return DETECTION_OPTION_NOT_EQUAL;
89 if( left->mime_decode_flag == right->mime_decode_flag )
90 return DETECTION_OPTION_EQUAL;
91
92 return DETECTION_OPTION_NOT_EQUAL;
93 }
94
95
96
97 /****************************************************************************
98 *
99 * Function: SetupFileData()
100 *
101 * Purpose: Load 'er up
102 *
103 * Arguments: None.
104 *
105 * Returns: void function
106 *
107 ****************************************************************************/
SetupFileData(void)108 void SetupFileData(void)
109 {
110 /* map the keyword to an initialization/processing function */
111 RegisterRuleOption("file_data", FileDataInit, NULL, OPT_TYPE_DETECTION, NULL);
112 #ifdef PERF_PROFILING
113 RegisterPreprocessorProfile("file_data", &fileDataPerfStats, 3, &ruleOTNEvalPerfStats, NULL);
114 #endif
115
116 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: file_data Setup\n"););
117 }
118
119
120 /****************************************************************************
121 *
122 * Function: FileDataInit(struct _SnortConfig *, char *, OptTreeNode *, int protocol)
123 *
124 * Purpose: Generic rule configuration function. Handles parsing the rule
125 * information and attaching the associated detection function to
126 * the OTN.
127 *
128 * Arguments: data => rule arguments/data
129 * otn => pointer to the current rule option list node
130 * protocol => protocol the rule is on (we don't care in this case)
131 *
132 * Returns: void function
133 *
134 ****************************************************************************/
FileDataInit(struct _SnortConfig * sc,char * data,OptTreeNode * otn,int protocol)135 static void FileDataInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol)
136 {
137 FileData *idx;
138 OptFpList *fpl;
139 void *idx_dup;
140
141 idx = (FileData *) SnortAlloc(sizeof(FileData));
142
143 if(idx == NULL)
144 {
145 FatalError("%s(%d): Unable to allocate file_data node\n",
146 file_name, file_line);
147 }
148
149
150
151 otn->ds_list[PLUGIN_FILE_DATA] = (void *)1;
152
153 FileDataParse(data, idx, otn);
154
155 if (add_detection_option(sc, RULE_OPTION_TYPE_FILE_DATA, (void *)idx, &idx_dup) == DETECTION_OPTION_EQUAL)
156 {
157 free(idx);
158 idx = idx_dup;
159 }
160
161 fpl = AddOptFuncToList(FileDataEval, otn);
162 fpl->type = RULE_OPTION_TYPE_FILE_DATA;
163 fpl->context = (void *)idx;
164
165 return;
166 }
167
168
169
170 /****************************************************************************
171 *
172 * Function: FileDataParse(char *, OptTreeNode *)
173 *
174 * Purpose: This is the function that is used to process the option keyword's
175 * arguments and attach them to the rule's data structures.
176 *
177 * Arguments: data => argument data
178 * otn => pointer to the current rule's OTN
179 *
180 * Returns: void function
181 *
182 ****************************************************************************/
FileDataParse(char * data,FileData * idx,OptTreeNode * otn)183 void FileDataParse(char *data, FileData *idx, OptTreeNode *otn)
184 {
185
186 if (IsEmptyStr(data))
187 {
188 idx->mime_decode_flag = 0;
189 }
190 else if(!strcasecmp("mime",data))
191 {
192 ParseWarning("The argument 'mime' to 'file_data' rule option is deprecated.\n");
193 }
194 else
195 {
196 FatalError("%s(%d) file_data: Invalid token %s\n",
197 file_name, file_line, data);
198 }
199
200 return;
201
202 }
203
204 /****************************************************************************
205 *
206 * Function: FileDataEval(char *, OptTreeNode *, OptFpList *)
207 *
208 * Purpose: Use this function to perform the particular detection routine
209 * that this rule keyword is supposed to encompass.
210 *
211 * Arguments: p => pointer to the decoded packet
212 * otn => pointer to the current rule's OTN
213 * fp_list => pointer to the function pointer list
214 *
215 * Returns: If the detection test fails, this function *must* return a zero!
216 * On success, it calls the next function in the detection list
217 *
218 ****************************************************************************/
FileDataEval(void * option_data,Packet * p)219 int FileDataEval(void *option_data, Packet *p)
220 {
221 int rval = DETECTION_OPTION_NO_MATCH;
222 const uint8_t *data;
223 uint16_t len;
224 FileData *idx;
225 PROFILE_VARS;
226
227 PREPROC_PROFILE_START(fileDataPerfStats);
228 idx = (FileData *)option_data;
229
230 data = file_data_ptr.data;
231 len = file_data_ptr.len;
232
233 if ((p->dsize == 0) || !idx)
234 {
235 PREPROC_PROFILE_END(fileDataPerfStats);
236 return rval;
237 }
238
239 if ((data == NULL)|| (len == 0))
240 {
241 data = p->data;
242 len = p->dsize;
243 }
244
245 if(idx->mime_decode_flag)
246 mime_present = 1;
247 else
248 mime_present = 0;
249
250 SetDoePtr(data, DOE_BUF_STD);
251 SetAltDetect(data, len);
252 rval = DETECTION_OPTION_MATCH;
253
254 PREPROC_PROFILE_END(fileDataPerfStats);
255 return rval;
256 }
257