]> git.ipfire.org Git - people/ms/suricata.git/blob - src/app-layer-htp.h
http: adds events for each libhtp log
[people/ms/suricata.git] / src / app-layer-htp.h
1 /* Copyright (C) 2007-2011 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 * \defgroup httplayer HTTP layer support
20 *
21 * @{
22 */
23
24 /**
25 * \file
26 *
27 * \author Gurvinder Singh <gurvindersinghdahiya@gmail.com>
28 * \author Pablo Rincon <pablo.rincon.crespo@gmail.com>
29 *
30 * This file provides a HTTP protocol support for the engine using HTP library.
31 */
32
33 #ifndef __APP_LAYER_HTP_H__
34 #define __APP_LAYER_HTP_H__
35
36 #include "util-radix-tree.h"
37 #include "util-file.h"
38 #include "app-layer-htp-mem.h"
39 #include "detect-engine-state.h"
40 #include "util-streaming-buffer.h"
41
42 #include <htp/htp.h>
43
44 /* default request body limit */
45 #define HTP_CONFIG_DEFAULT_REQUEST_BODY_LIMIT 4096U
46 #define HTP_CONFIG_DEFAULT_RESPONSE_BODY_LIMIT 4096U
47 #define HTP_CONFIG_DEFAULT_REQUEST_INSPECT_MIN_SIZE 32768U
48 #define HTP_CONFIG_DEFAULT_REQUEST_INSPECT_WINDOW 4096U
49 #define HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_MIN_SIZE 32768U
50 #define HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_WINDOW 4096U
51 #define HTP_CONFIG_DEFAULT_FIELD_LIMIT_SOFT 9000U
52 #define HTP_CONFIG_DEFAULT_FIELD_LIMIT_HARD 18000U
53
54 #define HTP_CONFIG_DEFAULT_RANDOMIZE 1
55 #define HTP_CONFIG_DEFAULT_RANDOMIZE_RANGE 10
56
57 /** a boundary should be smaller in size */
58 #define HTP_BOUNDARY_MAX 200U
59
60 // 0x0001 not used
61 #define HTP_FLAG_STATE_CLOSED_TS 0x0002 /**< Flag to indicate that HTTP
62 connection is closed */
63 #define HTP_FLAG_STATE_CLOSED_TC 0x0004 /**< Flag to indicate that HTTP
64 connection is closed */
65 #define HTP_FLAG_STORE_FILES_TS 0x0040
66 #define HTP_FLAG_STORE_FILES_TC 0x0080
67 #define HTP_FLAG_STORE_FILES_TX_TS 0x0100
68 #define HTP_FLAG_STORE_FILES_TX_TC 0x0200
69
70 enum {
71 HTP_BODY_REQUEST_NONE = 0,
72 HTP_BODY_REQUEST_MULTIPART, /* POST, MP */
73 HTP_BODY_REQUEST_POST, /* POST, no MP */
74 HTP_BODY_REQUEST_PUT,
75 };
76
77 enum {
78 /* libhtp errors/warnings */
79 HTTP_DECODER_EVENT_UNKNOWN_ERROR,
80 HTTP_DECODER_EVENT_GZIP_DECOMPRESSION_FAILED,
81 HTTP_DECODER_EVENT_REQUEST_FIELD_MISSING_COLON,
82 HTTP_DECODER_EVENT_RESPONSE_FIELD_MISSING_COLON,
83 HTTP_DECODER_EVENT_INVALID_REQUEST_CHUNK_LEN,
84 HTTP_DECODER_EVENT_INVALID_RESPONSE_CHUNK_LEN,
85 HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST,
86 HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE,
87 HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST,
88 HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE,
89 HTTP_DECODER_EVENT_100_CONTINUE_ALREADY_SEEN,
90 HTTP_DECODER_EVENT_UNABLE_TO_MATCH_RESPONSE_TO_REQUEST,
91 HTTP_DECODER_EVENT_INVALID_SERVER_PORT_IN_REQUEST,
92 HTTP_DECODER_EVENT_INVALID_AUTHORITY_PORT,
93 HTTP_DECODER_EVENT_REQUEST_HEADER_INVALID,
94 HTTP_DECODER_EVENT_RESPONSE_HEADER_INVALID,
95 HTTP_DECODER_EVENT_MISSING_HOST_HEADER,
96 HTTP_DECODER_EVENT_HOST_HEADER_AMBIGUOUS,
97 HTTP_DECODER_EVENT_INVALID_REQUEST_FIELD_FOLDING,
98 HTTP_DECODER_EVENT_INVALID_RESPONSE_FIELD_FOLDING,
99 HTTP_DECODER_EVENT_REQUEST_FIELD_TOO_LONG,
100 HTTP_DECODER_EVENT_RESPONSE_FIELD_TOO_LONG,
101 HTTP_DECODER_EVENT_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH,
102 HTTP_DECODER_EVENT_URI_HOST_INVALID,
103 HTTP_DECODER_EVENT_HEADER_HOST_INVALID,
104 HTTP_DECODER_EVENT_METHOD_DELIM_NON_COMPLIANT,
105 HTTP_DECODER_EVENT_URI_DELIM_NON_COMPLIANT,
106 HTTP_DECODER_EVENT_REQUEST_LINE_LEADING_WHITESPACE,
107 HTTP_DECODER_EVENT_TOO_MANY_ENCODING_LAYERS,
108 HTTP_DECODER_EVENT_ABNORMAL_CE_HEADER,
109 HTTP_DECODER_EVENT_AUTH_UNRECOGNIZED,
110 HTTP_DECODER_EVENT_REQUEST_HEADER_REPETITION,
111 HTTP_DECODER_EVENT_RESPONSE_HEADER_REPETITION,
112 HTTP_DECODER_EVENT_RESPONSE_MULTIPART_BYTERANGES,
113 HTTP_DECODER_EVENT_RESPONSE_ABNORMAL_TRANSFER_ENCODING,
114 HTTP_DECODER_EVENT_RESPONSE_CHUNKED_OLD_PROTO,
115 HTTP_DECODER_EVENT_RESPONSE_INVALID_PROTOCOL,
116 HTTP_DECODER_EVENT_RESPONSE_INVALID_STATUS,
117 HTTP_DECODER_EVENT_REQUEST_LINE_INCOMPLETE,
118
119 /* suricata errors/warnings */
120 HTTP_DECODER_EVENT_MULTIPART_GENERIC_ERROR,
121 HTTP_DECODER_EVENT_MULTIPART_NO_FILEDATA,
122 HTTP_DECODER_EVENT_MULTIPART_INVALID_HEADER,
123 };
124
125 typedef enum HtpSwfCompressType_ {
126 HTTP_SWF_COMPRESSION_NONE = 0,
127 HTTP_SWF_COMPRESSION_ZLIB,
128 HTTP_SWF_COMPRESSION_LZMA,
129 HTTP_SWF_COMPRESSION_BOTH,
130 } HtpSwfCompressType;
131
132 typedef struct HTPCfgDir_ {
133 uint32_t body_limit;
134 uint32_t inspect_min_size;
135 uint32_t inspect_window;
136 StreamingBufferConfig sbcfg;
137 } HTPCfgDir;
138
139 /** Need a linked list in order to keep track of these */
140 typedef struct HTPCfgRec_ {
141 htp_cfg_t *cfg;
142 struct HTPCfgRec_ *next;
143
144 int uri_include_all; /**< use all info in uri (bool) */
145
146 /** max size of the client body we inspect */
147 int randomize;
148 int randomize_range;
149 int http_body_inline;
150
151 int swf_decompression_enabled;
152 HtpSwfCompressType swf_compression_type;
153 uint32_t swf_decompress_depth;
154 uint32_t swf_compress_depth;
155
156 HTPCfgDir request;
157 HTPCfgDir response;
158 } HTPCfgRec;
159
160 /** Struct used to hold chunks of a body on a request */
161 struct HtpBodyChunk_ {
162 struct HtpBodyChunk_ *next; /**< Pointer to the next chunk */
163 int logged;
164 StreamingBufferSegment sbseg;
165 } __attribute__((__packed__));
166 typedef struct HtpBodyChunk_ HtpBodyChunk;
167
168 /** Struct used to hold all the chunks of a body on a request */
169 typedef struct HtpBody_ {
170 HtpBodyChunk *first; /**< Pointer to the first chunk */
171 HtpBodyChunk *last; /**< Pointer to the last chunk */
172
173 StreamingBuffer *sb;
174
175 /* Holds the length of the htp request body seen so far */
176 uint64_t content_len_so_far;
177 /* parser tracker */
178 uint64_t body_parsed;
179 /* inspection tracker */
180 uint64_t body_inspected;
181 } HtpBody;
182
183 #define HTP_CONTENTTYPE_SET 0x01 /**< We have the content type */
184 #define HTP_BOUNDARY_SET 0x02 /**< We have a boundary string */
185 #define HTP_BOUNDARY_OPEN 0x04 /**< We have a boundary string */
186 #define HTP_FILENAME_SET 0x08 /**< filename is registered in the flow */
187 #define HTP_DONTSTORE 0x10 /**< not storing this file */
188
189 /** Now the Body Chunks will be stored per transaction, at
190 * the tx user data */
191 typedef struct HtpTxUserData_ {
192 /** detection engine flags */
193 uint64_t detect_flags_ts;
194 uint64_t detect_flags_tc;
195
196 /* Body of the request (if any) */
197 uint8_t request_body_init;
198 uint8_t response_body_init;
199
200 uint8_t request_has_trailers;
201 uint8_t response_has_trailers;
202
203 /* indicates which loggers that have logged */
204 uint32_t logged;
205
206 HtpBody request_body;
207 HtpBody response_body;
208
209 bstr *request_uri_normalized;
210
211 uint8_t *request_headers_raw;
212 uint8_t *response_headers_raw;
213 uint32_t request_headers_raw_len;
214 uint32_t response_headers_raw_len;
215
216 AppLayerDecoderEvents *decoder_events; /**< per tx events */
217
218 /** Holds the boundary identificator string if any (used on
219 * multipart/form-data only)
220 */
221 uint8_t *boundary;
222 uint8_t boundary_len;
223
224 uint8_t tsflags;
225 uint8_t tcflags;
226
227 uint8_t request_body_type;
228
229 DetectEngineState *de_state;
230 } HtpTxUserData;
231
232 typedef struct HtpState_ {
233 /* Connection parser structure for each connection */
234 htp_connp_t *connp;
235 /* Connection structure for each connection */
236 htp_conn_t *conn;
237 Flow *f; /**< Needed to retrieve the original flow when usin HTPLib callbacks */
238 uint64_t transaction_cnt;
239 uint64_t store_tx_id;
240 FileContainer *files_ts;
241 FileContainer *files_tc;
242 const struct HTPCfgRec_ *cfg;
243 uint16_t flags;
244 uint16_t events;
245 uint16_t htp_messages_offset; /**< offset into conn->messages list */
246 uint32_t file_track_id; /**< used to assign file track ids to files */
247 uint64_t last_request_data_stamp;
248 uint64_t last_response_data_stamp;
249 } HtpState;
250
251 /** part of the engine needs the request body (e.g. http_client_body keyword) */
252 #define HTP_REQUIRE_REQUEST_BODY (1 << 0)
253 /** part of the engine needs the request body multipart header (e.g. filename
254 * and / or fileext keywords) */
255 #define HTP_REQUIRE_REQUEST_MULTIPART (1 << 1)
256 /** part of the engine needs the request file (e.g. log-file module) */
257 #define HTP_REQUIRE_REQUEST_FILE (1 << 2)
258 /** part of the engine needs the request body (e.g. file_data keyword) */
259 #define HTP_REQUIRE_RESPONSE_BODY (1 << 3)
260
261 SC_ATOMIC_DECLARE(uint32_t, htp_config_flags);
262
263 void RegisterHTPParsers(void);
264 void HTPParserRegisterTests(void);
265 void HTPAtExitPrintStats(void);
266 void HTPFreeConfig(void);
267
268 void HtpBodyPrint(HtpBody *);
269 void HtpBodyFree(HtpBody *);
270 /* To free the state from unittests using app-layer-htp */
271 void HTPStateFree(void *);
272 void AppLayerHtpEnableRequestBodyCallback(void);
273 void AppLayerHtpEnableResponseBodyCallback(void);
274 void AppLayerHtpNeedFileInspection(void);
275 void AppLayerHtpPrintStats(void);
276
277 void HTPConfigure(void);
278
279 void HtpConfigCreateBackup(void);
280 void HtpConfigRestoreBackup(void);
281
282 #endif /* __APP_LAYER_HTP_H__ */
283
284 /**
285 * @}
286 */