78 static struct HTPConfigTree {
94 #define HTP_MAX_MESSAGES 512
100 static uint64_t htp_state_memuse = 0;
101 static uint64_t htp_state_memcnt = 0;
105 {
"UNKNOWN_ERROR", HTP_LOG_CODE_UNKNOWN },
106 {
"GZIP_DECOMPRESSION_FAILED", HTP_LOG_CODE_GZIP_DECOMPRESSION_FAILED },
107 {
"REQUEST_FIELD_MISSING_COLON", HTP_LOG_CODE_REQUEST_FIELD_MISSING_COLON },
108 {
"RESPONSE_FIELD_MISSING_COLON", HTP_LOG_CODE_RESPONSE_FIELD_MISSING_COLON },
109 {
"INVALID_REQUEST_CHUNK_LEN", HTP_LOG_CODE_INVALID_REQUEST_CHUNK_LEN },
110 {
"INVALID_RESPONSE_CHUNK_LEN", HTP_LOG_CODE_INVALID_RESPONSE_CHUNK_LEN },
111 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST",
112 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST },
113 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE",
114 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE },
115 {
"INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST",
116 HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST },
117 {
"INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE",
118 HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE },
119 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST",
120 HTP_LOG_CODE_DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST },
121 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE",
122 HTP_LOG_CODE_DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE },
123 {
"100_CONTINUE_ALREADY_SEEN", HTP_LOG_CODE_CONTINUE_ALREADY_SEEN },
124 {
"UNABLE_TO_MATCH_RESPONSE_TO_REQUEST", HTP_LOG_CODE_UNABLE_TO_MATCH_RESPONSE_TO_REQUEST },
125 {
"INVALID_SERVER_PORT_IN_REQUEST", HTP_LOG_CODE_INVALID_SERVER_PORT_IN_REQUEST },
126 {
"INVALID_AUTHORITY_PORT", HTP_LOG_CODE_INVALID_AUTHORITY_PORT },
127 {
"REQUEST_HEADER_INVALID", HTP_LOG_CODE_REQUEST_HEADER_INVALID },
128 {
"RESPONSE_HEADER_INVALID", HTP_LOG_CODE_RESPONSE_HEADER_INVALID },
129 {
"MISSING_HOST_HEADER", HTP_LOG_CODE_MISSING_HOST_HEADER },
130 {
"HOST_HEADER_AMBIGUOUS", HTP_LOG_CODE_HOST_HEADER_AMBIGUOUS },
131 {
"INVALID_REQUEST_FIELD_FOLDING", HTP_LOG_CODE_INVALID_REQUEST_FIELD_FOLDING },
132 {
"INVALID_RESPONSE_FIELD_FOLDING", HTP_LOG_CODE_INVALID_RESPONSE_FIELD_FOLDING },
133 {
"REQUEST_FIELD_TOO_LONG", HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG },
134 {
"RESPONSE_FIELD_TOO_LONG", HTP_LOG_CODE_RESPONSE_FIELD_TOO_LONG },
135 {
"REQUEST_LINE_INVALID", HTP_LOG_CODE_REQUEST_LINE_INVALID },
136 {
"REQUEST_BODY_UNEXPECTED", HTP_LOG_CODE_REQUEST_BODY_UNEXPECTED },
137 {
"RESPONSE_BODY_UNEXPECTED", HTP_LOG_CODE_RESPONSE_BODY_UNEXPECTED },
138 {
"REQUEST_SERVER_PORT_TCP_PORT_MISMATCH", HTP_LOG_CODE_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH },
139 {
"REQUEST_URI_HOST_INVALID", HTP_LOG_CODE_URI_HOST_INVALID },
140 {
"REQUEST_HEADER_HOST_INVALID", HTP_LOG_CODE_HEADER_HOST_INVALID },
141 {
"REQUEST_AUTH_UNRECOGNIZED", HTP_LOG_CODE_AUTH_UNRECOGNIZED },
142 {
"REQUEST_HEADER_REPETITION", HTP_LOG_CODE_REQUEST_HEADER_REPETITION },
143 {
"RESPONSE_HEADER_REPETITION", HTP_LOG_CODE_RESPONSE_HEADER_REPETITION },
144 {
"DOUBLE_ENCODED_URI", HTP_LOG_CODE_DOUBLE_ENCODED_URI },
145 {
"URI_DELIM_NON_COMPLIANT", HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT },
146 {
"METHOD_DELIM_NON_COMPLIANT", HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT },
147 {
"REQUEST_LINE_LEADING_WHITESPACE", HTP_LOG_CODE_REQUEST_LINE_LEADING_WHITESPACE },
148 {
"TOO_MANY_ENCODING_LAYERS", HTP_LOG_CODE_TOO_MANY_ENCODING_LAYERS },
149 {
"REQUEST_TOO_MANY_LZMA_LAYERS", HTP_LOG_CODE_REQUEST_TOO_MANY_LZMA_LAYERS },
150 {
"RESPONSE_TOO_MANY_LZMA_LAYERS", HTP_LOG_CODE_RESPONSE_TOO_MANY_LZMA_LAYERS },
151 {
"ABNORMAL_CE_HEADER", HTP_LOG_CODE_ABNORMAL_CE_HEADER },
152 {
"RESPONSE_MULTIPART_BYTERANGES", HTP_LOG_CODE_RESPONSE_MULTIPART_BYTERANGES },
153 {
"RESPONSE_ABNORMAL_TRANSFER_ENCODING", HTP_LOG_CODE_RESPONSE_ABNORMAL_TRANSFER_ENCODING },
154 {
"RESPONSE_CHUNKED_OLD_PROTO", HTP_LOG_CODE_RESPONSE_CHUNKED_OLD_PROTO },
155 {
"RESPONSE_INVALID_PROTOCOL", HTP_LOG_CODE_RESPONSE_INVALID_PROTOCOL },
156 {
"RESPONSE_INVALID_STATUS", HTP_LOG_CODE_RESPONSE_INVALID_STATUS },
157 {
"REQUEST_LINE_INCOMPLETE", HTP_LOG_CODE_REQUEST_LINE_INCOMPLETE },
158 {
"PROTOCOL_CONTAINS_EXTRA_DATA", HTP_LOG_CODE_PROTOCOL_CONTAINS_EXTRA_DATA },
160 "CONTENT_LENGTH_EXTRA_DATA_START",
161 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_START,
164 "CONTENT_LENGTH_EXTRA_DATA_END",
165 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_END,
168 "CONTENT_LENGTH_EXTRA_DATA_END",
169 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_END,
171 {
"SWITCHING_PROTO_WITH_CONTENT_LENGTH", HTP_LOG_CODE_SWITCHING_PROTO_WITH_CONTENT_LENGTH },
172 {
"DEFORMED_EOL", HTP_LOG_CODE_DEFORMED_EOL },
173 {
"PARSER_STATE_ERROR", HTP_LOG_CODE_PARSER_STATE_ERROR },
174 {
"MISSING_OUTBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_OUTBOUND_TRANSACTION_DATA },
175 {
"MISSING_INBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_INBOUND_TRANSACTION_DATA },
176 {
"MISSING_INBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_INBOUND_TRANSACTION_DATA },
177 {
"ZERO_LENGTH_DATA_CHUNKS", HTP_LOG_CODE_ZERO_LENGTH_DATA_CHUNKS },
178 {
"REQUEST_LINE_UNKNOWN_METHOD", HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD },
179 {
"REQUEST_LINE_UNKNOWN_METHOD", HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD },
180 {
"REQUEST_LINE_UNKNOWN_METHOD_NO_PROTOCOL",
181 HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD_NO_PROTOCOL },
182 {
"REQUEST_LINE_UNKNOWN_METHOD_INVALID_PROTOCOL",
183 HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD_INVALID_PROTOCOL },
184 {
"REQUEST_LINE_MISSING_PROTOCOL", HTP_LOG_CODE_REQUEST_LINE_NO_PROTOCOL },
185 {
"RESPONSE_LINE_INVALID_PROTOCOL", HTP_LOG_CODE_RESPONSE_LINE_INVALID_PROTOCOL },
186 {
"RESPONSE_LINE_INVALID_RESPONSE_STATUS", HTP_LOG_CODE_RESPONSE_LINE_INVALID_RESPONSE_STATUS },
187 {
"RESPONSE_BODY_INTERNAL_ERROR", HTP_LOG_CODE_RESPONSE_BODY_INTERNAL_ERROR },
188 {
"REQUEST_BODY_DATA_CALLBACK_ERROR", HTP_LOG_CODE_REQUEST_BODY_DATA_CALLBACK_ERROR },
189 {
"RESPONSE_INVALID_EMPTY_NAME", HTP_LOG_CODE_RESPONSE_INVALID_EMPTY_NAME },
190 {
"REQUEST_INVALID_EMPTY_NAME", HTP_LOG_CODE_REQUEST_INVALID_EMPTY_NAME },
191 {
"RESPONSE_INVALID_LWS_AFTER_NAME", HTP_LOG_CODE_RESPONSE_INVALID_LWS_AFTER_NAME },
192 {
"RESPONSE_HEADER_NAME_NOT_TOKEN", HTP_LOG_CODE_RESPONSE_HEADER_NAME_NOT_TOKEN },
193 {
"REQUEST_INVALID_LWS_AFTER_NAME", HTP_LOG_CODE_REQUEST_INVALID_LWS_AFTER_NAME },
194 {
"LZMA_DECOMPRESSION_DISABLED", HTP_LOG_CODE_LZMA_DECOMPRESSION_DISABLED },
195 {
"CONNECTION_ALREADY_OPEN", HTP_LOG_CODE_CONNECTION_ALREADY_OPEN },
196 {
"COMPRESSION_BOMB_DOUBLE_LZMA", HTP_LOG_CODE_COMPRESSION_BOMB_DOUBLE_LZMA },
197 {
"INVALID_CONTENT_ENCODING", HTP_LOG_CODE_INVALID_CONTENT_ENCODING },
198 {
"INVALID_GAP", HTP_LOG_CODE_INVALID_GAP },
199 {
"REQUEST_CHUNK_EXTENSION", HTP_LOG_CODE_REQUEST_CHUNK_EXTENSION },
200 {
"RESPONSE_CHUNK_EXTENSION", HTP_LOG_CODE_RESPONSE_CHUNK_EXTENSION },
202 {
"LZMA_MEMLIMIT_REACHED", HTP_LOG_CODE_LZMA_MEMLIMIT_REACHED },
203 {
"COMPRESSION_BOMB", HTP_LOG_CODE_COMPRESSION_BOMB },
205 {
"REQUEST_TOO_MANY_HEADERS", HTP_LOG_CODE_REQUEST_TOO_MANY_HEADERS },
206 {
"RESPONSE_TOO_MANY_HEADERS", HTP_LOG_CODE_RESPONSE_TOO_MANY_HEADERS },
239 static int HTTPGetFrameIdByName(
const char *frame_name)
248 static const char *HTTPGetFrameNameById(
const uint8_t frame_id)
258 HTP_REQUEST_PROGRESS_NOT_STARTED,
262 HTP_REQUEST_PROGRESS_LINE,
266 HTP_REQUEST_PROGRESS_HEADERS,
270 HTP_REQUEST_PROGRESS_BODY,
274 HTP_REQUEST_PROGRESS_TRAILER,
278 HTP_REQUEST_PROGRESS_COMPLETE,
287 HTP_RESPONSE_PROGRESS_NOT_STARTED,
291 HTP_RESPONSE_PROGRESS_LINE,
295 HTP_RESPONSE_PROGRESS_HEADERS,
299 HTP_RESPONSE_PROGRESS_BODY,
303 HTP_RESPONSE_PROGRESS_TRAILER,
307 HTP_RESPONSE_PROGRESS_COMPLETE,
312 static int HtpStateGetStateIdByName(
const char *
name,
const uint8_t direction)
315 direction == STREAM_TOSERVER ? http_state_client_table : http_state_server_table;
324 static const char *HtpStateGetStateNameById(
const int id,
const uint8_t direction)
327 direction == STREAM_TOSERVER ? http_state_client_table : http_state_server_table;
332 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id);
333 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction);
334 static uint64_t HTPStateGetTxCnt(
void *alstate);
336 static void HTPParserRegisterTests(
void);
339 static inline uint64_t HtpGetActiveRequestTxID(
HtpState *s)
341 uint64_t
id = HTPStateGetTxCnt(s);
346 static inline uint64_t HtpGetActiveResponseTxID(
HtpState *s)
359 static const char *HTPLookupPersonalityString(
int p)
361 #define CASE_HTP_PERSONALITY_STRING(p) \
362 case HTP_SERVER_PERSONALITY_##p: \
366 CASE_HTP_PERSONALITY_STRING(MINIMAL);
367 CASE_HTP_PERSONALITY_STRING(GENERIC);
368 CASE_HTP_PERSONALITY_STRING(IDS);
369 CASE_HTP_PERSONALITY_STRING(IIS_4_0);
370 CASE_HTP_PERSONALITY_STRING(IIS_5_0);
371 CASE_HTP_PERSONALITY_STRING(IIS_5_1);
372 CASE_HTP_PERSONALITY_STRING(IIS_6_0);
373 CASE_HTP_PERSONALITY_STRING(IIS_7_0);
374 CASE_HTP_PERSONALITY_STRING(IIS_7_5);
375 CASE_HTP_PERSONALITY_STRING(APACHE_2);
389 static int HTPLookupPersonality(
const char *
str)
391 #define IF_HTP_PERSONALITY_NUM(p) \
392 if (strcasecmp(#p, str) == 0) \
393 return HTP_SERVER_PERSONALITY_##p
405 if (strcasecmp(
"TOMCAT_6_0",
str) == 0) {
407 "longer supported by libhtp.",
410 }
else if ((strcasecmp(
"APACHE",
str) == 0) ||
411 (strcasecmp(
"APACHE_2_2",
str) == 0))
414 "longer supported by libhtp, failing back to "
415 "Apache2 personality.",
417 return HTP_SERVER_PERSONALITY_APACHE_2;
424 const uint8_t dir,
const uint8_t e)
434 const uint64_t tx_id = (dir == STREAM_TOSERVER) ?
435 HtpGetActiveRequestTxID(s) : HtpGetActiveResponseTxID(s);
437 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
438 if (tx == NULL && tx_id > 0)
439 tx = HTPStateGetTx(s, tx_id - 1);
454 static void *HTPStateAlloc(
void *orig_state,
AppProto proto_orig)
468 htp_state_memuse +=
sizeof(
HtpState);
469 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
487 SCAppLayerTxDataCleanup(&htud->
tx_data);
511 if (s->
connp != NULL) {
515 uint64_t total_txs = HTPStateGetTxCnt(state);
517 if (s->
conn != NULL) {
518 for (tx_id = 0; tx_id < total_txs; tx_id++) {
519 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
522 HtpTxUserDataFree(s, htud);
523 htp_tx_set_user_data(tx, NULL);
527 htp_connp_destroy_all(s->
connp);
535 htp_state_memuse -=
sizeof(
HtpState);
536 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
547 static void HTPStateTransactionFree(
void *state, uint64_t
id)
555 htp_tx_t *tx = HTPStateGetTx(s,
id);
559 HtpTxUserDataFree(s, htud);
560 htp_tx_set_user_data(tx, NULL);
561 htp_tx_destroy(s->
connp, tx);
607 static void AppLayerHtpSetStreamDepthFlag(
void *tx,
const uint8_t
flags)
612 if (
flags & STREAM_TOCLIENT) {
622 SCLogDebug(
"cfg->body_limit %u stream_depth %u body->content_len_so_far %" PRIu64,
639 static uint32_t AppLayerHtpComputeChunkLength(uint64_t content_len_so_far, uint32_t body_limit,
640 uint32_t stream_depth, uint8_t
flags, uint32_t data_len)
642 uint32_t chunk_len = 0;
644 (content_len_so_far < (uint64_t)body_limit) &&
645 (content_len_so_far + (uint64_t)data_len) > body_limit)
647 chunk_len = (uint32_t)(body_limit - content_len_so_far);
649 (content_len_so_far < (uint64_t)stream_depth) &&
650 (content_len_so_far + (uint64_t)data_len) > stream_depth)
652 chunk_len = (uint32_t)(stream_depth - content_len_so_far);
655 return (chunk_len == 0 ? data_len : chunk_len);
666 static void HTPHandleError(
HtpState *s,
const uint8_t dir)
673 htp_log_t *log = htp_conn_next_log(s->
conn);
674 while (log != NULL) {
675 char *msg = htp_log_message(log);
678 log = htp_conn_next_log(s->
conn);
684 htp_log_code_t
id = htp_log_code(log);
685 if (
id != HTP_LOG_CODE_UNKNOWN &&
id != HTP_LOG_CODE_ERROR) {
686 HTPSetEvent(s, NULL, dir, (uint8_t)
id);
688 htp_free_cstring(msg);
698 log = htp_conn_next_log(s->
conn);
703 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s,
const htp_tx_t *tx)
706 BUG_ON(s == NULL || tx == NULL);
708 if (htp_tx_flags(tx) & (HTP_FLAGS_REQUEST_INVALID_T_E | HTP_FLAGS_REQUEST_INVALID_C_L |
709 HTP_FLAGS_HOST_MISSING | HTP_FLAGS_HOST_AMBIGUOUS |
710 HTP_FLAGS_HOSTU_INVALID | HTP_FLAGS_HOSTH_INVALID)) {
715 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_T_E)
716 HTPSetEvent(s, htud, STREAM_TOSERVER,
717 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST);
718 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_C_L)
720 s, htud, STREAM_TOSERVER, HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST);
721 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_MISSING)
722 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_MISSING_HOST_HEADER);
723 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_AMBIGUOUS)
724 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HOST_HEADER_AMBIGUOUS);
725 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTU_INVALID)
726 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_URI_HOST_INVALID);
727 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTH_INVALID)
728 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HEADER_HOST_INVALID);
730 if (htp_tx_request_auth_type(tx) == HTP_AUTH_TYPE_UNRECOGNIZED) {
734 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_AUTH_UNRECOGNIZED);
736 if (htp_tx_is_protocol_0_9(tx) && htp_tx_request_method_number(tx) == HTP_METHOD_UNKNOWN &&
737 (htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_INVALID ||
738 htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_UNKNOWN)) {
742 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_REQUEST_LINE_INVALID);
752 htp_cfg_t *htp = cfglist.
cfg;
753 void *user_data = NULL;
769 if (user_data != NULL) {
770 htp_cfg_rec = user_data;
771 htp = htp_cfg_rec->
cfg;
774 SCLogDebug(
"Using default HTP config: %p", htp);
778 #ifdef DEBUG_VALIDATION
785 hstate->
connp = htp_connp_create(htp);
786 if (hstate->
connp == NULL) {
790 hstate->
conn = (htp_conn_t *)htp_connp_connection(hstate->
connp);
792 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
793 hstate->
cfg = htp_cfg_rec;
798 htp_connp_open(hstate->
connp, NULL, f->
sp, NULL, f->
dp, &
tv);
820 StreamSlice stream_slice,
void *local_data)
830 if (NULL == hstate->
conn) {
831 if (Setup(f, hstate) != 0) {
836 hstate->
slice = &stream_slice;
838 const uint8_t *input = StreamSliceGetData(&stream_slice);
839 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
844 const int r = htp_connp_request_data(hstate->
connp, &
ts, input, input_len);
846 case HTP_STREAM_STATE_ERROR:
852 HTPHandleError(hstate, STREAM_TOSERVER);
859 htp_connp_request_close(hstate->
connp, &
ts);
861 SCLogDebug(
"stream eof encountered, closing htp handle for ts");
865 hstate->
slice = NULL;
887 StreamSlice stream_slice,
void *local_data)
893 const uint8_t *input = StreamSliceGetData(&stream_slice);
894 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
900 if (NULL == hstate->
conn) {
901 if (Setup(f, hstate) != 0) {
906 hstate->
slice = &stream_slice;
909 const htp_tx_t *tx = NULL;
910 uint32_t consumed = 0;
912 const int r = htp_connp_response_data(hstate->
connp, &
ts, input, input_len);
914 case HTP_STREAM_STATE_ERROR:
917 case HTP_STREAM_STATE_TUNNEL:
918 tx = htp_connp_get_response_tx(hstate->
connp);
919 if (tx != NULL && htp_tx_response_status_number(tx) == 101) {
920 const htp_header_t *h = htp_tx_response_header(tx,
"Upgrade");
925 if (htp_tx_request_port_number(tx) != -1) {
926 dp = (uint16_t)htp_tx_request_port_number(tx);
928 consumed = (uint32_t)htp_connp_response_data_consumed(hstate->
connp);
929 if (bstr_cmp_c(htp_header_value(h),
"h2c") == 0) {
934 hstate->
slice = NULL;
936 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
941 if (consumed > 0 && consumed < input_len) {
945 }
else if (bstr_cmp_c_nocase(htp_header_value(h),
"WebSocket")) {
950 hstate->
slice = NULL;
952 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
957 if (consumed > 0 && consumed < input_len) {
967 HTPHandleError(hstate, STREAM_TOCLIENT);
974 htp_connp_close(hstate->
connp, &
ts);
979 hstate->
slice = NULL;
990 static int HTTPParseContentDispositionHeader(
const uint8_t *
name,
size_t name_len,
991 const uint8_t *data,
size_t len, uint8_t
const **retptr,
size_t *retlen)
994 printf(
"DATA START: \n");
996 printf(
"DATA END: \n");
1001 for (x = 0; x <
len; x++) {
1002 if (!(isspace(data[x])))
1009 const uint8_t *line = data + x;
1010 size_t line_len =
len-x;
1013 printf(
"LINE START: \n");
1015 printf(
"LINE END: \n");
1017 for (x = 0 ; x < line_len; x++) {
1019 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
1023 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
1024 const uint8_t *token = line +
offset;
1025 size_t token_len = x -
offset;
1027 if ((x + 1) == line_len) {
1038 printf(
"TOKEN START: \n");
1040 printf(
"TOKEN END: \n");
1042 if (token_len > name_len) {
1043 if (
name == NULL || SCMemcmpLowercase(
name, token, name_len) == 0) {
1044 const uint8_t *value = token + name_len;
1045 size_t value_len = token_len - name_len;
1047 if (value[0] ==
'\"') {
1051 if (value[value_len-1] ==
'\"') {
1055 printf(
"VALUE START: \n");
1057 printf(
"VALUE END: \n");
1060 *retlen = value_len;
1084 static int HtpRequestBodySetupMultipart(
const htp_tx_t *tx,
HtpTxUserData *htud)
1086 const htp_header_t *h = htp_tx_request_header(tx,
"Content-Type");
1087 if (h != NULL && htp_header_value_len(h) > 0) {
1089 SCMimeStateInit(htp_header_value_ptr(h), (uint32_t)htp_header_value_len(h));
1106 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1109 chunks_buffer, chunks_buffer_len,
1113 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1116 if (tx && tx->
tx_data.de_state) {
1117 if (dir == STREAM_TOSERVER) {
1118 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1120 }
else if (dir == STREAM_TOCLIENT) {
1121 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1128 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len,
bool eof)
1131 printf(
"CHUNK START: \n");
1133 printf(
"CHUNK END: \n");
1139 STREAM_TOSERVER) >= HTP_REQUEST_PROGRESS_COMPLETE);
1141 const uint8_t *cur_buf = chunks_buffer;
1142 uint32_t cur_buf_len = chunks_buffer_len;
1158 const uint8_t *filename = NULL;
1159 uint16_t filename_len = 0;
1162 while (cur_buf_len > 0) {
1163 MimeParserResult r =
1164 SCMimeParse(htud->
mime_state, cur_buf, cur_buf_len, &consumed, &warnings);
1168 if (warnings & MIME_EVENT_FLAG_INVALID_HEADER) {
1172 if (warnings & MIME_EVENT_FLAG_NO_FILEDATA) {
1183 SCMimeStateGetFilename(htud->
mime_state, &filename, &filename_len);
1184 if (filename_len > 0) {
1188 hstate, htud, filename, filename_len, NULL, 0, STREAM_TOSERVER);
1191 }
else if (result == -2) {
1194 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1202 }
else if (result == -2) {
1210 uint32_t lastsize = consumed;
1211 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\n') {
1213 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\r') {
1217 HTPFileClose(htud, cur_buf, lastsize, 0, STREAM_TOSERVER);
1222 cur_buf += consumed;
1223 cur_buf_len -= consumed;
1235 const uint8_t *data, uint32_t data_len)
1242 uint8_t *filename = NULL;
1243 size_t filename_len = 0;
1246 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1247 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1248 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1251 if (filename != NULL) {
1257 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1261 }
else if (result == -2) {
1264 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1278 }
else if (result == -2) {
1291 const uint8_t *data, uint32_t data_len)
1304 const uint8_t *filename = NULL;
1305 size_t filename_len = 0;
1308 const htp_header_t *h = htp_tx_response_header(tx,
"Content-Disposition");
1309 if (h != NULL && htp_header_value_len(h) > 0) {
1311 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1312 htp_header_value_ptr(h), htp_header_value_len(h), &filename, &filename_len);
1316 if (filename == NULL) {
1318 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1319 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1320 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1324 if (filename != NULL) {
1326 const htp_header_t *h_content_range = htp_tx_response_header(tx,
"content-range");
1332 if (h_content_range != NULL) {
1334 data_len, tx, htp_header_value(h_content_range), htud);
1336 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1342 }
else if (result == -2) {
1345 FlagDetectStateNewFile(htud, STREAM_TOCLIENT);
1358 }
else if (result == -2) {
1376 static int HTPCallbackRequestBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1380 const htp_tx_t *tx = htp_tx_data_tx(d);
1385 if (htp_tx_data_is_empty(d))
1389 printf(
"HTPBODY START: \n");
1390 PrintRawDataFp(stdout, (uint8_t *)htp_tx_data_data(d), htp_tx_data_len(d));
1391 printf(
"HTPBODY END: \n");
1394 HtpState *hstate = htp_connp_user_data(connp);
1395 if (hstate == NULL) {
1399 SCLogDebug(
"New request body data available at %p -> %p -> %p, bodylen "
1401 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1404 if (tx_ud == NULL) {
1407 tx_ud->
tx_data.updated_ts =
true;
1413 if (htp_tx_request_method_number(tx) == HTP_METHOD_POST) {
1415 int r = HtpRequestBodySetupMultipart(tx, tx_ud);
1418 }
else if (r == 0) {
1422 }
else if (htp_tx_request_method_number(tx) == HTP_METHOD_PUT) {
1438 (uint32_t)htp_tx_data_len(d));
1439 BUG_ON(
len > (uint32_t)htp_tx_data_len(d));
1443 const uint8_t *chunks_buffer = NULL;
1444 uint32_t chunks_buffer_len = 0;
1452 HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len);
1453 if (chunks_buffer == NULL) {
1457 printf(
"REASSCHUNK START: \n");
1459 printf(
"REASSCHUNK END: \n");
1462 HtpRequestBodyHandleMultipart(hstate, tx_ud, htp_tx_data_tx(d), chunks_buffer,
1463 chunks_buffer_len, (htp_tx_data_data(d) == NULL && htp_tx_data_len(d) == 0));
1467 HtpRequestBodyHandlePOSTorPUT(
1468 hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1473 SCLogDebug(
"closing file that was being stored");
1480 if (hstate->
conn != NULL) {
1481 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1482 ", last %" PRIu64
")",
1484 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1493 if ((uint64_t)htp_conn_request_data_counter(hstate->
conn) >
1495 (uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1497 (uint64_t)UINT_MAX) {
1498 uint32_t data_size =
1499 (uint32_t)((uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1520 static int HTPCallbackResponseBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1524 const htp_tx_t *tx = htp_tx_data_tx(d);
1529 if (htp_tx_data_is_empty(d))
1532 HtpState *hstate = htp_connp_user_data(connp);
1533 if (hstate == NULL) {
1537 SCLogDebug(
"New response body data available at %p -> %p -> %p, bodylen "
1539 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1542 if (tx_ud == NULL) {
1545 tx_ud->
tx_data.updated_tc =
true;
1562 (uint32_t)htp_tx_data_len(d));
1563 BUG_ON(
len > (uint32_t)htp_tx_data_len(d));
1567 HtpResponseBodyHandle(hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1570 SCLogDebug(
"closing file that was being stored");
1576 if (hstate->
conn != NULL) {
1577 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1578 ", last %" PRIu64
")",
1580 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1588 if ((uint64_t)htp_conn_response_data_counter(hstate->
conn) >
1590 (uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1592 (uint64_t)UINT_MAX) {
1593 uint32_t data_size =
1594 (uint32_t)((uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1618 SCLogDebug(
"http_state_memcnt %"PRIu64
", http_state_memuse %"PRIu64
"",
1619 htp_state_memcnt, htp_state_memuse);
1637 htp_config_destroy(cfglist.
cfg);
1638 while (nextrec != NULL) {
1640 nextrec = nextrec->
next;
1642 htp_config_destroy(htprec->
cfg);
1650 static int HTPCallbackRequestHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1654 htud->
tx_data.updated_ts =
true;
1657 return HTP_STATUS_OK;
1660 static int HTPCallbackResponseHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1664 htud->
tx_data.updated_tc =
true;
1667 return HTP_STATUS_OK;
1674 static int HTPCallbackRequestStart(
const htp_connp_t *connp, htp_tx_t *tx)
1676 HtpState *hstate = htp_connp_user_data(connp);
1677 if (hstate == NULL) {
1681 uint64_t consumed = hstate->
slice->offset + htp_connp_request_data_consumed(hstate->
connp);
1682 SCLogDebug(
"HTTP request start: data offset %" PRIu64
", in_data_counter %" PRIu64, consumed,
1683 (uint64_t)htp_conn_request_data_counter(hstate->
conn));
1699 if (tx_ud == NULL) {
1704 tx_ud->
tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT;
1705 htp_tx_set_user_data(tx, tx_ud);
1707 tx_ud->
tx_data.updated_ts =
true;
1716 static int HTPCallbackResponseStart(
const htp_connp_t *connp, htp_tx_t *tx)
1718 HtpState *hstate = htp_connp_user_data(connp);
1719 if (hstate == NULL) {
1723 uint64_t consumed = hstate->
slice->offset + htp_connp_response_data_consumed(hstate->
connp);
1724 SCLogDebug(
"HTTP response start: data offset %" PRIu64
", out_data_counter %" PRIu64, consumed,
1725 (uint64_t)htp_conn_response_data_counter(hstate->
conn));
1740 if (tx_ud == NULL) {
1747 htp_tx_set_user_data(tx, tx_ud);
1749 tx_ud->
tx_data.updated_tc =
true;
1760 static int HTPCallbackRequestComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1768 HtpState *hstate = htp_connp_user_data(connp);
1769 if (hstate == NULL) {
1773 const uint64_t abs_right_edge =
1774 hstate->
slice->offset + htp_connp_request_data_consumed(hstate->
connp);
1782 SCLogDebug(
"HTTP request complete: data offset %" PRIu64
", request_size %" PRIu64,
1784 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1786 frame->
len = (int64_t)request_size;
1792 SCLogDebug(
"transaction_cnt %"PRIu64
", list_size %"PRIu64,
1797 HTPErrorCheckTxRequestFlags(hstate, tx);
1801 htud->
tx_data.updated_ts =
true;
1803 SCLogDebug(
"closing file that was being stored");
1806 if (abs_right_edge < (uint64_t)UINT32_MAX) {
1808 hstate->
f->
protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
1826 static int HTPCallbackResponseComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1830 HtpState *hstate = htp_connp_user_data(connp);
1831 if (hstate == NULL) {
1838 const uint64_t abs_right_edge =
1839 hstate->
slice->offset + htp_connp_response_data_consumed(hstate->
connp);
1846 SCLogDebug(
"HTTP response complete: data offset %" PRIu64
", response_size %" PRIu64,
1848 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1850 frame->
len = (int64_t)response_size;
1857 htud->
tx_data.updated_tc =
true;
1859 SCLogDebug(
"closing file that was being stored");
1870 if (htp_tx_request_method_number(tx) == HTP_METHOD_CONNECT) {
1873 if ((htp_tx_response_status_number(tx) >= 200) &&
1874 (htp_tx_response_status_number(tx) < 300) && (hstate->
transaction_cnt == 1)) {
1876 if (htp_tx_request_port_number(tx) != -1) {
1877 dp = (uint16_t)htp_tx_request_port_number(tx);
1891 static int HTPCallbackRequestLine(
const htp_connp_t *connp, htp_tx_t *tx)
1894 HtpState *hstate = htp_connp_user_data(connp);
1896 tx_ud = htp_tx_get_user_data(tx);
1898 return HTP_STATUS_OK;
1901 if (htp_tx_flags(tx)) {
1902 HTPErrorCheckTxRequestFlags(hstate, tx);
1904 return HTP_STATUS_OK;
1907 static int HTPCallbackRequestHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1910 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1911 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1912 return HTP_STATUS_OK;
1915 if (tx_ud == NULL) {
1916 return HTP_STATUS_OK;
1921 return HTP_STATUS_OK;
1924 tx_ud->
tx_data.updated_ts =
true;
1927 htp_tx_data_len(tx_data));
1930 if (tx && htp_tx_flags(tx)) {
1931 HtpState *hstate = htp_connp_user_data(connp);
1932 HTPErrorCheckTxRequestFlags(hstate, tx);
1934 return HTP_STATUS_OK;
1937 static int HTPCallbackResponseHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1940 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1941 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1942 return HTP_STATUS_OK;
1945 if (tx_ud == NULL) {
1946 return HTP_STATUS_OK;
1948 tx_ud->
tx_data.updated_tc =
true;
1952 return HTP_STATUS_OK;
1957 htp_tx_data_len(tx_data));
1960 return HTP_STATUS_OK;
1966 static void HTPConfigSetDefaultsPhase1(
HTPCfgRec *cfg_prec)
1968 htp_config_set_normalized_uri_include_all(cfg_prec->
cfg,
false);
1983 htp_config_register_request_header_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1984 htp_config_register_request_trailer_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1985 htp_config_register_response_header_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1986 htp_config_register_response_trailer_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1988 htp_config_register_request_trailer(cfg_prec->
cfg, HTPCallbackRequestHasTrailer);
1989 htp_config_register_response_trailer(cfg_prec->
cfg, HTPCallbackResponseHasTrailer);
1991 htp_config_register_request_body_data(cfg_prec->
cfg, HTPCallbackRequestBodyData);
1992 htp_config_register_response_body_data(cfg_prec->
cfg, HTPCallbackResponseBodyData);
1994 htp_config_register_request_start(cfg_prec->
cfg, HTPCallbackRequestStart);
1995 htp_config_register_request_complete(cfg_prec->
cfg, HTPCallbackRequestComplete);
1997 htp_config_register_response_start(cfg_prec->
cfg, HTPCallbackResponseStart);
1998 htp_config_register_response_complete(cfg_prec->
cfg, HTPCallbackResponseComplete);
2000 htp_config_set_parse_request_cookies(cfg_prec->
cfg, 0);
2001 htp_config_set_allow_space_uri(cfg_prec->
cfg, 1);
2004 htp_config_set_plusspace_decode(cfg_prec->
cfg, 0);
2006 htp_config_set_request_decompression(cfg_prec->
cfg, 1);
2011 #define HTP_CONFIG_DEFAULT_MAX_TX_LIMIT 512
2013 #define HTP_CONFIG_DEFAULT_HEADERS_LIMIT 1024
2021 static int RandomGetWrap(
void)
2027 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
2029 return r % RAND_MAX;
2038 static void HTPConfigSetDefaultsPhase2(
const char *
name,
HTPCfgRec *cfg_prec)
2044 long int r = RandomGetWrap();
2046 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2048 r = RandomGetWrap();
2050 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2051 SCLogConfig(
"'%s' server has 'request-body-minimal-inspect-size' set to"
2052 " %u and 'request-body-inspect-window' set to %u after"
2056 r = RandomGetWrap();
2058 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2060 r = RandomGetWrap();
2062 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2064 SCLogConfig(
"'%s' server has 'response-body-minimal-inspect-size' set to"
2065 " %u and 'response-body-inspect-window' set to %u after"
2070 htp_config_register_request_line(cfg_prec->
cfg, HTPCallbackRequestLine);
2073 static void HTPConfigParseParameters(
HTPCfgRec *cfg_prec,
SCConfNode *s,
struct HTPConfigTree *tree)
2075 if (cfg_prec == NULL || s == NULL || tree == NULL)
2082 if (strcasecmp(
"address", p->
name) == 0) {
2088 if (strchr(pval->
val,
':') != NULL) {
2089 SCLogDebug(
"LIBHTP adding ipv6 server %s at %s: %p",
2093 SCLogWarning(
"LIBHTP failed to add ipv6 server %s, ignoring", pval->
val);
2096 SCLogDebug(
"LIBHTP adding ipv4 server %s at %s: %p",
2100 SCLogWarning(
"LIBHTP failed to add ipv4 server %s, ignoring", pval->
val);
2105 }
else if (strcasecmp(
"personality", p->
name) == 0) {
2107 int personality = HTPLookupPersonality(p->
val);
2111 if (personality >= 0) {
2114 if (htp_config_set_server_personality(cfg_prec->
cfg, personality) ==
2117 "personality \"%s\", ignoring",
2121 HTPLookupPersonalityString(personality));
2127 htp_config_set_convert_lowercase(cfg_prec->
cfg, 0);
2135 }
else if (strcasecmp(
"request-body-limit", p->
name) == 0 ||
2136 strcasecmp(
"request_body_limit", p->
name) == 0) {
2138 SCLogError(
"Error parsing request-body-limit "
2139 "from conf file - %s. Killing engine",
2144 }
else if (strcasecmp(
"response-body-limit", p->
name) == 0) {
2146 SCLogError(
"Error parsing response-body-limit "
2147 "from conf file - %s. Killing engine",
2152 }
else if (strcasecmp(
"request-body-minimal-inspect-size", p->
name) == 0) {
2154 SCLogError(
"Error parsing request-body-minimal-inspect-size "
2155 "from conf file - %s. Killing engine",
2160 }
else if (strcasecmp(
"request-body-inspect-window", p->
name) == 0) {
2162 SCLogError(
"Error parsing request-body-inspect-window "
2163 "from conf file - %s. Killing engine",
2168 }
else if (strcasecmp(
"double-decode-query", p->
name) == 0) {
2170 }
else if (strcasecmp(
"double-decode-path", p->
name) == 0) {
2172 }
else if (strcasecmp(
"response-body-minimal-inspect-size", p->
name) == 0) {
2174 SCLogError(
"Error parsing response-body-minimal-inspect-size "
2175 "from conf file - %s. Killing engine",
2180 }
else if (strcasecmp(
"response-body-inspect-window", p->
name) == 0) {
2182 SCLogError(
"Error parsing response-body-inspect-window "
2183 "from conf file - %s. Killing engine",
2188 }
else if (strcasecmp(
"response-body-decompress-layer-limit", p->
name) == 0) {
2191 SCLogError(
"Error parsing response-body-inspect-window "
2192 "from conf file - %s. Killing engine",
2196 htp_config_set_decompression_layer_limit(cfg_prec->
cfg, value);
2197 }
else if (strcasecmp(
"path-convert-backslash-separators", p->
name) == 0) {
2199 }
else if (strcasecmp(
"path-bestfit-replacement-char", p->
name) == 0) {
2200 if (strlen(p->
val) == 1) {
2201 htp_config_set_bestfit_replacement_byte(cfg_prec->
cfg, p->
val[0]);
2204 "for libhtp param path-bestfit-replacement-char");
2206 }
else if (strcasecmp(
"path-convert-lowercase", p->
name) == 0) {
2208 }
else if (strcasecmp(
"path-nul-encoded-terminates", p->
name) == 0) {
2210 }
else if (strcasecmp(
"path-nul-raw-terminates", p->
name) == 0) {
2212 }
else if (strcasecmp(
"path-separators-compress", p->
name) == 0) {
2214 }
else if (strcasecmp(
"path-separators-decode", p->
name) == 0) {
2216 }
else if (strcasecmp(
"path-u-encoding-decode", p->
name) == 0) {
2218 }
else if (strcasecmp(
"path-url-encoding-invalid-handling", p->
name) == 0) {
2219 enum htp_url_encoding_handling_t handling;
2220 if (strcasecmp(p->
val,
"preserve_percent") == 0) {
2221 handling = HTP_URL_ENCODING_HANDLING_PRESERVE_PERCENT;
2222 }
else if (strcasecmp(p->
val,
"remove_percent") == 0) {
2223 handling = HTP_URL_ENCODING_HANDLING_REMOVE_PERCENT;
2224 }
else if (strcasecmp(p->
val,
"decode_invalid") == 0) {
2225 handling = HTP_URL_ENCODING_HANDLING_PROCESS_INVALID;
2228 "for libhtp param path-url-encoding-invalid-handling");
2231 htp_config_set_url_encoding_invalid_handling(cfg_prec->
cfg, handling);
2232 }
else if (strcasecmp(
"path-utf8-convert-bestfit", p->
name) == 0) {
2234 }
else if (strcasecmp(
"uri-include-all", p->
name) == 0) {
2237 }
else if (strcasecmp(
"query-plusspace-decode", p->
name) == 0) {
2239 }
else if (strcasecmp(
"meta-field-limit", p->
name) == 0) {
2243 "from conf file - %s. Killing engine",
2249 "from conf file cannot be 0. Killing engine");
2252 htp_config_set_field_limit(cfg_prec->
cfg, (
size_t)limit);
2253 }
else if (strcasecmp(
"lzma-memlimit", p->
name) == 0) {
2256 FatalError(
"failed to parse 'lzma-memlimit' "
2257 "from conf file - %s.",
2262 "from conf file cannot be 0.");
2265 SCLogConfig(
"Setting HTTP LZMA memory limit to %"PRIu32
" bytes", limit);
2266 htp_config_set_lzma_memlimit(cfg_prec->
cfg, (
size_t)limit);
2267 }
else if (strcasecmp(
"lzma-enabled", p->
name) == 0) {
2269 htp_config_set_lzma_layers(cfg_prec->
cfg, 1);
2274 "from conf file - %s.",
2277 SCLogConfig(
"Setting HTTP LZMA decompression layers to %" PRIu32
"", (
int)limit);
2278 htp_config_set_lzma_layers(cfg_prec->
cfg, limit);
2280 }
else if (strcasecmp(
"compression-bomb-limit", p->
name) == 0) {
2283 FatalError(
"failed to parse 'compression-bomb-limit' "
2284 "from conf file - %s.",
2289 "from conf file cannot be 0.");
2292 SCLogConfig(
"Setting HTTP compression bomb limit to %"PRIu32
" bytes", limit);
2293 htp_config_set_compression_bomb_limit(cfg_prec->
cfg, (
size_t)limit);
2294 }
else if (strcasecmp(
"decompression-time-limit", p->
name) == 0) {
2298 FatalError(
"failed to parse 'decompression-time-limit' "
2299 "from conf file - %s.",
2302 SCLogConfig(
"Setting HTTP decompression time limit to %" PRIu32
" usec", limit);
2303 htp_config_set_compression_time_limit(cfg_prec->
cfg, limit);
2304 }
else if (strcasecmp(
"max-tx", p->
name) == 0) {
2308 "from conf file - %s.",
2312 SCLogConfig(
"Setting HTTP max-tx limit to %" PRIu32
" bytes", limit);
2313 htp_config_set_max_tx(cfg_prec->
cfg, limit);
2314 }
else if (strcasecmp(
"headers-limit", p->
name) == 0) {
2317 FatalError(
"failed to parse 'headers-limit' "
2318 "from conf file - %s.",
2321 SCLogConfig(
"Setting HTTP headers limit to %" PRIu32, limit);
2322 htp_config_set_number_headers_limit(cfg_prec->
cfg, limit);
2323 }
else if (strcasecmp(
"randomize-inspection-sizes", p->
name) == 0) {
2327 }
else if (strcasecmp(
"randomize-inspection-range", p->
name) == 0) {
2330 (
const char *)p->
val, 0, 100) < 0) {
2332 "-inspection-range setting from conf file - \"%s\"."
2333 " It should be a valid integer less than or equal to 100."
2339 }
else if (strcasecmp(
"http-body-inline", p->
name) == 0) {
2345 if (strcmp(
"auto", p->
val) != 0) {
2354 }
else if (strcasecmp(
"swf-decompression", p->
name) == 0) {
2358 if (strcasecmp(
"enabled", pval->
name) == 0) {
2366 }
else if (strcasecmp(
"type", pval->
name) == 0) {
2367 if (strcasecmp(
"no", pval->
val) == 0) {
2369 }
else if (strcasecmp(
"deflate", pval->
val) == 0) {
2371 }
else if (strcasecmp(
"lzma", pval->
val) == 0) {
2373 }
else if (strcasecmp(
"both", pval->
val) == 0) {
2377 "swf-decompression.type: %s - "
2382 }
else if (strcasecmp(
"compress-depth", pval->
name) == 0) {
2384 SCLogError(
"Error parsing swf-decompression.compression-depth "
2385 "from conf file - %s. Killing engine",
2389 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2391 SCLogError(
"Error parsing swf-decompression.decompression-depth "
2392 "from conf file - %s. Killing engine",
2402 "default config: %s",
2412 cfglist.
next = NULL;
2419 cfglist.
cfg = htp_config_create();
2420 if (NULL == cfglist.
cfg) {
2421 FatalError(
"Failed to create HTP default config");
2424 HTPConfigSetDefaultsPhase1(&cfglist);
2425 if (
SCConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2426 HTPConfigParseParameters(&cfglist,
SCConfGetNode(
"libhtp.default-config"), &cfgtree);
2428 HTPConfigParseParameters(&cfglist,
2429 SCConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), &cfgtree);
2431 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2437 if (server_config == NULL) {
2439 if (server_config == NULL) {
2440 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2444 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2463 cfglist.
next = htprec;
2466 cfglist.
next->
cfg = htp_config_create();
2467 if (NULL == cfglist.
next->
cfg) {
2468 FatalError(
"Failed to create HTP server config");
2471 HTPConfigSetDefaultsPhase1(htprec);
2472 HTPConfigParseParameters(htprec, s, &cfgtree);
2473 HTPConfigSetDefaultsPhase2(s->
name, htprec);
2483 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
2494 static AppLayerGetFileState HTPGetTxFiles(
void *txv, uint8_t direction)
2496 AppLayerGetFileState files = { .fc = NULL, .cfg = &
htp_sbcfg };
2497 htp_tx_t *tx = (htp_tx_t *)txv;
2500 if (direction & STREAM_TOCLIENT) {
2509 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
2511 if (direction & STREAM_TOSERVER)
2512 return htp_tx_request_progress((htp_tx_t *)tx);
2514 return htp_tx_response_progress((htp_tx_t *)tx);
2517 static uint64_t HTPStateGetTxCnt(
void *alstate)
2521 if (http_state != NULL && http_state->
connp != NULL) {
2522 const int64_t size = htp_connp_tx_size(http_state->
connp);
2526 return (uint64_t)size;
2532 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
2536 if (http_state != NULL && http_state->
connp != NULL)
2537 return (
void *)htp_connp_tx(http_state->
connp, tx_id);
2546 if (http_state != NULL && http_state->
connp != NULL) {
2547 size_t txid = htp_connp_tx_size(http_state->
connp);
2549 return (
void *)htp_connp_tx(http_state->
connp, txid - 1);
2555 static int HTPStateGetEventInfo(
2556 const char *event_name, uint8_t *event_id, AppLayerEventType *event_type)
2559 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2565 static int HTPStateGetEventInfoById(
2566 uint8_t event_id,
const char **event_name, AppLayerEventType *event_type)
2569 if (*event_name == NULL) {
2571 "http's enum map table.",
2577 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2584 htp_tx_t *tx = (htp_tx_t *)vtx;
2592 static AppLayerStateData *HTPGetStateData(
void *vstate)
2598 static int HTPRegisterPatternsForProtocolDetection(
void)
2600 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
2601 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
2602 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
2603 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
2604 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
2605 const char *spacings[] = {
"|20|",
"|09|", NULL };
2606 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
2611 int register_result;
2612 char method_buffer[32] =
"";
2615 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
2616 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
2619 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
2626 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
2627 if (register_result < 0) {
2634 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
2636 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
2638 if (register_result < 0) {
2654 const char *proto_name =
"http";
2659 if (HTPRegisterPatternsForProtocolDetection() < 0)
2662 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
2677 ALPROTO_HTTP1, HTP_REQUEST_PROGRESS_COMPLETE, HTP_RESPONSE_PROGRESS_COMPLETE);
2689 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
2691 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
2697 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
2700 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
2703 IPPROTO_TCP,
ALPROTO_HTTP1, HtpStateGetStateIdByName, HtpStateGetStateNameById);
2707 SCLogInfo(
"Parser disabled for %s protocol. Protocol detection still on.", proto_name);
2723 cfglist_backup = cfglist;
2728 cfglist = cfglist_backup;
2733 static int HTPParserTest01(
void)
2735 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2737 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2740 memset(&ssn, 0,
sizeof(ssn));
2748 f->
proto = IPPROTO_TCP;
2754 for (u = 0; u < httplen1; u++) {
2758 flags = STREAM_TOSERVER|STREAM_START;
2759 else if (u == (httplen1 - 1))
2760 flags = STREAM_TOSERVER|STREAM_EOF;
2762 flags = STREAM_TOSERVER;
2771 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2774 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2777 FAIL_IF(bstr_cmp_c(htp_header_value(h),
"Victor/1.0"));
2778 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2779 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2788 static int HTPParserTest01b(
void)
2790 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2792 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2795 memset(&ssn, 0,
sizeof(ssn));
2803 f->
proto = IPPROTO_TCP;
2808 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
2815 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2818 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2821 FAIL_IF(strcmp(bstr_util_strdup_to_c(htp_header_value(h)),
"Victor/1.0"));
2822 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2823 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2832 static int HTPParserTest01c(
void)
2834 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2836 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2839 memset(&ssn, 0,
sizeof(ssn));
2847 f->
proto = IPPROTO_TCP;
2853 for (u = 0; u < httplen1; u++) {
2857 flags = STREAM_TOSERVER|STREAM_START;
2858 else if (u == (httplen1 - 1))
2859 flags = STREAM_TOSERVER|STREAM_EOF;
2861 flags = STREAM_TOSERVER;
2870 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2873 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2876 FAIL_IF(strcmp(bstr_util_strdup_to_c(htp_header_value(h)),
"Victor/1.0"));
2877 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2878 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2888 static int HTPParserTest01a(
void)
2891 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2893 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2898 memset(&ssn, 0,
sizeof(ssn));
2900 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2903 f->
proto = IPPROTO_TCP;
2909 for (u = 0; u < httplen1; u++) {
2913 flags = STREAM_TOSERVER|STREAM_START;
2914 else if (u == (httplen1 - 1))
2915 flags = STREAM_TOSERVER|STREAM_EOF;
2917 flags = STREAM_TOSERVER;
2926 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2929 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2932 FAIL_IF(strcmp(bstr_util_strdup_to_c(htp_header_value(h)),
"Victor/1.0"));
2933 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2934 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2943 static int HTPParserTest02(
void)
2946 uint8_t httpbuf1[] =
"POST";
2947 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2952 memset(&ssn, 0,
sizeof(ssn));
2954 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2957 f->
proto = IPPROTO_TCP;
2963 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
2969 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
2971 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2975 char *method = bstr_util_strdup_to_c(htp_tx_request_method(tx));
2978 FAIL_IF(strcmp(method,
"POST") != 0);
2989 static int HTPParserTest03(
void)
2992 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
2993 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2998 memset(&ssn, 0,
sizeof(ssn));
3000 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3003 f->
proto = IPPROTO_TCP;
3009 for (u = 0; u < httplen1; u++) {
3012 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3013 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3014 else flags = STREAM_TOSERVER;
3022 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3025 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3027 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3028 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
3038 static int HTPParserTest04(
void)
3042 uint8_t httpbuf1[] =
"World!\r\n";
3043 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3047 memset(&ssn, 0,
sizeof(ssn));
3049 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3052 f->
proto = IPPROTO_TCP;
3058 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3064 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3066 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3068 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3069 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V0_9);
3079 static int HTPParserTest05(
void)
3081 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3082 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3083 uint8_t httpbuf2[] =
"Post D";
3084 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3085 uint8_t httpbuf3[] =
"ata is c0oL!";
3086 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3088 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3089 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3090 uint8_t httpbuf5[] =
"post R";
3091 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3092 uint8_t httpbuf6[] =
"esults are tha bomb!";
3093 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3096 memset(&ssn, 0,
sizeof(ssn));
3104 f->
proto = IPPROTO_TCP;
3134 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3136 FAIL_IF_NOT(htp_tx_request_method_number(tx) == HTP_METHOD_POST);
3137 FAIL_IF_NOT(htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_V1_0);
3139 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3142 FAIL_IF_NOT(htp_tx_response_status_number(tx) == 200);
3152 static int HTPParserTest06(
void)
3154 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3155 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3156 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3157 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3158 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3160 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3161 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3162 "FrontPage/5.0.2.2510\r\n"
3163 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3165 "Content-Type: text/html\r\n\r\n"
3167 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3168 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3169 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3170 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3171 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3172 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3173 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3174 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3175 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3176 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3177 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3178 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3179 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3180 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3181 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3182 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3183 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3184 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3185 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3186 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3187 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3188 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3189 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3190 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3191 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3192 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3193 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3194 "aHA=\r\n0\r\n\r\n";
3195 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3201 memset(&ssn, 0,
sizeof(ssn));
3206 f->
proto = IPPROTO_TCP;
3221 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3224 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
3225 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3227 FAIL_IF(htp_tx_response_status_number(tx) != 200);
3228 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3230 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3241 static int HTPParserTest07(
void)
3244 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3245 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3250 memset(&ssn, 0,
sizeof(ssn));
3252 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3255 f->
proto = IPPROTO_TCP;
3261 for (u = 0; u < httplen1; u++) {
3265 flags = STREAM_TOSERVER|STREAM_START;
3266 else if (u == (httplen1 - 1))
3267 flags = STREAM_TOSERVER|STREAM_EOF;
3269 flags = STREAM_TOSERVER;
3278 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3279 size_t reflen =
sizeof(ref) - 1;
3281 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3283 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3285 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3287 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref, bstr_len(request_uri_normalized)) != 0);
3299 static int HTPParserTest08(
void)
3302 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3303 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3324 memset(&ssn, 0,
sizeof(ssn));
3326 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3329 f->
proto = IPPROTO_TCP;
3334 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3342 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3344 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3346 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3360 static int HTPParserTest09(
void)
3363 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3364 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3374 personality: Apache_2_2\n\
3386 memset(&ssn, 0,
sizeof(ssn));
3388 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3391 f->
proto = IPPROTO_TCP;
3396 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3404 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3406 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3408 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3422 static int HTPParserTest10(
void)
3426 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3427 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3432 memset(&ssn, 0,
sizeof(ssn));
3434 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3437 f->
proto = IPPROTO_TCP;
3443 for (u = 0; u < httplen1; u++) {
3447 flags = STREAM_TOSERVER|STREAM_START;
3448 else if (u == (httplen1 - 1))
3449 flags = STREAM_TOSERVER|STREAM_EOF;
3451 flags = STREAM_TOSERVER;
3460 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3461 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3464 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3468 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3470 FAIL_IF(strcmp(value,
"www.google.com") != 0);
3482 static int HTPParserTest11(
void)
3485 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3486 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3491 memset(&ssn, 0,
sizeof(ssn));
3493 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3496 f->
proto = IPPROTO_TCP;
3502 for (u = 0; u < httplen1; u++) {
3506 flags = STREAM_TOSERVER|STREAM_START;
3507 else if (u == (httplen1 - 1))
3508 flags = STREAM_TOSERVER|STREAM_EOF;
3510 flags = STREAM_TOSERVER;
3519 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3521 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3524 FAIL_IF(bstr_len(request_uri_normalized) != 4);
3525 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3526 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'%');
3527 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'0');
3528 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'0');
3538 static int HTPParserTest12(
void)
3541 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3542 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3547 memset(&ssn, 0,
sizeof(ssn));
3549 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3552 f->
proto = IPPROTO_TCP;
3558 for (u = 0; u < httplen1; u++) {
3562 flags = STREAM_TOSERVER|STREAM_START;
3563 else if (u == (httplen1 - 1))
3564 flags = STREAM_TOSERVER|STREAM_EOF;
3566 flags = STREAM_TOSERVER;
3575 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3577 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3580 FAIL_IF(bstr_len(request_uri_normalized) != 7);
3581 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3582 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'?');
3583 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'a');
3584 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'=');
3585 FAIL_IF(bstr_ptr(request_uri_normalized)[4] !=
'%');
3586 FAIL_IF(bstr_ptr(request_uri_normalized)[5] !=
'0');
3587 FAIL_IF(bstr_ptr(request_uri_normalized)[6] !=
'0');
3597 static int HTPParserTest13(
void)
3600 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3601 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3606 memset(&ssn, 0,
sizeof(ssn));
3608 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3611 f->
proto = IPPROTO_TCP;
3617 for (u = 0; u < httplen1; u++) {
3621 flags = STREAM_TOSERVER|STREAM_START;
3622 else if (u == (httplen1 - 1))
3623 flags = STREAM_TOSERVER|STREAM_EOF;
3625 flags = STREAM_TOSERVER;
3633 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3634 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3637 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3641 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3643 FAIL_IF(strcmp(value,
"www.google.com\rName: Value") != 0);
3655 static int HTPParserConfigTest01(
void)
3668 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3669 personality: Tomcat_6_0\n\
3674 - 192.168.10.0/24\n\
3675 personality: IIS_7_0\n\
3684 outputs =
SCConfGetNode(
"libhtp.default-config.personality");
3695 FAIL_IF(strcmp(node->
name,
"apache-tomcat") != 0);
3702 FAIL_IF(strcmp(node2->
val,
"Tomcat_6_0") != 0);
3712 FAIL_IF(strcmp(n->
val,
"192.168.1.0/24") != 0);
3752 FAIL_IF(strcmp(n->
val,
"192.168.0.0/24") != 0);
3756 FAIL_IF(strcmp(n->
val,
"192.168.10.0/24") != 0);
3771 static int HTPParserConfigTest02(
void)
3784 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3785 personality: Tomcat_6_0\n\
3790 - 192.168.10.0/24\n\
3791 personality: IIS_7_0\n\
3803 htp_cfg_t *htp = cfglist.
cfg;
3806 void *user_data = NULL;
3808 addr =
"192.168.10.42";
3809 FAIL_IF(inet_pton(AF_INET, addr, buf) != 1);
3813 htp = htp_cfg_rec->
cfg;
3819 FAIL_IF(inet_pton(AF_INET6, addr, buf) != 1);
3822 htp_cfg_rec = user_data;
3823 htp = htp_cfg_rec->
cfg;
3836 static int HTPParserConfigTest03(
void)
3839 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3841 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3857 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3858 personality: Tomcat_6_0\n\
3863 - 192.168.10.0/24\n\
3864 personality: IIS_7_0\n\
3875 const char *addr =
"192.168.10.42";
3877 memset(&ssn, 0,
sizeof(ssn));
3882 f->
proto = IPPROTO_TCP;
3885 htp_cfg_t *htp = cfglist.
cfg;
3888 void *user_data = NULL;
3893 htp = htp_cfg_rec->
cfg;
3900 for (u = 0; u < httplen1; u++) {
3903 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3904 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3905 else flags = STREAM_TOSERVER;
3914 FAIL_IF(HTPStateGetTxCnt(htp_state) != 2);
3916 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3918 tx = HTPStateGetTx(htp_state, 1);
3938 static int HTPParserDecodingTest01(
void)
3940 uint8_t httpbuf1[] =
3941 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3942 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3943 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
3944 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3955 personality: Apache_2\n\
3963 const char *addr =
"4.3.2.1";
3964 memset(&ssn, 0,
sizeof(ssn));
3969 f->
proto = IPPROTO_TCP;
3974 for (uint32_t u = 0; u < httplen1; u++) {
3976 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3977 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3978 else flags = STREAM_TOSERVER;
3987 uint8_t ref1[] =
"/abc%2fdef";
3988 size_t reflen =
sizeof(ref1) - 1;
3990 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3994 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3997 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3998 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4000 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4001 reflen =
sizeof(ref2) - 1;
4003 tx = HTPStateGetTx(htp_state, 1);
4007 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4010 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4011 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4013 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4014 reflen =
sizeof(ref3) - 1;
4015 tx = HTPStateGetTx(htp_state, 2);
4019 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4022 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4023 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4036 static int HTPParserDecodingTest01a(
void)
4038 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4039 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4040 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4041 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4052 personality: Apache_2\n\
4060 const char *addr =
"4.3.2.1";
4061 memset(&ssn, 0,
sizeof(ssn));
4066 f->
proto = IPPROTO_TCP;
4072 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4078 uint8_t ref1[] =
"/abc%2fdef";
4079 size_t reflen =
sizeof(ref1) - 1;
4081 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4085 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4088 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4089 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4091 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4092 reflen =
sizeof(ref2) - 1;
4094 tx = HTPStateGetTx(htp_state, 1);
4097 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4100 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4102 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4104 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4105 reflen =
sizeof(ref3) - 1;
4106 tx = HTPStateGetTx(htp_state, 2);
4109 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4112 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4114 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4133 static int HTPParserDecodingTest02(
void)
4136 uint8_t httpbuf1[] =
4137 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4138 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4139 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4140 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4152 double-decode-path: no\n\
4153 double-decode-query: no\n\
4161 const char *addr =
"4.3.2.1";
4162 memset(&ssn, 0,
sizeof(ssn));
4167 f->
proto = IPPROTO_TCP;
4173 for (u = 0; u < httplen1; u++) {
4176 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4177 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4178 else flags = STREAM_TOSERVER;
4187 uint8_t ref1[] =
"/abc/def";
4188 size_t reflen =
sizeof(ref1) - 1;
4190 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4192 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4194 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4195 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4197 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4198 reflen =
sizeof(ref2) - 1;
4200 tx = HTPStateGetTx(htp_state, 1);
4202 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4204 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4206 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4208 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4209 reflen =
sizeof(ref3) - 1;
4210 tx = HTPStateGetTx(htp_state, 2);
4212 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4214 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4216 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4234 static int HTPParserDecodingTest03(
void)
4237 uint8_t httpbuf1[] =
4238 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4239 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4240 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4252 double-decode-path: yes\n\
4253 double-decode-query: yes\n\
4261 const char *addr =
"4.3.2.1";
4262 memset(&ssn, 0,
sizeof(ssn));
4267 f->
proto = IPPROTO_TCP;
4273 for (u = 0; u < httplen1; u++) {
4276 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4277 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4278 else flags = STREAM_TOSERVER;
4287 uint8_t ref1[] =
"/abc/def";
4288 size_t reflen =
sizeof(ref1) - 1;
4290 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4292 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4294 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4296 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4298 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4299 reflen =
sizeof(ref2) - 1;
4301 tx = HTPStateGetTx(htp_state, 1);
4303 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4305 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4307 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4322 static int HTPParserDecodingTest04(
void)
4325 uint8_t httpbuf1[] =
4326 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4327 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4339 double-decode-path: yes\n\
4340 double-decode-query: yes\n\
4348 const char *addr =
"4.3.2.1";
4349 memset(&ssn, 0,
sizeof(ssn));
4354 f->
proto = IPPROTO_TCP;
4360 for (u = 0; u < httplen1; u++) {
4363 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4364 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4365 else flags = STREAM_TOSERVER;
4374 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
4375 size_t reflen =
sizeof(ref1) - 1;
4377 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4379 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4381 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4383 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4398 static int HTPParserDecodingTest05(
void)
4401 uint8_t httpbuf1[] =
4402 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4403 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4415 double-decode-path: yes\n\
4416 double-decode-query: yes\n\
4424 const char *addr =
"4.3.2.1";
4425 memset(&ssn, 0,
sizeof(ssn));
4430 f->
proto = IPPROTO_TCP;
4436 for (u = 0; u < httplen1; u++) {
4439 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4440 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4441 else flags = STREAM_TOSERVER;
4450 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
4451 size_t reflen =
sizeof(ref1) - 1;
4453 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4455 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4457 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4459 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4474 static int HTPParserDecodingTest06(
void)
4477 uint8_t httpbuf1[] =
4478 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4479 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4491 double-decode-path: yes\n\
4492 double-decode-query: yes\n\
4500 const char *addr =
"4.3.2.1";
4501 memset(&ssn, 0,
sizeof(ssn));
4506 f->
proto = IPPROTO_TCP;
4512 for (u = 0; u < httplen1; u++) {
4515 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4516 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4517 else flags = STREAM_TOSERVER;
4526 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
4527 size_t reflen =
sizeof(ref1) - 1;
4529 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4531 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4533 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4535 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4550 static int HTPParserDecodingTest07(
void)
4553 uint8_t httpbuf1[] =
4554 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4555 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4567 double-decode-path: yes\n\
4568 double-decode-query: yes\n\
4569 query-plusspace-decode: yes\n\
4577 const char *addr =
"4.3.2.1";
4578 memset(&ssn, 0,
sizeof(ssn));
4583 f->
proto = IPPROTO_TCP;
4589 for (u = 0; u < httplen1; u++) {
4592 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4593 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4594 else flags = STREAM_TOSERVER;
4603 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
4604 size_t reflen =
sizeof(ref1) - 1;
4606 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4608 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4610 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4612 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4627 static int HTPParserDecodingTest08(
void)
4630 uint8_t httpbuf1[] =
4631 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4632 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4651 const char *addr =
"4.3.2.1";
4652 memset(&ssn, 0,
sizeof(ssn));
4657 f->
proto = IPPROTO_TCP;
4663 for (u = 0; u < httplen1; u++) {
4666 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4667 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4668 else flags = STREAM_TOSERVER;
4677 uint8_t ref1[] =
"/blah/";
4678 size_t reflen =
sizeof(ref1) - 1;
4680 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4682 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4684 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4686 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4701 static int HTPParserDecodingTest09(
void)
4704 uint8_t httpbuf1[] =
4705 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4706 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4718 uri-include-all: true\n\
4726 const char *addr =
"4.3.2.1";
4727 memset(&ssn, 0,
sizeof(ssn));
4732 f->
proto = IPPROTO_TCP;
4738 for (u = 0; u < httplen1; u++) {
4741 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4742 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4743 else flags = STREAM_TOSERVER;
4752 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
4753 size_t reflen =
sizeof(ref1) - 1;
4755 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4757 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4759 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4761 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4775 static int HTPBodyReassemblyTest01(
void)
4778 memset(&htud, 0x00,
sizeof(htud));
4780 memset(&hstate, 0x00,
sizeof(hstate));
4782 memset(&flow, 0x00,
sizeof(flow));
4784 htp_cfg_t *cfg = htp_config_create();
4786 htp_connp_t *connp = htp_connp_create(cfg);
4788 const htp_tx_t *tx = htp_connp_get_request_tx(connp);
4794 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
4795 uint8_t chunk2[] =
"POST /uri HTTP/1.1\r\nHost: hostname.com\r\nKeep-Alive: 115\r\nAccept-Charset: utf-8\r\nUser-Agent: Mozilla/5.0 (X11; Linux i686; rv:9.0.1) Gecko/20100101 Firefox/9.0.1\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nConnection: keep-alive\r\nContent-length: 68102\r\nReferer: http://otherhost.com\r\nAccept-Encoding: gzip\r\nContent-Type: multipart/form-data; boundary=e5a320f21416a02493a0a6f561b1c494\r\nCookie: blah\r\nAccept-Language: us\r\n\r\n--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
4802 const uint8_t *chunks_buffer = NULL;
4803 uint32_t chunks_buffer_len = 0;
4805 HtpRequestBodyReassemble(&htud, &chunks_buffer, &chunks_buffer_len);
4808 printf(
"REASSCHUNK START: \n");
4810 printf(
"REASSCHUNK END: \n");
4813 htud.
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
4814 strlen(
"multipart/form-data; boundary=toto"));
4817 HtpRequestBodyHandleMultipart(&hstate, &htud, &tx, chunks_buffer, chunks_buffer_len,
false);
4827 static int HTPSegvTest01(
void)
4830 uint8_t httpbuf1[] =
"POST /uri HTTP/1.1\r\nHost: hostname.com\r\nKeep-Alive: 115\r\nAccept-Charset: utf-8\r\nUser-Agent: Mozilla/5.0 (X11; Linux i686; rv:9.0.1) Gecko/20100101 Firefox/9.0.1\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nConnection: keep-alive\r\nContent-length: 68102\r\nReferer: http://otherhost.com\r\nAccept-Encoding: gzip\r\nContent-Type: multipart/form-data; boundary=e5a320f21416a02493a0a6f561b1c494\r\nCookie: blah\r\nAccept-Language: us\r\n\r\n--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
4831 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4839 double-decode-path: no\n\
4840 double-decode-query: no\n\
4841 request-body-limit: 0\n\
4842 response-body-limit: 0\n\
4855 memset(&ssn, 0,
sizeof(ssn));
4857 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4860 f->
proto = IPPROTO_TCP;
4865 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
4869 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
4890 static int HTPParserTest14(
void)
4901 double-decode-path: no\n\
4902 double-decode-query: no\n\
4903 request-body-limit: 0\n\
4904 response-body-limit: 0\n\
4909 memset(&ssn, 0,
sizeof(ssn));
4919 memset(httpbuf, 0x00,
len);
4922 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4923 "Host: myhost.lan\r\n"
4924 "Connection: keep-alive\r\n"
4926 "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36\r\n"
4927 "Referer: http://blah.lan/\r\n"
4928 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
4930 size_t o = strlen(httpbuf);
4931 for ( ; o <
len - 4; o++) {
4934 httpbuf[
len - 4] =
'\r';
4935 httpbuf[
len - 3] =
'\n';
4936 httpbuf[
len - 2] =
'\r';
4937 httpbuf[
len - 1] =
'\n';
4943 f->
proto = IPPROTO_TCP;
4948 for (u = 0; u <
len; u++) {
4951 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4952 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4953 else flags = STREAM_TOSERVER;
4961 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4963 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
4964 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
4971 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG);
4986 static int HTPParserTest15(
void)
4989 char *httpbuf = NULL;
5000 double-decode-path: no\n\
5001 double-decode-query: no\n\
5002 request-body-limit: 0\n\
5003 response-body-limit: 0\n\
5004 meta-field-limit: 20000\n\
5008 memset(&ssn, 0,
sizeof(ssn));
5019 memset(httpbuf, 0x00,
len);
5022 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5023 "Host: myhost.lan\r\n"
5024 "Connection: keep-alive\r\n"
5026 "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36\r\n"
5027 "Referer: http://blah.lan/\r\n"
5028 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5030 size_t o = strlen(httpbuf);
5031 for ( ; o <
len - 4; o++) {
5034 httpbuf[
len - 4] =
'\r';
5035 httpbuf[
len - 3] =
'\n';
5036 httpbuf[
len - 2] =
'\r';
5037 httpbuf[
len - 1] =
'\n';
5039 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5042 f->
proto = IPPROTO_TCP;
5048 for (u = 0; u <
len; u++) {
5051 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5052 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5053 else flags = STREAM_TOSERVER;
5062 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5064 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5065 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5084 static int HTPParserTest16(
void)
5091 memset(&ssn, 0,
sizeof(ssn));
5093 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5094 "Host: myhost.lan\r\n"
5095 "Connection: keep-alive\r\n"
5097 "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36\r\n"
5098 "Referer: http://blah.lan/\r\n"
5099 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5100 "Cookie: blah\r\n\r\n";
5101 size_t len =
sizeof(httpbuf) - 1;
5103 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5106 f->
proto = IPPROTO_TCP;
5111 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5119 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5121 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5122 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5124 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5131 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT);
5132 FAIL_IF(decoder_events->
events[1] != HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT);
5143 static int HTPParserTest20(
void)
5146 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5147 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5148 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5149 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5150 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
5151 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5152 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5153 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5159 memset(&ssn, 0,
sizeof(ssn));
5161 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5164 f->
proto = IPPROTO_TCP;
5183 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5185 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5188 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5189 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5191 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5192 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5202 static int HTPParserTest21(
void)
5205 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5206 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5207 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5208 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5209 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
5210 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5211 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5212 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5218 memset(&ssn, 0,
sizeof(ssn));
5220 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5223 f->
proto = IPPROTO_TCP;
5242 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5244 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5247 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5248 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5250 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5251 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5261 static int HTPParserTest22(
void)
5264 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5265 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5266 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5267 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5268 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
5269 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5270 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5276 memset(&ssn, 0,
sizeof(ssn));
5278 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5281 f->
proto = IPPROTO_TCP;
5296 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5298 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5301 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5302 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5304 FAIL_IF(htp_tx_response_status_number(tx) != -0);
5305 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5315 static int HTPParserTest23(
void)
5318 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5319 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5320 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5321 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5322 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
5323 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5324 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5330 memset(&ssn, 0,
sizeof(ssn));
5332 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5335 f->
proto = IPPROTO_TCP;
5350 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5352 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5355 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5356 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5358 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5359 FAIL_IF(htp_tx_response_protocol_number(tx) != -2);
5369 static int HTPParserTest24(
void)
5372 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5373 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5374 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5375 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5376 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
5377 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5378 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5384 memset(&ssn, 0,
sizeof(ssn));
5386 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5389 f->
proto = IPPROTO_TCP;
5404 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5406 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5409 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5410 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5412 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5413 FAIL_IF(htp_tx_response_protocol_number(tx) != HTP_PROTOCOL_V1_0);
5422 static int HTPParserTest25(
void)
5429 memset(&ssn, 0,
sizeof(ssn));
5434 f->
proto = IPPROTO_TCP;
5438 const char *
str =
"GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
5440 (uint8_t *)
str, strlen(
str));
5464 str =
"HTTP 1.1 200 OK\r\nServer: Suricata/1.0\r\nContent-Length: 8\r\n\r\nSuricata";
5466 (uint8_t *)
str, strlen(
str));
5500 (uint8_t *)
str, strlen(
str));
5511 (uint8_t *)
str, strlen(
str));
5531 static int HTPParserTest26(
void)
5540 request-body-limit: 1\n\
5541 response-body-limit: 1\n\
5555 uint8_t httpbuf1[] =
"GET /alice.txt HTTP/1.1\r\n\r\n";
5556 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5557 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\n"
5558 "Content-Type: text/plain\r\n"
5559 "Content-Length: 228\r\n\r\n"
5560 "Alice was beginning to get very tired of sitting by her sister on the bank."
5561 "Alice was beginning to get very tired of sitting by her sister on the bank.";
5562 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5563 uint8_t httpbuf3[] =
"Alice was beginning to get very tired of sitting by her sister on the bank.\r\n\r\n";
5564 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5570 memset(&th_v, 0,
sizeof(th_v));
5571 memset(&f, 0,
sizeof(f));
5572 memset(&ssn, 0,
sizeof(ssn));
5579 f.
proto = IPPROTO_TCP;
5600 "(filestore; sid:1; rev:1;)");
5645 AppLayerGetFileState files = HTPGetTxFiles(tx_ptr, STREAM_TOCLIENT);
5667 static int HTPParserTest27(
void)
5670 memset(&cfg, 0,
sizeof(cfg));
5674 uint32_t
len = 1000;
5699 static void HTPParserRegisterTests(
void)
5721 UtRegisterTest(
"HTPParserDecodingTest01", HTPParserDecodingTest01);
5722 UtRegisterTest(
"HTPParserDecodingTest01a", HTPParserDecodingTest01a);
5723 UtRegisterTest(
"HTPParserDecodingTest02", HTPParserDecodingTest02);
5724 UtRegisterTest(
"HTPParserDecodingTest03", HTPParserDecodingTest03);
5725 UtRegisterTest(
"HTPParserDecodingTest04", HTPParserDecodingTest04);
5726 UtRegisterTest(
"HTPParserDecodingTest05", HTPParserDecodingTest05);
5727 UtRegisterTest(
"HTPParserDecodingTest06", HTPParserDecodingTest06);
5728 UtRegisterTest(
"HTPParserDecodingTest07", HTPParserDecodingTest07);
5729 UtRegisterTest(
"HTPParserDecodingTest08", HTPParserDecodingTest08);
5730 UtRegisterTest(
"HTPParserDecodingTest09", HTPParserDecodingTest09);
5732 UtRegisterTest(
"HTPBodyReassemblyTest01", HTPBodyReassemblyTest01);