]> git.ipfire.org Git - people/ms/suricata.git/blame - src/app-layer-htp.h
ftp: small code cleanup
[people/ms/suricata.git] / src / app-layer-htp.h
CommitLineData
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"
ced01da8 38#include "app-layer-htp-mem.h"
6279da0f 39#include "detect-engine-state.h"
46e55f1e 40#include "util-streaming-buffer.h"
910922cd 41#include "rust.h"
a9cdd2bb 42
07f7ba55
GS
43#include <htp/htp.h>
44
6ebe7b7c 45/* default request body limit */
2763a612
VJ
46#define HTP_CONFIG_DEFAULT_REQUEST_BODY_LIMIT 4096U
47#define HTP_CONFIG_DEFAULT_RESPONSE_BODY_LIMIT 4096U
48#define HTP_CONFIG_DEFAULT_REQUEST_INSPECT_MIN_SIZE 32768U
49#define HTP_CONFIG_DEFAULT_REQUEST_INSPECT_WINDOW 4096U
50#define HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_MIN_SIZE 32768U
51#define HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_WINDOW 4096U
fb496791
VJ
52#define HTP_CONFIG_DEFAULT_FIELD_LIMIT_SOFT 9000U
53#define HTP_CONFIG_DEFAULT_FIELD_LIMIT_HARD 18000U
a0ee6ade 54
61a6eaf3
JI
55/* default libhtp lzma limit, taken from libhtp. */
56#define HTP_CONFIG_DEFAULT_LZMA_MEMLIMIT 1048576U
af4f8162 57#define HTP_CONFIG_DEFAULT_COMPRESSION_BOMB_LIMIT 1048576U
61a6eaf3 58
ff784075
EL
59#define HTP_CONFIG_DEFAULT_RANDOMIZE 1
60#define HTP_CONFIG_DEFAULT_RANDOMIZE_RANGE 10
61
a0ee6ade
VJ
62/** a boundary should be smaller in size */
63#define HTP_BOUNDARY_MAX 200U
6ebe7b7c 64
e6494114 65// 0x0001 not used
64625675 66#define HTP_FLAG_STATE_CLOSED_TS 0x0002 /**< Flag to indicate that HTTP
0165b3f0 67 connection is closed */
64625675
AS
68#define HTP_FLAG_STATE_CLOSED_TC 0x0004 /**< Flag to indicate that HTTP
69 connection is closed */
64625675
AS
70#define HTP_FLAG_STORE_FILES_TS 0x0040
71#define HTP_FLAG_STORE_FILES_TC 0x0080
72#define HTP_FLAG_STORE_FILES_TX_TS 0x0100
73#define HTP_FLAG_STORE_FILES_TX_TC 0x0200
9878eca0 74
23e01d23
VJ
75enum {
76 HTP_BODY_REQUEST_NONE = 0,
3702a33a
VJ
77 HTP_BODY_REQUEST_MULTIPART, /* POST, MP */
78 HTP_BODY_REQUEST_POST, /* POST, no MP */
23e01d23
VJ
79 HTP_BODY_REQUEST_PUT,
80};
81
f713b653 82enum {
e21d8cdf 83 /* libhtp errors/warnings */
f713b653
VJ
84 HTTP_DECODER_EVENT_UNKNOWN_ERROR,
85 HTTP_DECODER_EVENT_GZIP_DECOMPRESSION_FAILED,
86 HTTP_DECODER_EVENT_REQUEST_FIELD_MISSING_COLON,
93d121bf 87 HTTP_DECODER_EVENT_RESPONSE_FIELD_MISSING_COLON,
f713b653
VJ
88 HTTP_DECODER_EVENT_INVALID_REQUEST_CHUNK_LEN,
89 HTTP_DECODER_EVENT_INVALID_RESPONSE_CHUNK_LEN,
90 HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST,
91 HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE,
92 HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST,
93 HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE,
9cbf9ef7
PA
94 HTTP_DECODER_EVENT_DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST,
95 HTTP_DECODER_EVENT_DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE,
f713b653
VJ
96 HTTP_DECODER_EVENT_100_CONTINUE_ALREADY_SEEN,
97 HTTP_DECODER_EVENT_UNABLE_TO_MATCH_RESPONSE_TO_REQUEST,
98 HTTP_DECODER_EVENT_INVALID_SERVER_PORT_IN_REQUEST,
99 HTTP_DECODER_EVENT_INVALID_AUTHORITY_PORT,
100 HTTP_DECODER_EVENT_REQUEST_HEADER_INVALID,
93d121bf 101 HTTP_DECODER_EVENT_RESPONSE_HEADER_INVALID,
f713b653
VJ
102 HTTP_DECODER_EVENT_MISSING_HOST_HEADER,
103 HTTP_DECODER_EVENT_HOST_HEADER_AMBIGUOUS,
104 HTTP_DECODER_EVENT_INVALID_REQUEST_FIELD_FOLDING,
105 HTTP_DECODER_EVENT_INVALID_RESPONSE_FIELD_FOLDING,
106 HTTP_DECODER_EVENT_REQUEST_FIELD_TOO_LONG,
107 HTTP_DECODER_EVENT_RESPONSE_FIELD_TOO_LONG,
9f519e95 108 HTTP_DECODER_EVENT_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH,
cb150003
VJ
109 HTTP_DECODER_EVENT_URI_HOST_INVALID,
110 HTTP_DECODER_EVENT_HEADER_HOST_INVALID,
e78e33a4 111 HTTP_DECODER_EVENT_METHOD_DELIM_NON_COMPLIANT,
5ad7198d 112 HTTP_DECODER_EVENT_URI_DELIM_NON_COMPLIANT,
52195a41 113 HTTP_DECODER_EVENT_REQUEST_LINE_LEADING_WHITESPACE,
d0cded25
VJ
114 HTTP_DECODER_EVENT_TOO_MANY_ENCODING_LAYERS,
115 HTTP_DECODER_EVENT_ABNORMAL_CE_HEADER,
a1c6e091 116 HTTP_DECODER_EVENT_AUTH_UNRECOGNIZED,
b6b7778e
PA
117 HTTP_DECODER_EVENT_REQUEST_HEADER_REPETITION,
118 HTTP_DECODER_EVENT_RESPONSE_HEADER_REPETITION,
3e120668
PA
119 HTTP_DECODER_EVENT_RESPONSE_MULTIPART_BYTERANGES,
120 HTTP_DECODER_EVENT_RESPONSE_ABNORMAL_TRANSFER_ENCODING,
121 HTTP_DECODER_EVENT_RESPONSE_CHUNKED_OLD_PROTO,
122 HTTP_DECODER_EVENT_RESPONSE_INVALID_PROTOCOL,
123 HTTP_DECODER_EVENT_RESPONSE_INVALID_STATUS,
124 HTTP_DECODER_EVENT_REQUEST_LINE_INCOMPLETE,
8a339e73 125 HTTP_DECODER_EVENT_DOUBLE_ENCODED_URI,
b5f3e032
PA
126 HTTP_DECODER_EVENT_REQUEST_LINE_INVALID,
127 HTTP_DECODER_EVENT_REQUEST_BODY_UNEXPECTED,
e21d8cdf 128
c9c23d5c 129 HTTP_DECODER_EVENT_LZMA_MEMLIMIT_REACHED,
af4f8162 130 HTTP_DECODER_EVENT_COMPRESSION_BOMB,
c9c23d5c 131
e21d8cdf
VJ
132 /* suricata errors/warnings */
133 HTTP_DECODER_EVENT_MULTIPART_GENERIC_ERROR,
134 HTTP_DECODER_EVENT_MULTIPART_NO_FILEDATA,
135 HTTP_DECODER_EVENT_MULTIPART_INVALID_HEADER,
053c7288
PA
136
137 HTTP_DECODER_EVENT_TOO_MANY_WARNINGS,
f713b653
VJ
138};
139
d0f92e2a
GL
140typedef enum HtpSwfCompressType_ {
141 HTTP_SWF_COMPRESSION_NONE = 0,
142 HTTP_SWF_COMPRESSION_ZLIB,
143 HTTP_SWF_COMPRESSION_LZMA,
144 HTTP_SWF_COMPRESSION_BOTH,
145} HtpSwfCompressType;
146
6fb808fc 147typedef struct HTPCfgDir_ {
24a2f515
VJ
148 uint32_t body_limit;
149 uint32_t inspect_min_size;
150 uint32_t inspect_window;
6fb808fc
VJ
151 StreamingBufferConfig sbcfg;
152} HTPCfgDir;
153
2763a612
VJ
154/** Need a linked list in order to keep track of these */
155typedef struct HTPCfgRec_ {
156 htp_cfg_t *cfg;
157 struct HTPCfgRec_ *next;
158
a8b971c7
VJ
159 int uri_include_all; /**< use all info in uri (bool) */
160
2763a612 161 /** max size of the client body we inspect */
ff784075
EL
162 int randomize;
163 int randomize_range;
a459376d 164 int http_body_inline;
46e55f1e 165
d0f92e2a
GL
166 int swf_decompression_enabled;
167 HtpSwfCompressType swf_compression_type;
168 uint32_t swf_decompress_depth;
169 uint32_t swf_compress_depth;
170
6fb808fc
VJ
171 HTPCfgDir request;
172 HTPCfgDir response;
2763a612
VJ
173} HTPCfgRec;
174
0165b3f0 175/** Struct used to hold chunks of a body on a request */
d378b76c 176struct HtpBodyChunk_ {
a0ee6ade 177 struct HtpBodyChunk_ *next; /**< Pointer to the next chunk */
bac6c3ab 178 int logged;
269313a5 179 StreamingBufferSegment sbseg;
d378b76c
VJ
180} __attribute__((__packed__));
181typedef struct HtpBodyChunk_ HtpBodyChunk;
0165b3f0
PR
182
183/** Struct used to hold all the chunks of a body on a request */
7a8cd61f
VJ
184typedef struct HtpBody_ {
185 HtpBodyChunk *first; /**< Pointer to the first chunk */
186 HtpBodyChunk *last; /**< Pointer to the last chunk */
a0ee6ade 187
46e55f1e
VJ
188 StreamingBuffer *sb;
189
b402d971
VJ
190 /* Holds the length of the htp request body seen so far */
191 uint64_t content_len_so_far;
d378b76c 192 /* parser tracker */
b402d971 193 uint64_t body_parsed;
d378b76c
VJ
194 /* inspection tracker */
195 uint64_t body_inspected;
0165b3f0 196} HtpBody;
fc2f7f29 197
de904db8
GL
198#define HTP_CONTENTTYPE_SET BIT_U8(0) /**< We have the content type */
199#define HTP_BOUNDARY_SET BIT_U8(1) /**< We have a boundary string */
200#define HTP_BOUNDARY_OPEN BIT_U8(2) /**< We have a boundary string */
201#define HTP_FILENAME_SET BIT_U8(3) /**< filename is registered in the flow */
202#define HTP_DONTSTORE BIT_U8(4) /**< not storing this file */
203#define HTP_STREAM_DEPTH_SET BIT_U8(5) /**< stream-depth is set */
23e01d23 204
06a65cb4
PR
205/** Now the Body Chunks will be stored per transaction, at
206 * the tx user data */
66a3cd96 207typedef struct HtpTxUserData_ {
5c6a65dc 208 /* Body of the request (if any) */
48cf0585
AS
209 uint8_t request_body_init;
210 uint8_t response_body_init;
c52fe9a5 211
44022743
VJ
212 uint8_t request_has_trailers;
213 uint8_t response_has_trailers;
214
66a3cd96 215 HtpBody request_body;
b402d971 216 HtpBody response_body;
a0ee6ade 217
48cf0585
AS
218 bstr *request_uri_normalized;
219
220 uint8_t *request_headers_raw;
221 uint8_t *response_headers_raw;
222 uint32_t request_headers_raw_len;
223 uint32_t response_headers_raw_len;
224
3f5acc54
VJ
225 AppLayerDecoderEvents *decoder_events; /**< per tx events */
226
07c05f7d 227 /** Holds the boundary identification string if any (used on
a0ee6ade
VJ
228 * multipart/form-data only)
229 */
6d60b3a7 230 uint8_t *boundary;
a0ee6ade 231 uint8_t boundary_len;
6d60b3a7 232
43c7fd75
VJ
233 uint8_t tsflags;
234 uint8_t tcflags;
b402d971 235
d378b76c 236 uint8_t request_body_type;
d378b76c 237
6279da0f 238 DetectEngineState *de_state;
910922cd 239 AppLayerTxData tx_data;
66a3cd96 240} HtpTxUserData;
06a65cb4 241
07f7ba55 242typedef struct HtpState_ {
48cf0585
AS
243 /* Connection parser structure for each connection */
244 htp_connp_t *connp;
245 /* Connection structure for each connection */
246 htp_conn_t *conn;
07c05f7d 247 Flow *f; /**< Needed to retrieve the original flow when using HTPLib callbacks */
d4d18e31 248 uint64_t transaction_cnt;
d4d18e31 249 uint64_t store_tx_id;
d59ca75e
VJ
250 FileContainer *files_ts;
251 FileContainer *files_tc;
feafc838 252 const struct HTPCfgRec_ *cfg;
d4d18e31 253 uint16_t flags;
3f5acc54
VJ
254 uint16_t events;
255 uint16_t htp_messages_offset; /**< offset into conn->messages list */
9132e403 256 uint32_t file_track_id; /**< used to assign file track ids to files */
e02b74de
VJ
257 uint64_t last_request_data_stamp;
258 uint64_t last_response_data_stamp;
07f7ba55
GS
259} HtpState;
260
6fa46d75 261/** part of the engine needs the request body (e.g. http_client_body keyword) */
92679442 262#define HTP_REQUIRE_REQUEST_BODY (1 << 0)
6fa46d75
AS
263/** part of the engine needs the request body multipart header (e.g. filename
264 * and / or fileext keywords) */
92679442 265#define HTP_REQUIRE_REQUEST_MULTIPART (1 << 1)
6fa46d75 266/** part of the engine needs the request file (e.g. log-file module) */
92679442 267#define HTP_REQUIRE_REQUEST_FILE (1 << 2)
6fa46d75 268/** part of the engine needs the request body (e.g. file_data keyword) */
92679442
EL
269#define HTP_REQUIRE_RESPONSE_BODY (1 << 3)
270
3ae1854d 271SC_ATOMIC_EXTERN(uint32_t, htp_config_flags);
6fa46d75 272
07f7ba55
GS
273void RegisterHTPParsers(void);
274void HTPParserRegisterTests(void);
fc2f7f29
GS
275void HTPAtExitPrintStats(void);
276void HTPFreeConfig(void);
48248687 277
0165b3f0
PR
278void HtpBodyPrint(HtpBody *);
279void HtpBodyFree(HtpBody *);
25a3a5c6
PR
280/* To free the state from unittests using app-layer-htp */
281void HTPStateFree(void *);
97d49d8f 282void AppLayerHtpEnableRequestBodyCallback(void);
b402d971 283void AppLayerHtpEnableResponseBodyCallback(void);
6d60b3a7 284void AppLayerHtpNeedFileInspection(void);
6fca55e0 285void AppLayerHtpPrintStats(void);
0165b3f0 286
ab4b15c2
AS
287void HTPConfigure(void);
288
289void HtpConfigCreateBackup(void);
290void HtpConfigRestoreBackup(void);
291
48248687 292#endif /* __APP_LAYER_HTP_H__ */
07f7ba55 293
60a99915
EL
294/**
295 * @}
296 */