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);
452 static void *HTPStateAlloc(
void *orig_state,
AppProto proto_orig)
466 htp_state_memuse +=
sizeof(
HtpState);
467 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
474 static void HtpTxUserDataFree(
void *txud)
486 SCAppLayerTxDataCleanup(&htud->
tx_data);
510 if (s->
connp != NULL) {
512 htp_connp_destroy_all(s->
connp);
520 htp_state_memuse -=
sizeof(
HtpState);
521 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
532 static void HTPStateTransactionFree(
void *state, uint64_t
id)
539 htp_tx_destroy(s->
connp,
id);
584 static void AppLayerHtpSetStreamDepthFlag(
void *tx,
const uint8_t
flags)
588 if (
flags & STREAM_TOCLIENT) {
597 SCLogDebug(
"cfg->body_limit %u stream_depth %u body->content_len_so_far %" PRIu64,
614 static uint32_t AppLayerHtpComputeChunkLength(uint64_t content_len_so_far, uint32_t body_limit,
615 uint32_t stream_depth, uint8_t
flags, uint32_t data_len)
617 uint32_t chunk_len = 0;
619 (content_len_so_far < (uint64_t)body_limit) &&
620 (content_len_so_far + (uint64_t)data_len) > body_limit)
622 chunk_len = (uint32_t)(body_limit - content_len_so_far);
624 (content_len_so_far < (uint64_t)stream_depth) &&
625 (content_len_so_far + (uint64_t)data_len) > stream_depth)
627 chunk_len = (uint32_t)(stream_depth - content_len_so_far);
630 return (chunk_len == 0 ? data_len : chunk_len);
641 static void HTPHandleError(
HtpState *s,
const uint8_t dir)
648 htp_log_t *log = htp_conn_next_log(s->
conn);
649 while (log != NULL) {
650 char *msg = htp_log_message(log);
653 log = htp_conn_next_log(s->
conn);
659 htp_log_code_t
id = htp_log_code(log);
660 if (
id != HTP_LOG_CODE_UNKNOWN &&
id != HTP_LOG_CODE_ERROR) {
661 HTPSetEvent(s, NULL, dir, (uint8_t)
id);
663 htp_free_cstring(msg);
673 log = htp_conn_next_log(s->
conn);
678 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s,
const htp_tx_t *tx)
681 BUG_ON(s == NULL || tx == NULL);
683 if (htp_tx_flags(tx) & (HTP_FLAGS_REQUEST_INVALID_T_E | HTP_FLAGS_REQUEST_INVALID_C_L |
684 HTP_FLAGS_HOST_MISSING | HTP_FLAGS_HOST_AMBIGUOUS |
685 HTP_FLAGS_HOSTU_INVALID | HTP_FLAGS_HOSTH_INVALID)) {
688 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_T_E)
689 HTPSetEvent(s, htud, STREAM_TOSERVER,
690 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST);
691 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_C_L)
693 s, htud, STREAM_TOSERVER, HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST);
694 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_MISSING)
695 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_MISSING_HOST_HEADER);
696 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_AMBIGUOUS)
697 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HOST_HEADER_AMBIGUOUS);
698 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTU_INVALID)
699 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_URI_HOST_INVALID);
700 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTH_INVALID)
701 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HEADER_HOST_INVALID);
703 if (htp_tx_request_auth_type(tx) == HTP_AUTH_TYPE_UNRECOGNIZED) {
705 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_AUTH_UNRECOGNIZED);
707 if (htp_tx_is_protocol_0_9(tx) && htp_tx_request_method_number(tx) == HTP_METHOD_UNKNOWN &&
708 (htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_INVALID ||
709 htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_UNKNOWN)) {
711 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_REQUEST_LINE_INVALID);
721 htp_cfg_t *htp = cfglist.
cfg;
722 void *user_data = NULL;
738 if (user_data != NULL) {
739 htp_cfg_rec = user_data;
740 htp = htp_cfg_rec->
cfg;
743 SCLogDebug(
"Using default HTP config: %p", htp);
747 #ifdef DEBUG_VALIDATION
754 hstate->
connp = htp_connp_create(htp);
755 if (hstate->
connp == NULL) {
759 hstate->
conn = (htp_conn_t *)htp_connp_connection(hstate->
connp);
761 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
762 hstate->
cfg = htp_cfg_rec;
767 htp_connp_open(hstate->
connp, NULL, f->
sp, NULL, f->
dp, &
tv);
789 StreamSlice stream_slice,
void *local_data)
799 if (NULL == hstate->
conn) {
800 if (Setup(f, hstate) != 0) {
805 hstate->
slice = &stream_slice;
807 const uint8_t *input = StreamSliceGetData(&stream_slice);
808 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
813 const int r = htp_connp_request_data(hstate->
connp, &
ts, input, input_len);
815 case HTP_STREAM_STATE_ERROR:
821 HTPHandleError(hstate, STREAM_TOSERVER);
828 htp_connp_request_close(hstate->
connp, &
ts);
830 SCLogDebug(
"stream eof encountered, closing htp handle for ts");
834 hstate->
slice = NULL;
856 StreamSlice stream_slice,
void *local_data)
862 const uint8_t *input = StreamSliceGetData(&stream_slice);
863 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
869 if (NULL == hstate->
conn) {
870 if (Setup(f, hstate) != 0) {
875 hstate->
slice = &stream_slice;
878 const htp_tx_t *tx = NULL;
879 uint32_t consumed = 0;
881 const int r = htp_connp_response_data(hstate->
connp, &
ts, input, input_len);
883 case HTP_STREAM_STATE_ERROR:
886 case HTP_STREAM_STATE_TUNNEL:
887 tx = htp_connp_get_response_tx(hstate->
connp);
888 if (tx != NULL && htp_tx_response_status_number(tx) == 101) {
889 const htp_header_t *h = htp_tx_response_header(tx,
"Upgrade");
894 if (htp_tx_request_port_number(tx) != -1) {
895 dp = (uint16_t)htp_tx_request_port_number(tx);
897 consumed = (uint32_t)htp_connp_response_data_consumed(hstate->
connp);
898 if (bstr_cmp_c(htp_header_value(h),
"h2c") == 0) {
903 hstate->
slice = NULL;
905 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
910 if (consumed > 0 && consumed < input_len) {
914 }
else if (bstr_cmp_c_nocase(htp_header_value(h),
"WebSocket")) {
919 hstate->
slice = NULL;
921 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
926 if (consumed > 0 && consumed < input_len) {
936 HTPHandleError(hstate, STREAM_TOCLIENT);
943 htp_connp_close(hstate->
connp, &
ts);
948 hstate->
slice = NULL;
959 static int HTTPParseContentDispositionHeader(
const uint8_t *
name,
size_t name_len,
960 const uint8_t *data,
size_t len, uint8_t
const **retptr,
size_t *retlen)
963 printf(
"DATA START: \n");
965 printf(
"DATA END: \n");
970 for (x = 0; x <
len; x++) {
971 if (!(isspace(data[x])))
978 const uint8_t *line = data + x;
979 size_t line_len =
len-x;
982 printf(
"LINE START: \n");
984 printf(
"LINE END: \n");
986 for (x = 0 ; x < line_len; x++) {
988 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
992 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
993 const uint8_t *token = line +
offset;
994 size_t token_len = x -
offset;
996 if ((x + 1) == line_len) {
1007 printf(
"TOKEN START: \n");
1009 printf(
"TOKEN END: \n");
1011 if (token_len > name_len) {
1012 if (
name == NULL || SCMemcmpLowercase(
name, token, name_len) == 0) {
1013 const uint8_t *value = token + name_len;
1014 size_t value_len = token_len - name_len;
1016 if (value[0] ==
'\"') {
1020 if (value[value_len-1] ==
'\"') {
1024 printf(
"VALUE START: \n");
1026 printf(
"VALUE END: \n");
1029 *retlen = value_len;
1053 static int HtpRequestBodySetupMultipart(
const htp_tx_t *tx,
HtpTxUserData *htud)
1055 const htp_header_t *h = htp_tx_request_header(tx,
"Content-Type");
1056 if (h != NULL && htp_header_value_len(h) > 0) {
1058 SCMimeStateInit(htp_header_value_ptr(h), (uint32_t)htp_header_value_len(h));
1075 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1078 chunks_buffer, chunks_buffer_len,
1082 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1085 if (tx && tx->
tx_data.de_state) {
1086 if (dir == STREAM_TOSERVER) {
1087 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1089 }
else if (dir == STREAM_TOCLIENT) {
1090 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1097 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len,
bool eof)
1100 printf(
"CHUNK START: \n");
1102 printf(
"CHUNK END: \n");
1108 STREAM_TOSERVER) >= HTP_REQUEST_PROGRESS_COMPLETE);
1110 const uint8_t *cur_buf = chunks_buffer;
1111 uint32_t cur_buf_len = chunks_buffer_len;
1127 const uint8_t *filename = NULL;
1128 uint16_t filename_len = 0;
1131 while (cur_buf_len > 0) {
1132 MimeParserResult r =
1133 SCMimeParse(htud->
mime_state, cur_buf, cur_buf_len, &consumed, &warnings);
1137 if (warnings & MIME_EVENT_FLAG_INVALID_HEADER) {
1141 if (warnings & MIME_EVENT_FLAG_NO_FILEDATA) {
1152 SCMimeStateGetFilename(htud->
mime_state, &filename, &filename_len);
1153 if (filename_len > 0) {
1157 hstate, htud, filename, filename_len, NULL, 0, STREAM_TOSERVER);
1160 }
else if (result == -2) {
1163 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1171 }
else if (result == -2) {
1179 uint32_t lastsize = consumed;
1180 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\n') {
1182 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\r') {
1186 HTPFileClose(htud, cur_buf, lastsize, 0, STREAM_TOSERVER);
1191 cur_buf += consumed;
1192 cur_buf_len -= consumed;
1204 const uint8_t *data, uint32_t data_len)
1211 uint8_t *filename = NULL;
1212 size_t filename_len = 0;
1215 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1216 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1217 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1220 if (filename != NULL) {
1226 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1230 }
else if (result == -2) {
1233 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1247 }
else if (result == -2) {
1260 const uint8_t *data, uint32_t data_len)
1273 const uint8_t *filename = NULL;
1274 size_t filename_len = 0;
1277 const htp_header_t *h = htp_tx_response_header(tx,
"Content-Disposition");
1278 if (h != NULL && htp_header_value_len(h) > 0) {
1280 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1281 htp_header_value_ptr(h), htp_header_value_len(h), &filename, &filename_len);
1285 if (filename == NULL) {
1287 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1288 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1289 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1293 if (filename != NULL) {
1295 const htp_header_t *h_content_range = htp_tx_response_header(tx,
"content-range");
1301 if (h_content_range != NULL) {
1303 data_len, tx, htp_header_value(h_content_range), htud);
1305 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1311 }
else if (result == -2) {
1314 FlagDetectStateNewFile(htud, STREAM_TOCLIENT);
1327 }
else if (result == -2) {
1345 static int HTPCallbackRequestBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1349 const htp_tx_t *tx = htp_tx_data_tx(d);
1354 if (htp_tx_data_is_empty(d))
1358 printf(
"HTPBODY START: \n");
1359 PrintRawDataFp(stdout, (uint8_t *)htp_tx_data_data(d), htp_tx_data_len(d));
1360 printf(
"HTPBODY END: \n");
1363 HtpState *hstate = htp_connp_user_data(connp);
1364 if (hstate == NULL) {
1368 SCLogDebug(
"New request body data available at %p -> %p -> %p, bodylen "
1370 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1373 if (tx_ud == NULL) {
1376 tx_ud->
tx_data.updated_ts =
true;
1382 if (htp_tx_request_method_number(tx) == HTP_METHOD_POST) {
1384 int r = HtpRequestBodySetupMultipart(tx, tx_ud);
1387 }
else if (r == 0) {
1391 }
else if (htp_tx_request_method_number(tx) == HTP_METHOD_PUT) {
1407 (uint32_t)htp_tx_data_len(d));
1408 BUG_ON(
len > (uint32_t)htp_tx_data_len(d));
1412 const uint8_t *chunks_buffer = NULL;
1413 uint32_t chunks_buffer_len = 0;
1421 HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len);
1422 if (chunks_buffer == NULL) {
1426 printf(
"REASSCHUNK START: \n");
1428 printf(
"REASSCHUNK END: \n");
1431 HtpRequestBodyHandleMultipart(hstate, tx_ud, htp_tx_data_tx(d), chunks_buffer,
1432 chunks_buffer_len, (htp_tx_data_data(d) == NULL && htp_tx_data_len(d) == 0));
1436 HtpRequestBodyHandlePOSTorPUT(
1437 hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1442 SCLogDebug(
"closing file that was being stored");
1449 if (hstate->
conn != NULL) {
1450 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1451 ", last %" PRIu64
")",
1453 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1462 if ((uint64_t)htp_conn_request_data_counter(hstate->
conn) >
1464 (uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1466 (uint64_t)UINT_MAX) {
1467 uint32_t data_size =
1468 (uint32_t)((uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1489 static int HTPCallbackResponseBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1493 const htp_tx_t *tx = htp_tx_data_tx(d);
1498 if (htp_tx_data_is_empty(d))
1501 HtpState *hstate = htp_connp_user_data(connp);
1502 if (hstate == NULL) {
1506 SCLogDebug(
"New response body data available at %p -> %p -> %p, bodylen "
1508 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1511 tx_ud->
tx_data.updated_tc =
true;
1528 (uint32_t)htp_tx_data_len(d));
1529 BUG_ON(
len > (uint32_t)htp_tx_data_len(d));
1533 HtpResponseBodyHandle(hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1536 SCLogDebug(
"closing file that was being stored");
1542 if (hstate->
conn != NULL) {
1543 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1544 ", last %" PRIu64
")",
1546 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1554 if ((uint64_t)htp_conn_response_data_counter(hstate->
conn) >
1556 (uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1558 (uint64_t)UINT_MAX) {
1559 uint32_t data_size =
1560 (uint32_t)((uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1584 SCLogDebug(
"http_state_memcnt %"PRIu64
", http_state_memuse %"PRIu64
"",
1585 htp_state_memcnt, htp_state_memuse);
1603 htp_config_destroy(cfglist.
cfg);
1604 while (nextrec != NULL) {
1606 nextrec = nextrec->
next;
1608 htp_config_destroy(htprec->
cfg);
1616 static int HTPCallbackRequestHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1619 htud->
tx_data.updated_ts =
true;
1621 return HTP_STATUS_OK;
1624 static int HTPCallbackResponseHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1627 htud->
tx_data.updated_tc =
true;
1629 return HTP_STATUS_OK;
1632 static void *HTPCallbackTxCreate(
bool request)
1640 tx_ud->
tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT;
1642 tx_ud->
tx_data.file_tx = STREAM_TOCLIENT;
1651 static int HTPCallbackRequestStart(
const htp_connp_t *connp, htp_tx_t *tx)
1653 HtpState *hstate = htp_connp_user_data(connp);
1654 if (hstate == NULL) {
1658 uint64_t consumed = hstate->
slice->offset + htp_connp_request_data_consumed(hstate->
connp);
1659 SCLogDebug(
"HTTP request start: data offset %" PRIu64
", in_data_counter %" PRIu64, consumed,
1660 (uint64_t)htp_conn_request_data_counter(hstate->
conn));
1676 tx_ud->
tx_data.updated_ts =
true;
1684 static int HTPCallbackResponseStart(
const htp_connp_t *connp, htp_tx_t *tx)
1686 HtpState *hstate = htp_connp_user_data(connp);
1687 if (hstate == NULL) {
1691 uint64_t consumed = hstate->
slice->offset + htp_connp_response_data_consumed(hstate->
connp);
1692 SCLogDebug(
"HTTP response start: data offset %" PRIu64
", out_data_counter %" PRIu64, consumed,
1693 (uint64_t)htp_conn_response_data_counter(hstate->
conn));
1708 tx_ud->
tx_data.updated_tc =
true;
1718 static int HTPCallbackRequestComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1726 HtpState *hstate = htp_connp_user_data(connp);
1727 if (hstate == NULL) {
1731 const uint64_t abs_right_edge =
1732 hstate->
slice->offset + htp_connp_request_data_consumed(hstate->
connp);
1740 SCLogDebug(
"HTTP request complete: data offset %" PRIu64
", request_size %" PRIu64,
1742 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1744 frame->
len = (int64_t)request_size;
1750 SCLogDebug(
"transaction_cnt %"PRIu64
", list_size %"PRIu64,
1755 HTPErrorCheckTxRequestFlags(hstate, tx);
1758 htud->
tx_data.updated_ts =
true;
1760 SCLogDebug(
"closing file that was being stored");
1763 if (abs_right_edge < (uint64_t)UINT32_MAX) {
1765 hstate->
f->
protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
1782 static int HTPCallbackResponseComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1786 HtpState *hstate = htp_connp_user_data(connp);
1787 if (hstate == NULL) {
1794 const uint64_t abs_right_edge =
1795 hstate->
slice->offset + htp_connp_response_data_consumed(hstate->
connp);
1802 SCLogDebug(
"HTTP response complete: data offset %" PRIu64
", response_size %" PRIu64,
1804 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1806 frame->
len = (int64_t)response_size;
1812 htud->
tx_data.updated_tc =
true;
1814 SCLogDebug(
"closing file that was being stored");
1824 if (htp_tx_request_method_number(tx) == HTP_METHOD_CONNECT) {
1827 if ((htp_tx_response_status_number(tx) >= 200) &&
1828 (htp_tx_response_status_number(tx) < 300) && (hstate->
transaction_cnt == 1)) {
1830 if (htp_tx_request_port_number(tx) != -1) {
1831 dp = (uint16_t)htp_tx_request_port_number(tx);
1845 static int HTPCallbackRequestLine(
const htp_connp_t *connp, htp_tx_t *tx)
1847 HtpState *hstate = htp_connp_user_data(connp);
1849 if (htp_tx_flags(tx)) {
1850 HTPErrorCheckTxRequestFlags(hstate, tx);
1852 return HTP_STATUS_OK;
1855 static int HTPCallbackRequestHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1858 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1859 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1860 return HTP_STATUS_OK;
1866 return HTP_STATUS_OK;
1869 tx_ud->
tx_data.updated_ts =
true;
1872 htp_tx_data_len(tx_data));
1875 if (tx && htp_tx_flags(tx)) {
1876 HtpState *hstate = htp_connp_user_data(connp);
1877 HTPErrorCheckTxRequestFlags(hstate, tx);
1879 return HTP_STATUS_OK;
1882 static int HTPCallbackResponseHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1885 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1886 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1887 return HTP_STATUS_OK;
1890 tx_ud->
tx_data.updated_tc =
true;
1894 return HTP_STATUS_OK;
1899 htp_tx_data_len(tx_data));
1902 return HTP_STATUS_OK;
1908 static void HTPConfigSetDefaultsPhase1(
HTPCfgRec *cfg_prec)
1910 htp_config_set_normalized_uri_include_all(cfg_prec->
cfg,
false);
1925 htp_config_register_request_header_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1926 htp_config_register_request_trailer_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1927 htp_config_register_response_header_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1928 htp_config_register_response_trailer_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1930 htp_config_register_request_trailer(cfg_prec->
cfg, HTPCallbackRequestHasTrailer);
1931 htp_config_register_response_trailer(cfg_prec->
cfg, HTPCallbackResponseHasTrailer);
1933 htp_config_register_request_body_data(cfg_prec->
cfg, HTPCallbackRequestBodyData);
1934 htp_config_register_response_body_data(cfg_prec->
cfg, HTPCallbackResponseBodyData);
1936 htp_config_register_tx_create(cfg_prec->
cfg, HTPCallbackTxCreate);
1937 htp_config_register_tx_destroy(cfg_prec->
cfg, HtpTxUserDataFree);
1939 htp_config_register_request_start(cfg_prec->
cfg, HTPCallbackRequestStart);
1940 htp_config_register_request_complete(cfg_prec->
cfg, HTPCallbackRequestComplete);
1942 htp_config_register_response_start(cfg_prec->
cfg, HTPCallbackResponseStart);
1943 htp_config_register_response_complete(cfg_prec->
cfg, HTPCallbackResponseComplete);
1945 htp_config_set_parse_request_cookies(cfg_prec->
cfg, 0);
1946 htp_config_set_allow_space_uri(cfg_prec->
cfg, 1);
1949 htp_config_set_plusspace_decode(cfg_prec->
cfg, 0);
1951 htp_config_set_request_decompression(cfg_prec->
cfg, 1);
1956 #define HTP_CONFIG_DEFAULT_MAX_TX_LIMIT 512
1958 #define HTP_CONFIG_DEFAULT_HEADERS_LIMIT 1024
1966 static int RandomGetWrap(
void)
1972 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
1974 return r % RAND_MAX;
1983 static void HTPConfigSetDefaultsPhase2(
const char *
name,
HTPCfgRec *cfg_prec)
1989 long int r = RandomGetWrap();
1991 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
1993 r = RandomGetWrap();
1995 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
1996 SCLogConfig(
"'%s' server has 'request-body-minimal-inspect-size' set to"
1997 " %u and 'request-body-inspect-window' set to %u after"
2001 r = RandomGetWrap();
2003 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2005 r = RandomGetWrap();
2007 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2009 SCLogConfig(
"'%s' server has 'response-body-minimal-inspect-size' set to"
2010 " %u and 'response-body-inspect-window' set to %u after"
2015 htp_config_register_request_line(cfg_prec->
cfg, HTPCallbackRequestLine);
2018 static void HTPConfigParseParameters(
HTPCfgRec *cfg_prec,
SCConfNode *s,
struct HTPConfigTree *tree)
2020 if (cfg_prec == NULL || s == NULL || tree == NULL)
2027 if (strcasecmp(
"address", p->
name) == 0) {
2033 if (strchr(pval->
val,
':') != NULL) {
2034 SCLogDebug(
"LIBHTP adding ipv6 server %s at %s: %p",
2038 SCLogWarning(
"LIBHTP failed to add ipv6 server %s, ignoring", pval->
val);
2041 SCLogDebug(
"LIBHTP adding ipv4 server %s at %s: %p",
2045 SCLogWarning(
"LIBHTP failed to add ipv4 server %s, ignoring", pval->
val);
2050 }
else if (strcasecmp(
"personality", p->
name) == 0) {
2052 int personality = HTPLookupPersonality(p->
val);
2056 if (personality >= 0) {
2059 if (htp_config_set_server_personality(cfg_prec->
cfg, personality) ==
2062 "personality \"%s\", ignoring",
2066 HTPLookupPersonalityString(personality));
2072 htp_config_set_convert_lowercase(cfg_prec->
cfg, 0);
2080 }
else if (strcasecmp(
"request-body-limit", p->
name) == 0 ||
2081 strcasecmp(
"request_body_limit", p->
name) == 0) {
2083 SCLogError(
"Error parsing request-body-limit "
2084 "from conf file - %s. Killing engine",
2089 }
else if (strcasecmp(
"response-body-limit", p->
name) == 0) {
2091 SCLogError(
"Error parsing response-body-limit "
2092 "from conf file - %s. Killing engine",
2097 }
else if (strcasecmp(
"request-body-minimal-inspect-size", p->
name) == 0) {
2099 SCLogError(
"Error parsing request-body-minimal-inspect-size "
2100 "from conf file - %s. Killing engine",
2105 }
else if (strcasecmp(
"request-body-inspect-window", p->
name) == 0) {
2107 SCLogError(
"Error parsing request-body-inspect-window "
2108 "from conf file - %s. Killing engine",
2113 }
else if (strcasecmp(
"double-decode-query", p->
name) == 0) {
2115 }
else if (strcasecmp(
"double-decode-path", p->
name) == 0) {
2117 }
else if (strcasecmp(
"response-body-minimal-inspect-size", p->
name) == 0) {
2119 SCLogError(
"Error parsing response-body-minimal-inspect-size "
2120 "from conf file - %s. Killing engine",
2125 }
else if (strcasecmp(
"response-body-inspect-window", p->
name) == 0) {
2127 SCLogError(
"Error parsing response-body-inspect-window "
2128 "from conf file - %s. Killing engine",
2133 }
else if (strcasecmp(
"response-body-decompress-layer-limit", p->
name) == 0) {
2136 SCLogError(
"Error parsing response-body-inspect-window "
2137 "from conf file - %s. Killing engine",
2141 htp_config_set_decompression_layer_limit(cfg_prec->
cfg, value);
2142 }
else if (strcasecmp(
"path-convert-backslash-separators", p->
name) == 0) {
2144 }
else if (strcasecmp(
"path-bestfit-replacement-char", p->
name) == 0) {
2145 if (strlen(p->
val) == 1) {
2146 htp_config_set_bestfit_replacement_byte(cfg_prec->
cfg, p->
val[0]);
2149 "for libhtp param path-bestfit-replacement-char");
2151 }
else if (strcasecmp(
"path-convert-lowercase", p->
name) == 0) {
2153 }
else if (strcasecmp(
"path-nul-encoded-terminates", p->
name) == 0) {
2155 }
else if (strcasecmp(
"path-nul-raw-terminates", p->
name) == 0) {
2157 }
else if (strcasecmp(
"path-separators-compress", p->
name) == 0) {
2159 }
else if (strcasecmp(
"path-separators-decode", p->
name) == 0) {
2161 }
else if (strcasecmp(
"path-u-encoding-decode", p->
name) == 0) {
2163 }
else if (strcasecmp(
"path-url-encoding-invalid-handling", p->
name) == 0) {
2164 enum htp_url_encoding_handling_t handling;
2165 if (strcasecmp(p->
val,
"preserve_percent") == 0) {
2166 handling = HTP_URL_ENCODING_HANDLING_PRESERVE_PERCENT;
2167 }
else if (strcasecmp(p->
val,
"remove_percent") == 0) {
2168 handling = HTP_URL_ENCODING_HANDLING_REMOVE_PERCENT;
2169 }
else if (strcasecmp(p->
val,
"decode_invalid") == 0) {
2170 handling = HTP_URL_ENCODING_HANDLING_PROCESS_INVALID;
2173 "for libhtp param path-url-encoding-invalid-handling");
2176 htp_config_set_url_encoding_invalid_handling(cfg_prec->
cfg, handling);
2177 }
else if (strcasecmp(
"path-utf8-convert-bestfit", p->
name) == 0) {
2179 }
else if (strcasecmp(
"uri-include-all", p->
name) == 0) {
2182 }
else if (strcasecmp(
"query-plusspace-decode", p->
name) == 0) {
2184 }
else if (strcasecmp(
"meta-field-limit", p->
name) == 0) {
2188 "from conf file - %s. Killing engine",
2194 "from conf file cannot be 0. Killing engine");
2197 htp_config_set_field_limit(cfg_prec->
cfg, (
size_t)limit);
2198 }
else if (strcasecmp(
"lzma-memlimit", p->
name) == 0) {
2201 FatalError(
"failed to parse 'lzma-memlimit' "
2202 "from conf file - %s.",
2207 "from conf file cannot be 0.");
2210 SCLogConfig(
"Setting HTTP LZMA memory limit to %"PRIu32
" bytes", limit);
2211 htp_config_set_lzma_memlimit(cfg_prec->
cfg, (
size_t)limit);
2212 }
else if (strcasecmp(
"lzma-enabled", p->
name) == 0) {
2214 htp_config_set_lzma_layers(cfg_prec->
cfg, 1);
2219 "from conf file - %s.",
2222 SCLogConfig(
"Setting HTTP LZMA decompression layers to %" PRIu32
"", (
int)limit);
2223 htp_config_set_lzma_layers(cfg_prec->
cfg, limit);
2225 }
else if (strcasecmp(
"compression-bomb-limit", p->
name) == 0) {
2228 FatalError(
"failed to parse 'compression-bomb-limit' "
2229 "from conf file - %s.",
2234 "from conf file cannot be 0.");
2237 SCLogConfig(
"Setting HTTP compression bomb limit to %"PRIu32
" bytes", limit);
2238 htp_config_set_compression_bomb_limit(cfg_prec->
cfg, (
size_t)limit);
2239 }
else if (strcasecmp(
"decompression-time-limit", p->
name) == 0) {
2243 FatalError(
"failed to parse 'decompression-time-limit' "
2244 "from conf file - %s.",
2247 SCLogConfig(
"Setting HTTP decompression time limit to %" PRIu32
" usec", limit);
2248 htp_config_set_compression_time_limit(cfg_prec->
cfg, limit);
2249 }
else if (strcasecmp(
"max-tx", p->
name) == 0) {
2253 "from conf file - %s.",
2257 SCLogConfig(
"Setting HTTP max-tx limit to %" PRIu32
" bytes", limit);
2258 htp_config_set_max_tx(cfg_prec->
cfg, limit);
2259 }
else if (strcasecmp(
"headers-limit", p->
name) == 0) {
2262 FatalError(
"failed to parse 'headers-limit' "
2263 "from conf file - %s.",
2266 SCLogConfig(
"Setting HTTP headers limit to %" PRIu32, limit);
2267 htp_config_set_number_headers_limit(cfg_prec->
cfg, limit);
2268 }
else if (strcasecmp(
"randomize-inspection-sizes", p->
name) == 0) {
2272 }
else if (strcasecmp(
"randomize-inspection-range", p->
name) == 0) {
2275 (
const char *)p->
val, 0, 100) < 0) {
2277 "-inspection-range setting from conf file - \"%s\"."
2278 " It should be a valid integer less than or equal to 100."
2284 }
else if (strcasecmp(
"http-body-inline", p->
name) == 0) {
2290 if (strcmp(
"auto", p->
val) != 0) {
2299 }
else if (strcasecmp(
"swf-decompression", p->
name) == 0) {
2303 if (strcasecmp(
"enabled", pval->
name) == 0) {
2311 }
else if (strcasecmp(
"type", pval->
name) == 0) {
2312 if (strcasecmp(
"no", pval->
val) == 0) {
2314 }
else if (strcasecmp(
"deflate", pval->
val) == 0) {
2316 }
else if (strcasecmp(
"lzma", pval->
val) == 0) {
2318 }
else if (strcasecmp(
"both", pval->
val) == 0) {
2322 "swf-decompression.type: %s - "
2327 }
else if (strcasecmp(
"compress-depth", pval->
name) == 0) {
2329 SCLogError(
"Error parsing swf-decompression.compression-depth "
2330 "from conf file - %s. Killing engine",
2334 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2336 SCLogError(
"Error parsing swf-decompression.decompression-depth "
2337 "from conf file - %s. Killing engine",
2347 "default config: %s",
2357 cfglist.
next = NULL;
2364 cfglist.
cfg = htp_config_create();
2365 if (NULL == cfglist.
cfg) {
2366 FatalError(
"Failed to create HTP default config");
2369 HTPConfigSetDefaultsPhase1(&cfglist);
2370 if (
SCConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2371 HTPConfigParseParameters(&cfglist,
SCConfGetNode(
"libhtp.default-config"), &cfgtree);
2373 HTPConfigParseParameters(&cfglist,
2374 SCConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), &cfgtree);
2376 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2382 if (server_config == NULL) {
2384 if (server_config == NULL) {
2385 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2389 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2408 cfglist.
next = htprec;
2411 cfglist.
next->
cfg = htp_config_create();
2412 if (NULL == cfglist.
next->
cfg) {
2413 FatalError(
"Failed to create HTP server config");
2416 HTPConfigSetDefaultsPhase1(htprec);
2417 HTPConfigParseParameters(htprec, s, &cfgtree);
2418 HTPConfigSetDefaultsPhase2(s->
name, htprec);
2428 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
2439 static AppLayerGetFileState HTPGetTxFiles(
void *txv, uint8_t direction)
2441 AppLayerGetFileState files = { .fc = NULL, .cfg = &
htp_sbcfg };
2442 htp_tx_t *tx = (htp_tx_t *)txv;
2444 if (direction & STREAM_TOCLIENT) {
2452 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
2454 if (direction & STREAM_TOSERVER)
2455 return htp_tx_request_progress((htp_tx_t *)tx);
2457 return htp_tx_response_progress((htp_tx_t *)tx);
2460 static uint64_t HTPStateGetTxCnt(
void *alstate)
2464 if (http_state != NULL && http_state->
connp != NULL) {
2465 const int64_t size = htp_connp_tx_size(http_state->
connp);
2469 return (uint64_t)size;
2475 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
2479 if (http_state != NULL && http_state->
connp != NULL)
2480 return (
void *)htp_connp_tx(http_state->
connp, tx_id);
2485 static AppLayerGetTxIterTuple HTPGetTxIterator(
const uint8_t ipproto,
const AppProto alproto,
2489 uint64_t size = HTPStateGetTxCnt(alstate);
2490 AppLayerGetTxIterTuple no_tuple = { NULL, 0,
false };
2492 while (state->
un.
u64 < size) {
2493 htp_tx_t *tx = htp_connp_tx_index(http_state->
connp, state->
un.
u64);
2497 uint64_t tx_id = htp_tx_index(tx);
2498 if (tx_id < min_tx_id) {
2502 AppLayerGetTxIterTuple tuple = {
2505 .has_next = state->
un.
u64 < size,
2517 if (http_state != NULL && http_state->
connp != NULL) {
2518 size_t txid = htp_connp_tx_size(http_state->
connp);
2520 return (
void *)htp_connp_tx(http_state->
connp, txid - 1);
2526 static int HTPStateGetEventInfo(
2527 const char *event_name, uint8_t *event_id, AppLayerEventType *event_type)
2530 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2536 static int HTPStateGetEventInfoById(
2537 uint8_t event_id,
const char **event_name, AppLayerEventType *event_type)
2540 if (*event_name == NULL) {
2542 "http's enum map table.",
2548 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2555 htp_tx_t *tx = (htp_tx_t *)vtx;
2560 static AppLayerStateData *HTPGetStateData(
void *vstate)
2566 static int HTPRegisterPatternsForProtocolDetection(
void)
2568 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
2569 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
2570 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
2571 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
2572 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
2573 const char *spacings[] = {
"|20|",
"|09|", NULL };
2574 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
2579 int register_result;
2580 char method_buffer[32] =
"";
2583 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
2584 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
2587 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
2594 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
2595 if (register_result < 0) {
2602 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
2604 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
2606 if (register_result < 0) {
2622 const char *proto_name =
"http";
2627 if (HTPRegisterPatternsForProtocolDetection() < 0)
2630 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
2645 ALPROTO_HTTP1, HTP_REQUEST_PROGRESS_COMPLETE, HTP_RESPONSE_PROGRESS_COMPLETE);
2657 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
2659 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
2665 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
2668 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
2671 IPPROTO_TCP,
ALPROTO_HTTP1, HtpStateGetStateIdByName, HtpStateGetStateNameById);
2675 SCLogInfo(
"Parser disabled for %s protocol. Protocol detection still on.", proto_name);
2691 cfglist_backup = cfglist;
2696 cfglist = cfglist_backup;
2701 static int HTPParserTest01(
void)
2703 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2705 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2708 memset(&ssn, 0,
sizeof(ssn));
2716 f->
proto = IPPROTO_TCP;
2722 for (u = 0; u < httplen1; u++) {
2726 flags = STREAM_TOSERVER|STREAM_START;
2727 else if (u == (httplen1 - 1))
2728 flags = STREAM_TOSERVER|STREAM_EOF;
2730 flags = STREAM_TOSERVER;
2739 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2742 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2745 FAIL_IF(bstr_cmp_c(htp_header_value(h),
"Victor/1.0"));
2746 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2747 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2756 static int HTPParserTest01b(
void)
2758 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2760 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2763 memset(&ssn, 0,
sizeof(ssn));
2771 f->
proto = IPPROTO_TCP;
2776 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
2783 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2786 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2789 FAIL_IF(strcmp(bstr_util_strdup_to_c(htp_header_value(h)),
"Victor/1.0"));
2790 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2791 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2800 static int HTPParserTest01c(
void)
2802 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2804 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2807 memset(&ssn, 0,
sizeof(ssn));
2815 f->
proto = IPPROTO_TCP;
2821 for (u = 0; u < httplen1; u++) {
2825 flags = STREAM_TOSERVER|STREAM_START;
2826 else if (u == (httplen1 - 1))
2827 flags = STREAM_TOSERVER|STREAM_EOF;
2829 flags = STREAM_TOSERVER;
2838 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2841 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2844 FAIL_IF(strcmp(bstr_util_strdup_to_c(htp_header_value(h)),
"Victor/1.0"));
2845 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2846 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2856 static int HTPParserTest01a(
void)
2859 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2861 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2866 memset(&ssn, 0,
sizeof(ssn));
2868 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2871 f->
proto = IPPROTO_TCP;
2877 for (u = 0; u < httplen1; u++) {
2881 flags = STREAM_TOSERVER|STREAM_START;
2882 else if (u == (httplen1 - 1))
2883 flags = STREAM_TOSERVER|STREAM_EOF;
2885 flags = STREAM_TOSERVER;
2894 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2897 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2900 FAIL_IF(strcmp(bstr_util_strdup_to_c(htp_header_value(h)),
"Victor/1.0"));
2901 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2902 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2911 static int HTPParserTest02(
void)
2914 uint8_t httpbuf1[] =
"POST";
2915 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2920 memset(&ssn, 0,
sizeof(ssn));
2922 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2925 f->
proto = IPPROTO_TCP;
2931 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
2937 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
2939 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2943 char *method = bstr_util_strdup_to_c(htp_tx_request_method(tx));
2946 FAIL_IF(strcmp(method,
"POST") != 0);
2957 static int HTPParserTest03(
void)
2960 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
2961 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2966 memset(&ssn, 0,
sizeof(ssn));
2968 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2971 f->
proto = IPPROTO_TCP;
2977 for (u = 0; u < httplen1; u++) {
2980 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
2981 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
2982 else flags = STREAM_TOSERVER;
2990 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2993 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2995 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
2996 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
3006 static int HTPParserTest04(
void)
3010 uint8_t httpbuf1[] =
"World!\r\n";
3011 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3015 memset(&ssn, 0,
sizeof(ssn));
3017 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3020 f->
proto = IPPROTO_TCP;
3026 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3032 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3034 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3036 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3037 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V0_9);
3047 static int HTPParserTest05(
void)
3049 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3050 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3051 uint8_t httpbuf2[] =
"Post D";
3052 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3053 uint8_t httpbuf3[] =
"ata is c0oL!";
3054 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3056 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3057 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3058 uint8_t httpbuf5[] =
"post R";
3059 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3060 uint8_t httpbuf6[] =
"esults are tha bomb!";
3061 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3064 memset(&ssn, 0,
sizeof(ssn));
3072 f->
proto = IPPROTO_TCP;
3102 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3104 FAIL_IF_NOT(htp_tx_request_method_number(tx) == HTP_METHOD_POST);
3105 FAIL_IF_NOT(htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_V1_0);
3107 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3110 FAIL_IF_NOT(htp_tx_response_status_number(tx) == 200);
3120 static int HTPParserTest06(
void)
3122 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3123 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3124 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3125 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3126 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3128 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3129 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3130 "FrontPage/5.0.2.2510\r\n"
3131 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3133 "Content-Type: text/html\r\n\r\n"
3135 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3136 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3137 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3138 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3139 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3140 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3141 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3142 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3143 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3144 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3145 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3146 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3147 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3148 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3149 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3150 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3151 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3152 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3153 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3154 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3155 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3156 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3157 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3158 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3159 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3160 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3161 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3162 "aHA=\r\n0\r\n\r\n";
3163 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3169 memset(&ssn, 0,
sizeof(ssn));
3174 f->
proto = IPPROTO_TCP;
3189 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3192 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
3193 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3195 FAIL_IF(htp_tx_response_status_number(tx) != 200);
3196 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3198 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3209 static int HTPParserTest07(
void)
3212 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3213 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3218 memset(&ssn, 0,
sizeof(ssn));
3220 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3223 f->
proto = IPPROTO_TCP;
3229 for (u = 0; u < httplen1; u++) {
3233 flags = STREAM_TOSERVER|STREAM_START;
3234 else if (u == (httplen1 - 1))
3235 flags = STREAM_TOSERVER|STREAM_EOF;
3237 flags = STREAM_TOSERVER;
3246 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3247 size_t reflen =
sizeof(ref) - 1;
3249 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3251 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3253 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3255 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref, bstr_len(request_uri_normalized)) != 0);
3267 static int HTPParserTest08(
void)
3270 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3271 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3292 memset(&ssn, 0,
sizeof(ssn));
3294 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3297 f->
proto = IPPROTO_TCP;
3302 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3310 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3312 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3314 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3328 static int HTPParserTest09(
void)
3331 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3332 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3342 personality: Apache_2_2\n\
3354 memset(&ssn, 0,
sizeof(ssn));
3356 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3359 f->
proto = IPPROTO_TCP;
3364 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3372 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3374 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3376 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3390 static int HTPParserTest10(
void)
3394 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3395 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3400 memset(&ssn, 0,
sizeof(ssn));
3402 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3405 f->
proto = IPPROTO_TCP;
3411 for (u = 0; u < httplen1; u++) {
3415 flags = STREAM_TOSERVER|STREAM_START;
3416 else if (u == (httplen1 - 1))
3417 flags = STREAM_TOSERVER|STREAM_EOF;
3419 flags = STREAM_TOSERVER;
3428 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3429 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3432 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3436 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3438 FAIL_IF(strcmp(value,
"www.google.com") != 0);
3450 static int HTPParserTest11(
void)
3453 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3454 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3459 memset(&ssn, 0,
sizeof(ssn));
3461 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3464 f->
proto = IPPROTO_TCP;
3470 for (u = 0; u < httplen1; u++) {
3474 flags = STREAM_TOSERVER|STREAM_START;
3475 else if (u == (httplen1 - 1))
3476 flags = STREAM_TOSERVER|STREAM_EOF;
3478 flags = STREAM_TOSERVER;
3487 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3489 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3492 FAIL_IF(bstr_len(request_uri_normalized) != 4);
3493 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3494 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'%');
3495 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'0');
3496 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'0');
3506 static int HTPParserTest12(
void)
3509 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3510 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3515 memset(&ssn, 0,
sizeof(ssn));
3517 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3520 f->
proto = IPPROTO_TCP;
3526 for (u = 0; u < httplen1; u++) {
3530 flags = STREAM_TOSERVER|STREAM_START;
3531 else if (u == (httplen1 - 1))
3532 flags = STREAM_TOSERVER|STREAM_EOF;
3534 flags = STREAM_TOSERVER;
3543 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3545 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3548 FAIL_IF(bstr_len(request_uri_normalized) != 7);
3549 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3550 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'?');
3551 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'a');
3552 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'=');
3553 FAIL_IF(bstr_ptr(request_uri_normalized)[4] !=
'%');
3554 FAIL_IF(bstr_ptr(request_uri_normalized)[5] !=
'0');
3555 FAIL_IF(bstr_ptr(request_uri_normalized)[6] !=
'0');
3565 static int HTPParserTest13(
void)
3568 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3569 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3574 memset(&ssn, 0,
sizeof(ssn));
3576 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3579 f->
proto = IPPROTO_TCP;
3585 for (u = 0; u < httplen1; u++) {
3589 flags = STREAM_TOSERVER|STREAM_START;
3590 else if (u == (httplen1 - 1))
3591 flags = STREAM_TOSERVER|STREAM_EOF;
3593 flags = STREAM_TOSERVER;
3601 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3602 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3605 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3609 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3611 FAIL_IF(strcmp(value,
"www.google.com\rName: Value") != 0);
3623 static int HTPParserConfigTest01(
void)
3636 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3637 personality: Tomcat_6_0\n\
3642 - 192.168.10.0/24\n\
3643 personality: IIS_7_0\n\
3652 outputs =
SCConfGetNode(
"libhtp.default-config.personality");
3663 FAIL_IF(strcmp(node->
name,
"apache-tomcat") != 0);
3670 FAIL_IF(strcmp(node2->
val,
"Tomcat_6_0") != 0);
3680 FAIL_IF(strcmp(n->
val,
"192.168.1.0/24") != 0);
3720 FAIL_IF(strcmp(n->
val,
"192.168.0.0/24") != 0);
3724 FAIL_IF(strcmp(n->
val,
"192.168.10.0/24") != 0);
3739 static int HTPParserConfigTest02(
void)
3752 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3753 personality: Tomcat_6_0\n\
3758 - 192.168.10.0/24\n\
3759 personality: IIS_7_0\n\
3771 htp_cfg_t *htp = cfglist.
cfg;
3774 void *user_data = NULL;
3776 addr =
"192.168.10.42";
3777 FAIL_IF(inet_pton(AF_INET, addr, buf) != 1);
3781 htp = htp_cfg_rec->
cfg;
3787 FAIL_IF(inet_pton(AF_INET6, addr, buf) != 1);
3790 htp_cfg_rec = user_data;
3791 htp = htp_cfg_rec->
cfg;
3804 static int HTPParserConfigTest03(
void)
3807 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3809 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3825 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3826 personality: Tomcat_6_0\n\
3831 - 192.168.10.0/24\n\
3832 personality: IIS_7_0\n\
3843 const char *addr =
"192.168.10.42";
3845 memset(&ssn, 0,
sizeof(ssn));
3850 f->
proto = IPPROTO_TCP;
3853 htp_cfg_t *htp = cfglist.
cfg;
3856 void *user_data = NULL;
3861 htp = htp_cfg_rec->
cfg;
3868 for (u = 0; u < httplen1; u++) {
3871 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3872 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3873 else flags = STREAM_TOSERVER;
3882 FAIL_IF(HTPStateGetTxCnt(htp_state) != 2);
3884 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3886 tx = HTPStateGetTx(htp_state, 1);
3905 static int HTPParserDecodingTest01(
void)
3907 uint8_t httpbuf1[] =
3908 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3909 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3910 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
3911 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3922 personality: Apache_2\n\
3930 const char *addr =
"4.3.2.1";
3931 memset(&ssn, 0,
sizeof(ssn));
3936 f->
proto = IPPROTO_TCP;
3941 for (uint32_t u = 0; u < httplen1; u++) {
3943 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3944 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3945 else flags = STREAM_TOSERVER;
3954 uint8_t ref1[] =
"/abc%2fdef";
3955 size_t reflen =
sizeof(ref1) - 1;
3957 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3961 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3964 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3965 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
3967 uint8_t ref2[] =
"/abc/def?ghi/jkl";
3968 reflen =
sizeof(ref2) - 1;
3970 tx = HTPStateGetTx(htp_state, 1);
3974 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3977 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3978 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
3980 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
3981 reflen =
sizeof(ref3) - 1;
3982 tx = HTPStateGetTx(htp_state, 2);
3986 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3989 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3990 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4002 static int HTPParserDecodingTest01a(
void)
4004 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4005 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4006 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4007 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4018 personality: Apache_2\n\
4026 const char *addr =
"4.3.2.1";
4027 memset(&ssn, 0,
sizeof(ssn));
4032 f->
proto = IPPROTO_TCP;
4038 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4044 uint8_t ref1[] =
"/abc%2fdef";
4045 size_t reflen =
sizeof(ref1) - 1;
4047 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4051 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4054 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4055 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4057 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4058 reflen =
sizeof(ref2) - 1;
4060 tx = HTPStateGetTx(htp_state, 1);
4063 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4066 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4068 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4070 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4071 reflen =
sizeof(ref3) - 1;
4072 tx = HTPStateGetTx(htp_state, 2);
4075 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4078 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4080 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4098 static int HTPParserDecodingTest02(
void)
4101 uint8_t httpbuf1[] =
4102 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4103 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4104 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4105 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4117 double-decode-path: no\n\
4118 double-decode-query: no\n\
4126 const char *addr =
"4.3.2.1";
4127 memset(&ssn, 0,
sizeof(ssn));
4132 f->
proto = IPPROTO_TCP;
4138 for (u = 0; u < httplen1; u++) {
4141 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4142 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4143 else flags = STREAM_TOSERVER;
4152 uint8_t ref1[] =
"/abc/def";
4153 size_t reflen =
sizeof(ref1) - 1;
4155 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4157 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4159 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4160 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4162 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4163 reflen =
sizeof(ref2) - 1;
4165 tx = HTPStateGetTx(htp_state, 1);
4167 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4169 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4171 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4173 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4174 reflen =
sizeof(ref3) - 1;
4175 tx = HTPStateGetTx(htp_state, 2);
4177 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4179 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4181 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4198 static int HTPParserDecodingTest03(
void)
4201 uint8_t httpbuf1[] =
4202 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4203 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4204 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4216 double-decode-path: yes\n\
4217 double-decode-query: yes\n\
4225 const char *addr =
"4.3.2.1";
4226 memset(&ssn, 0,
sizeof(ssn));
4231 f->
proto = IPPROTO_TCP;
4237 for (u = 0; u < httplen1; u++) {
4240 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4241 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4242 else flags = STREAM_TOSERVER;
4251 uint8_t ref1[] =
"/abc/def";
4252 size_t reflen =
sizeof(ref1) - 1;
4254 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4256 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4258 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4260 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4262 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4263 reflen =
sizeof(ref2) - 1;
4265 tx = HTPStateGetTx(htp_state, 1);
4267 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4269 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4271 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4285 static int HTPParserDecodingTest04(
void)
4288 uint8_t httpbuf1[] =
4289 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4290 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4302 double-decode-path: yes\n\
4303 double-decode-query: yes\n\
4311 const char *addr =
"4.3.2.1";
4312 memset(&ssn, 0,
sizeof(ssn));
4317 f->
proto = IPPROTO_TCP;
4323 for (u = 0; u < httplen1; u++) {
4326 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4327 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4328 else flags = STREAM_TOSERVER;
4337 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
4338 size_t reflen =
sizeof(ref1) - 1;
4340 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4342 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4344 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4346 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4360 static int HTPParserDecodingTest05(
void)
4363 uint8_t httpbuf1[] =
4364 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4365 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4377 double-decode-path: yes\n\
4378 double-decode-query: yes\n\
4386 const char *addr =
"4.3.2.1";
4387 memset(&ssn, 0,
sizeof(ssn));
4392 f->
proto = IPPROTO_TCP;
4398 for (u = 0; u < httplen1; u++) {
4401 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4402 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4403 else flags = STREAM_TOSERVER;
4412 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
4413 size_t reflen =
sizeof(ref1) - 1;
4415 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4417 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4419 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4421 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4435 static int HTPParserDecodingTest06(
void)
4438 uint8_t httpbuf1[] =
4439 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4440 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4452 double-decode-path: yes\n\
4453 double-decode-query: yes\n\
4461 const char *addr =
"4.3.2.1";
4462 memset(&ssn, 0,
sizeof(ssn));
4467 f->
proto = IPPROTO_TCP;
4473 for (u = 0; u < httplen1; u++) {
4476 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4477 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4478 else flags = STREAM_TOSERVER;
4487 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
4488 size_t reflen =
sizeof(ref1) - 1;
4490 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4492 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4494 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4496 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4510 static int HTPParserDecodingTest07(
void)
4513 uint8_t httpbuf1[] =
4514 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4515 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4527 double-decode-path: yes\n\
4528 double-decode-query: yes\n\
4529 query-plusspace-decode: yes\n\
4537 const char *addr =
"4.3.2.1";
4538 memset(&ssn, 0,
sizeof(ssn));
4543 f->
proto = IPPROTO_TCP;
4549 for (u = 0; u < httplen1; u++) {
4552 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4553 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4554 else flags = STREAM_TOSERVER;
4563 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
4564 size_t reflen =
sizeof(ref1) - 1;
4566 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4568 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4570 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4572 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4586 static int HTPParserDecodingTest08(
void)
4589 uint8_t httpbuf1[] =
4590 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4591 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4610 const char *addr =
"4.3.2.1";
4611 memset(&ssn, 0,
sizeof(ssn));
4616 f->
proto = IPPROTO_TCP;
4622 for (u = 0; u < httplen1; u++) {
4625 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4626 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4627 else flags = STREAM_TOSERVER;
4636 uint8_t ref1[] =
"/blah/";
4637 size_t reflen =
sizeof(ref1) - 1;
4639 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4641 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4643 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4645 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4659 static int HTPParserDecodingTest09(
void)
4662 uint8_t httpbuf1[] =
4663 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4664 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4676 uri-include-all: true\n\
4684 const char *addr =
"4.3.2.1";
4685 memset(&ssn, 0,
sizeof(ssn));
4690 f->
proto = IPPROTO_TCP;
4696 for (u = 0; u < httplen1; u++) {
4699 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4700 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4701 else flags = STREAM_TOSERVER;
4710 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
4711 size_t reflen =
sizeof(ref1) - 1;
4713 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4715 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4717 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4719 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4732 static int HTPBodyReassemblyTest01(
void)
4735 memset(&htud, 0x00,
sizeof(htud));
4737 memset(&hstate, 0x00,
sizeof(hstate));
4739 memset(&flow, 0x00,
sizeof(flow));
4741 htp_cfg_t *cfg = htp_config_create();
4743 htp_connp_t *connp = htp_connp_create(cfg);
4745 const htp_tx_t *tx = htp_connp_get_request_tx(connp);
4751 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
4752 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";
4759 const uint8_t *chunks_buffer = NULL;
4760 uint32_t chunks_buffer_len = 0;
4762 HtpRequestBodyReassemble(&htud, &chunks_buffer, &chunks_buffer_len);
4765 printf(
"REASSCHUNK START: \n");
4767 printf(
"REASSCHUNK END: \n");
4770 htud.
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
4771 strlen(
"multipart/form-data; boundary=toto"));
4774 HtpRequestBodyHandleMultipart(&hstate, &htud, &tx, chunks_buffer, chunks_buffer_len,
false);
4784 static int HTPSegvTest01(
void)
4787 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";
4788 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4796 double-decode-path: no\n\
4797 double-decode-query: no\n\
4798 request-body-limit: 0\n\
4799 response-body-limit: 0\n\
4812 memset(&ssn, 0,
sizeof(ssn));
4814 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4817 f->
proto = IPPROTO_TCP;
4822 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
4826 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
4847 static int HTPParserTest14(
void)
4858 double-decode-path: no\n\
4859 double-decode-query: no\n\
4860 request-body-limit: 0\n\
4861 response-body-limit: 0\n\
4866 memset(&ssn, 0,
sizeof(ssn));
4876 memset(httpbuf, 0x00,
len);
4879 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4880 "Host: myhost.lan\r\n"
4881 "Connection: keep-alive\r\n"
4883 "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"
4884 "Referer: http://blah.lan/\r\n"
4885 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
4887 size_t o = strlen(httpbuf);
4888 for ( ; o <
len - 4; o++) {
4891 httpbuf[
len - 4] =
'\r';
4892 httpbuf[
len - 3] =
'\n';
4893 httpbuf[
len - 2] =
'\r';
4894 httpbuf[
len - 1] =
'\n';
4900 f->
proto = IPPROTO_TCP;
4905 for (u = 0; u <
len; u++) {
4908 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4909 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4910 else flags = STREAM_TOSERVER;
4918 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4920 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
4921 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
4928 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG);
4943 static int HTPParserTest15(
void)
4946 char *httpbuf = NULL;
4957 double-decode-path: no\n\
4958 double-decode-query: no\n\
4959 request-body-limit: 0\n\
4960 response-body-limit: 0\n\
4961 meta-field-limit: 20000\n\
4965 memset(&ssn, 0,
sizeof(ssn));
4976 memset(httpbuf, 0x00,
len);
4979 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4980 "Host: myhost.lan\r\n"
4981 "Connection: keep-alive\r\n"
4983 "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"
4984 "Referer: http://blah.lan/\r\n"
4985 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
4987 size_t o = strlen(httpbuf);
4988 for ( ; o <
len - 4; o++) {
4991 httpbuf[
len - 4] =
'\r';
4992 httpbuf[
len - 3] =
'\n';
4993 httpbuf[
len - 2] =
'\r';
4994 httpbuf[
len - 1] =
'\n';
4996 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4999 f->
proto = IPPROTO_TCP;
5005 for (u = 0; u <
len; u++) {
5008 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5009 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5010 else flags = STREAM_TOSERVER;
5019 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5021 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5022 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5041 static int HTPParserTest16(
void)
5048 memset(&ssn, 0,
sizeof(ssn));
5050 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5051 "Host: myhost.lan\r\n"
5052 "Connection: keep-alive\r\n"
5054 "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"
5055 "Referer: http://blah.lan/\r\n"
5056 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5057 "Cookie: blah\r\n\r\n";
5058 size_t len =
sizeof(httpbuf) - 1;
5060 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5063 f->
proto = IPPROTO_TCP;
5068 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5076 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5078 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5079 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5081 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5088 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT);
5089 FAIL_IF(decoder_events->
events[1] != HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT);
5100 static int HTPParserTest20(
void)
5103 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5104 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5105 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5106 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5107 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
5108 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5109 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5110 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5116 memset(&ssn, 0,
sizeof(ssn));
5118 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5121 f->
proto = IPPROTO_TCP;
5140 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5142 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5145 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5146 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5148 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5149 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5159 static int HTPParserTest21(
void)
5162 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5163 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5164 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5165 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5166 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
5167 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5168 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5169 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5175 memset(&ssn, 0,
sizeof(ssn));
5177 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5180 f->
proto = IPPROTO_TCP;
5199 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5201 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5204 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5205 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5207 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5208 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5218 static int HTPParserTest22(
void)
5221 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5222 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5223 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5224 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5225 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
5226 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5227 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5233 memset(&ssn, 0,
sizeof(ssn));
5235 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5238 f->
proto = IPPROTO_TCP;
5253 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5255 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5258 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5259 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5261 FAIL_IF(htp_tx_response_status_number(tx) != -0);
5262 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5272 static int HTPParserTest23(
void)
5275 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5276 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5277 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5278 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5279 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
5280 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5281 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5287 memset(&ssn, 0,
sizeof(ssn));
5289 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5292 f->
proto = IPPROTO_TCP;
5307 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5309 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5312 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5313 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5315 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5316 FAIL_IF(htp_tx_response_protocol_number(tx) != -2);
5327 static int HTPParserTest24(
void)
5330 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5331 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5332 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5333 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5334 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
5335 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5336 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5342 memset(&ssn, 0,
sizeof(ssn));
5344 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5347 f->
proto = IPPROTO_TCP;
5362 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5364 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5367 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5368 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5370 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5371 FAIL_IF(htp_tx_response_protocol_number(tx) != HTP_PROTOCOL_V1_0);
5381 static int HTPParserTest25(
void)
5388 memset(&ssn, 0,
sizeof(ssn));
5393 f->
proto = IPPROTO_TCP;
5397 const char *
str =
"GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
5399 (uint8_t *)
str, strlen(
str));
5423 str =
"HTTP 1.1 200 OK\r\nServer: Suricata/1.0\r\nContent-Length: 8\r\n\r\nSuricata";
5425 (uint8_t *)
str, strlen(
str));
5459 (uint8_t *)
str, strlen(
str));
5470 (uint8_t *)
str, strlen(
str));
5491 static int HTPParserTest26(
void)
5500 request-body-limit: 1\n\
5501 response-body-limit: 1\n\
5515 uint8_t httpbuf1[] =
"GET /alice.txt HTTP/1.1\r\n\r\n";
5516 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5517 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\n"
5518 "Content-Type: text/plain\r\n"
5519 "Content-Length: 228\r\n\r\n"
5520 "Alice was beginning to get very tired of sitting by her sister on the bank."
5521 "Alice was beginning to get very tired of sitting by her sister on the bank.";
5522 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5523 uint8_t httpbuf3[] =
"Alice was beginning to get very tired of sitting by her sister on the bank.\r\n\r\n";
5524 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5530 memset(&th_v, 0,
sizeof(th_v));
5531 memset(&f, 0,
sizeof(f));
5532 memset(&ssn, 0,
sizeof(ssn));
5539 f.
proto = IPPROTO_TCP;
5560 "(filestore; sid:1; rev:1;)");
5605 AppLayerGetFileState files = HTPGetTxFiles(tx_ptr, STREAM_TOCLIENT);
5628 static int HTPParserTest27(
void)
5631 memset(&cfg, 0,
sizeof(cfg));
5635 uint32_t
len = 1000;
5660 static void HTPParserRegisterTests(
void)
5682 UtRegisterTest(
"HTPParserDecodingTest01", HTPParserDecodingTest01);
5683 UtRegisterTest(
"HTPParserDecodingTest01a", HTPParserDecodingTest01a);
5684 UtRegisterTest(
"HTPParserDecodingTest02", HTPParserDecodingTest02);
5685 UtRegisterTest(
"HTPParserDecodingTest03", HTPParserDecodingTest03);
5686 UtRegisterTest(
"HTPParserDecodingTest04", HTPParserDecodingTest04);
5687 UtRegisterTest(
"HTPParserDecodingTest05", HTPParserDecodingTest05);
5688 UtRegisterTest(
"HTPParserDecodingTest06", HTPParserDecodingTest06);
5689 UtRegisterTest(
"HTPParserDecodingTest07", HTPParserDecodingTest07);
5690 UtRegisterTest(
"HTPParserDecodingTest08", HTPParserDecodingTest08);
5691 UtRegisterTest(
"HTPParserDecodingTest09", HTPParserDecodingTest09);
5693 UtRegisterTest(
"HTPBodyReassemblyTest01", HTPBodyReassemblyTest01);