]>
Commit | Line | Data |
---|---|---|
a0ee6ade | 1 | /* Copyright (C) 2007-2011 Open Information Security Foundation |
ce019275 WM |
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. | |
0165b3f0 | 11 | * |
ce019275 WM |
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 | ||
60a99915 EL |
18 | /** |
19 | * \defgroup httplayer HTTP layer support | |
20 | * | |
21 | * @{ | |
22 | */ | |
23 | ||
ce019275 WM |
24 | /** |
25 | * \file | |
0165b3f0 | 26 | * |
07f7ba55 | 27 | * \author Gurvinder Singh <gurvindersinghdahiya@gmail.com> |
0165b3f0 | 28 | * \author Pablo Rincon <pablo.rincon.crespo@gmail.com> |
07f7ba55 | 29 | * |
ce019275 | 30 | * This file provides a HTTP protocol support for the engine using HTP library. |
07f7ba55 GS |
31 | */ |
32 | ||
48248687 VJ |
33 | #ifndef __APP_LAYER_HTP_H__ |
34 | #define __APP_LAYER_HTP_H__ | |
07f7ba55 | 35 | |
a9cdd2bb | 36 | #include "util-radix-tree.h" |
e1022ee5 | 37 | #include "util-file.h" |
a9cdd2bb | 38 | |
07f7ba55 GS |
39 | #include <htp/htp.h> |
40 | ||
6ebe7b7c | 41 | /* default request body limit */ |
2763a612 VJ |
42 | #define HTP_CONFIG_DEFAULT_REQUEST_BODY_LIMIT 4096U |
43 | #define HTP_CONFIG_DEFAULT_RESPONSE_BODY_LIMIT 4096U | |
44 | #define HTP_CONFIG_DEFAULT_REQUEST_INSPECT_MIN_SIZE 32768U | |
45 | #define HTP_CONFIG_DEFAULT_REQUEST_INSPECT_WINDOW 4096U | |
46 | #define HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_MIN_SIZE 32768U | |
47 | #define HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_WINDOW 4096U | |
a0ee6ade VJ |
48 | |
49 | /** a boundary should be smaller in size */ | |
50 | #define HTP_BOUNDARY_MAX 200U | |
6ebe7b7c | 51 | |
9878eca0 | 52 | #define HTP_FLAG_STATE_OPEN 0x0001 /**< Flag to indicate that HTTP |
0165b3f0 | 53 | connection is open */ |
64625675 | 54 | #define HTP_FLAG_STATE_CLOSED_TS 0x0002 /**< Flag to indicate that HTTP |
0165b3f0 | 55 | connection is closed */ |
64625675 AS |
56 | #define HTP_FLAG_STATE_CLOSED_TC 0x0004 /**< Flag to indicate that HTTP |
57 | connection is closed */ | |
58 | #define HTP_FLAG_STATE_DATA 0x0008 /**< Flag to indicate that HTTP | |
0165b3f0 | 59 | connection needs more data */ |
64625675 | 60 | #define HTP_FLAG_STATE_ERROR 0x0010 /**< Flag to indicate that an error |
0165b3f0 PR |
61 | has been occured on HTTP |
62 | connection */ | |
64625675 | 63 | #define HTP_FLAG_NEW_BODY_SET 0x0020 /**< Flag to indicate that HTTP |
0165b3f0 PR |
64 | has parsed a new body (for |
65 | pcre) */ | |
64625675 AS |
66 | #define HTP_FLAG_STORE_FILES_TS 0x0040 |
67 | #define HTP_FLAG_STORE_FILES_TC 0x0080 | |
68 | #define HTP_FLAG_STORE_FILES_TX_TS 0x0100 | |
69 | #define HTP_FLAG_STORE_FILES_TX_TC 0x0200 | |
c2c53994 | 70 | /** flag the state that a new file has been set in this tx */ |
64625675 | 71 | #define HTP_FLAG_NEW_FILE_TX_TS 0x0400 |
c2c53994 | 72 | /** flag the state that a new file has been set in this tx */ |
64625675 | 73 | #define HTP_FLAG_NEW_FILE_TX_TC 0x0800 |
9878eca0 | 74 | |
0165b3f0 | 75 | enum { |
23e01d23 | 76 | HTP_BODY_NONE = 0, /**< Flag to indicate the current |
0165b3f0 PR |
77 | operation */ |
78 | HTP_BODY_REQUEST, /**< Flag to indicate that the | |
79 | current operation is a request */ | |
80 | HTP_BODY_RESPONSE /**< Flag to indicate that the current | |
81 | * operation is a response */ | |
82 | }; | |
83 | ||
23e01d23 VJ |
84 | enum { |
85 | HTP_BODY_REQUEST_NONE = 0, | |
3702a33a VJ |
86 | HTP_BODY_REQUEST_MULTIPART, /* POST, MP */ |
87 | HTP_BODY_REQUEST_POST, /* POST, no MP */ | |
23e01d23 VJ |
88 | HTP_BODY_REQUEST_PUT, |
89 | }; | |
90 | ||
f713b653 | 91 | enum { |
e21d8cdf | 92 | /* libhtp errors/warnings */ |
f713b653 VJ |
93 | HTTP_DECODER_EVENT_UNKNOWN_ERROR, |
94 | HTTP_DECODER_EVENT_GZIP_DECOMPRESSION_FAILED, | |
95 | HTTP_DECODER_EVENT_REQUEST_FIELD_MISSING_COLON, | |
93d121bf | 96 | HTTP_DECODER_EVENT_RESPONSE_FIELD_MISSING_COLON, |
f713b653 VJ |
97 | HTTP_DECODER_EVENT_INVALID_REQUEST_CHUNK_LEN, |
98 | HTTP_DECODER_EVENT_INVALID_RESPONSE_CHUNK_LEN, | |
99 | HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST, | |
100 | HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE, | |
101 | HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST, | |
102 | HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE, | |
103 | HTTP_DECODER_EVENT_100_CONTINUE_ALREADY_SEEN, | |
104 | HTTP_DECODER_EVENT_UNABLE_TO_MATCH_RESPONSE_TO_REQUEST, | |
105 | HTTP_DECODER_EVENT_INVALID_SERVER_PORT_IN_REQUEST, | |
106 | HTTP_DECODER_EVENT_INVALID_AUTHORITY_PORT, | |
107 | HTTP_DECODER_EVENT_REQUEST_HEADER_INVALID, | |
93d121bf | 108 | HTTP_DECODER_EVENT_RESPONSE_HEADER_INVALID, |
f713b653 VJ |
109 | HTTP_DECODER_EVENT_MISSING_HOST_HEADER, |
110 | HTTP_DECODER_EVENT_HOST_HEADER_AMBIGUOUS, | |
111 | HTTP_DECODER_EVENT_INVALID_REQUEST_FIELD_FOLDING, | |
112 | HTTP_DECODER_EVENT_INVALID_RESPONSE_FIELD_FOLDING, | |
113 | HTTP_DECODER_EVENT_REQUEST_FIELD_TOO_LONG, | |
114 | HTTP_DECODER_EVENT_RESPONSE_FIELD_TOO_LONG, | |
9f519e95 | 115 | HTTP_DECODER_EVENT_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH, |
e21d8cdf VJ |
116 | |
117 | /* suricata errors/warnings */ | |
118 | HTTP_DECODER_EVENT_MULTIPART_GENERIC_ERROR, | |
119 | HTTP_DECODER_EVENT_MULTIPART_NO_FILEDATA, | |
120 | HTTP_DECODER_EVENT_MULTIPART_INVALID_HEADER, | |
f713b653 VJ |
121 | }; |
122 | ||
0165b3f0 PR |
123 | #define HTP_PCRE_NONE 0x00 /**< No pcre executed yet */ |
124 | #define HTP_PCRE_DONE 0x01 /**< Flag to indicate that pcre has | |
125 | done some inspection in the | |
126 | chunks */ | |
127 | #define HTP_PCRE_HAS_MATCH 0x02 /**< Flag to indicate that the chunks | |
128 | matched on some rule */ | |
129 | ||
2763a612 VJ |
130 | /** Need a linked list in order to keep track of these */ |
131 | typedef struct HTPCfgRec_ { | |
132 | htp_cfg_t *cfg; | |
133 | struct HTPCfgRec_ *next; | |
134 | ||
135 | /** max size of the client body we inspect */ | |
136 | uint32_t request_body_limit; | |
137 | uint32_t response_body_limit; | |
138 | ||
139 | uint32_t request_inspect_min_size; | |
140 | uint32_t request_inspect_window; | |
141 | ||
142 | uint32_t response_inspect_min_size; | |
143 | uint32_t response_inspect_window; | |
144 | } HTPCfgRec; | |
145 | ||
0165b3f0 | 146 | /** Struct used to hold chunks of a body on a request */ |
d378b76c | 147 | struct HtpBodyChunk_ { |
0165b3f0 | 148 | uint8_t *data; /**< Pointer to the data of the chunk */ |
a0ee6ade VJ |
149 | struct HtpBodyChunk_ *next; /**< Pointer to the next chunk */ |
150 | uint64_t stream_offset; | |
d378b76c VJ |
151 | uint32_t len; /**< Length of the chunk */ |
152 | } __attribute__((__packed__)); | |
153 | typedef struct HtpBodyChunk_ HtpBodyChunk; | |
0165b3f0 PR |
154 | |
155 | /** Struct used to hold all the chunks of a body on a request */ | |
7a8cd61f VJ |
156 | typedef struct HtpBody_ { |
157 | HtpBodyChunk *first; /**< Pointer to the first chunk */ | |
158 | HtpBodyChunk *last; /**< Pointer to the last chunk */ | |
a0ee6ade | 159 | |
b402d971 VJ |
160 | /* Holds the length of the htp request body */ |
161 | uint64_t content_len; | |
162 | /* Holds the length of the htp request body seen so far */ | |
163 | uint64_t content_len_so_far; | |
d378b76c | 164 | /* parser tracker */ |
b402d971 | 165 | uint64_t body_parsed; |
d378b76c VJ |
166 | /* inspection tracker */ |
167 | uint64_t body_inspected; | |
0165b3f0 | 168 | } HtpBody; |
fc2f7f29 | 169 | |
d378b76c | 170 | #define HTP_REQ_BODY_COMPLETE 0x01 /**< body is complete or limit is reached, |
a0ee6ade | 171 | either way, this is it. */ |
d378b76c VJ |
172 | #define HTP_RES_BODY_COMPLETE 0x02 |
173 | #define HTP_CONTENTTYPE_SET 0x04 /**< We have the content type */ | |
174 | #define HTP_BOUNDARY_SET 0x08 /**< We have a boundary string */ | |
175 | #define HTP_BOUNDARY_OPEN 0x10 /**< We have a boundary string */ | |
176 | #define HTP_FILENAME_SET 0x20 /**< filename is registered in the flow */ | |
177 | #define HTP_DONTSTORE 0x40 /**< not storing this file */ | |
23e01d23 VJ |
178 | |
179 | #define HTP_TX_HAS_FILE 0x01 | |
180 | #define HTP_TX_HAS_FILENAME 0x02 /**< filename is known at this time */ | |
181 | #define HTP_TX_HAS_TYPE 0x04 | |
182 | #define HTP_TX_HAS_FILECONTENT 0x08 /**< file has content so we can do type detect */ | |
183 | ||
184 | #define HTP_RULE_NEED_FILE HTP_TX_HAS_FILE | |
185 | #define HTP_RULE_NEED_FILENAME HTP_TX_HAS_FILENAME | |
186 | #define HTP_RULE_NEED_TYPE HTP_TX_HAS_TYPE | |
187 | #define HTP_RULE_NEED_FILECONTENT HTP_TX_HAS_FILECONTENT | |
6ebe7b7c | 188 | |
06a65cb4 PR |
189 | /** Now the Body Chunks will be stored per transaction, at |
190 | * the tx user data */ | |
66a3cd96 | 191 | typedef struct HtpTxUserData_ { |
5c6a65dc | 192 | /* Body of the request (if any) */ |
66a3cd96 | 193 | HtpBody request_body; |
b402d971 | 194 | HtpBody response_body; |
a0ee6ade VJ |
195 | |
196 | /** Holds the boundary identificator string if any (used on | |
197 | * multipart/form-data only) | |
198 | */ | |
6d60b3a7 | 199 | uint8_t *boundary; |
a0ee6ade | 200 | uint8_t boundary_len; |
6d60b3a7 | 201 | |
43c7fd75 VJ |
202 | uint8_t tsflags; |
203 | uint8_t tcflags; | |
b402d971 VJ |
204 | |
205 | int16_t operation; | |
d378b76c VJ |
206 | |
207 | uint8_t request_body_type; | |
208 | uint8_t response_body_type; | |
209 | ||
66a3cd96 | 210 | } HtpTxUserData; |
06a65cb4 | 211 | |
07f7ba55 | 212 | typedef struct HtpState_ { |
07f7ba55 | 213 | |
7a8cd61f VJ |
214 | htp_connp_t *connp; /**< Connection parser structure for |
215 | each connection */ | |
6d60b3a7 | 216 | Flow *f; /**< Needed to retrieve the original flow when usin HTPLib callbacks */ |
d4d18e31 AS |
217 | uint64_t transaction_cnt; |
218 | uint64_t transaction_done; | |
219 | uint64_t store_tx_id; | |
d59ca75e VJ |
220 | FileContainer *files_ts; |
221 | FileContainer *files_tc; | |
2763a612 | 222 | struct HTPCfgRec_ *cfg; |
d4d18e31 | 223 | uint16_t flags; |
07f7ba55 GS |
224 | } HtpState; |
225 | ||
6fa46d75 | 226 | /** part of the engine needs the request body (e.g. http_client_body keyword) */ |
92679442 | 227 | #define HTP_REQUIRE_REQUEST_BODY (1 << 0) |
6fa46d75 AS |
228 | /** part of the engine needs the request body multipart header (e.g. filename |
229 | * and / or fileext keywords) */ | |
92679442 | 230 | #define HTP_REQUIRE_REQUEST_MULTIPART (1 << 1) |
6fa46d75 | 231 | /** part of the engine needs the request file (e.g. log-file module) */ |
92679442 | 232 | #define HTP_REQUIRE_REQUEST_FILE (1 << 2) |
6fa46d75 | 233 | /** part of the engine needs the request body (e.g. file_data keyword) */ |
92679442 EL |
234 | #define HTP_REQUIRE_RESPONSE_BODY (1 << 3) |
235 | ||
236 | SC_ATOMIC_DECLARE(uint32_t, htp_config_flags); | |
6fa46d75 | 237 | |
07f7ba55 GS |
238 | void RegisterHTPParsers(void); |
239 | void HTPParserRegisterTests(void); | |
fc2f7f29 GS |
240 | void HTPAtExitPrintStats(void); |
241 | void HTPFreeConfig(void); | |
48248687 | 242 | |
0165b3f0 PR |
243 | htp_tx_t *HTPTransactionMain(const HtpState *); |
244 | ||
245 | int HTPCallbackRequestBodyData(htp_tx_data_t *); | |
4e44073c | 246 | int HtpTransactionGetLoggableId(Flow *); |
0165b3f0 PR |
247 | void HtpBodyPrint(HtpBody *); |
248 | void HtpBodyFree(HtpBody *); | |
25a3a5c6 PR |
249 | /* To free the state from unittests using app-layer-htp */ |
250 | void HTPStateFree(void *); | |
97d49d8f | 251 | void AppLayerHtpEnableRequestBodyCallback(void); |
b402d971 | 252 | void AppLayerHtpEnableResponseBodyCallback(void); |
6d60b3a7 | 253 | void AppLayerHtpNeedFileInspection(void); |
6fca55e0 | 254 | void AppLayerHtpPrintStats(void); |
0165b3f0 | 255 | |
48248687 | 256 | #endif /* __APP_LAYER_HTP_H__ */ |
07f7ba55 | 257 | |
60a99915 EL |
258 | /** |
259 | * @} | |
260 | */ |