74 static struct HTPConfigTree {
90 #define HTP_MAX_MESSAGES 512
96 static uint64_t htp_state_memuse = 0;
97 static uint64_t htp_state_memcnt = 0;
101 {
"UNKNOWN_ERROR", HTP_LOG_CODE_UNKNOWN },
102 {
"GZIP_DECOMPRESSION_FAILED", HTP_LOG_CODE_GZIP_DECOMPRESSION_FAILED },
103 {
"REQUEST_FIELD_MISSING_COLON", HTP_LOG_CODE_REQUEST_FIELD_MISSING_COLON },
104 {
"RESPONSE_FIELD_MISSING_COLON", HTP_LOG_CODE_RESPONSE_FIELD_MISSING_COLON },
105 {
"INVALID_REQUEST_CHUNK_LEN", HTP_LOG_CODE_INVALID_REQUEST_CHUNK_LEN },
106 {
"INVALID_RESPONSE_CHUNK_LEN", HTP_LOG_CODE_INVALID_RESPONSE_CHUNK_LEN },
107 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST",
108 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST },
109 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE",
110 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE },
111 {
"INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST",
112 HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST },
113 {
"INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE",
114 HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE },
115 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST",
116 HTP_LOG_CODE_DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST },
117 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE",
118 HTP_LOG_CODE_DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE },
119 {
"100_CONTINUE_ALREADY_SEEN", HTP_LOG_CODE_CONTINUE_ALREADY_SEEN },
120 {
"UNABLE_TO_MATCH_RESPONSE_TO_REQUEST", HTP_LOG_CODE_UNABLE_TO_MATCH_RESPONSE_TO_REQUEST },
121 {
"INVALID_SERVER_PORT_IN_REQUEST", HTP_LOG_CODE_INVALID_SERVER_PORT_IN_REQUEST },
122 {
"INVALID_AUTHORITY_PORT", HTP_LOG_CODE_INVALID_AUTHORITY_PORT },
123 {
"REQUEST_HEADER_INVALID", HTP_LOG_CODE_REQUEST_HEADER_INVALID },
124 {
"RESPONSE_HEADER_INVALID", HTP_LOG_CODE_RESPONSE_HEADER_INVALID },
125 {
"MISSING_HOST_HEADER", HTP_LOG_CODE_MISSING_HOST_HEADER },
126 {
"HOST_HEADER_AMBIGUOUS", HTP_LOG_CODE_HOST_HEADER_AMBIGUOUS },
127 {
"INVALID_REQUEST_FIELD_FOLDING", HTP_LOG_CODE_INVALID_REQUEST_FIELD_FOLDING },
128 {
"INVALID_RESPONSE_FIELD_FOLDING", HTP_LOG_CODE_INVALID_RESPONSE_FIELD_FOLDING },
129 {
"REQUEST_FIELD_TOO_LONG", HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG },
130 {
"RESPONSE_FIELD_TOO_LONG", HTP_LOG_CODE_RESPONSE_FIELD_TOO_LONG },
131 {
"REQUEST_LINE_INVALID", HTP_LOG_CODE_REQUEST_LINE_INVALID },
132 {
"REQUEST_BODY_UNEXPECTED", HTP_LOG_CODE_REQUEST_BODY_UNEXPECTED },
133 {
"RESPONSE_BODY_UNEXPECTED", HTP_LOG_CODE_RESPONSE_BODY_UNEXPECTED },
134 {
"REQUEST_SERVER_PORT_TCP_PORT_MISMATCH", HTP_LOG_CODE_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH },
135 {
"REQUEST_URI_HOST_INVALID", HTP_LOG_CODE_URI_HOST_INVALID },
136 {
"REQUEST_HEADER_HOST_INVALID", HTP_LOG_CODE_HEADER_HOST_INVALID },
137 {
"REQUEST_AUTH_UNRECOGNIZED", HTP_LOG_CODE_AUTH_UNRECOGNIZED },
138 {
"REQUEST_HEADER_REPETITION", HTP_LOG_CODE_REQUEST_HEADER_REPETITION },
139 {
"RESPONSE_HEADER_REPETITION", HTP_LOG_CODE_RESPONSE_HEADER_REPETITION },
140 {
"DOUBLE_ENCODED_URI", HTP_LOG_CODE_DOUBLE_ENCODED_URI },
141 {
"URI_DELIM_NON_COMPLIANT", HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT },
142 {
"METHOD_DELIM_NON_COMPLIANT", HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT },
143 {
"REQUEST_LINE_LEADING_WHITESPACE", HTP_LOG_CODE_REQUEST_LINE_LEADING_WHITESPACE },
144 {
"TOO_MANY_ENCODING_LAYERS", HTP_LOG_CODE_TOO_MANY_ENCODING_LAYERS },
145 {
"REQUEST_TOO_MANY_LZMA_LAYERS", HTP_LOG_CODE_REQUEST_TOO_MANY_LZMA_LAYERS },
146 {
"RESPONSE_TOO_MANY_LZMA_LAYERS", HTP_LOG_CODE_RESPONSE_TOO_MANY_LZMA_LAYERS },
147 {
"ABNORMAL_CE_HEADER", HTP_LOG_CODE_ABNORMAL_CE_HEADER },
148 {
"RESPONSE_MULTIPART_BYTERANGES", HTP_LOG_CODE_RESPONSE_MULTIPART_BYTERANGES },
149 {
"RESPONSE_ABNORMAL_TRANSFER_ENCODING", HTP_LOG_CODE_RESPONSE_ABNORMAL_TRANSFER_ENCODING },
150 {
"RESPONSE_CHUNKED_OLD_PROTO", HTP_LOG_CODE_RESPONSE_CHUNKED_OLD_PROTO },
151 {
"RESPONSE_INVALID_PROTOCOL", HTP_LOG_CODE_RESPONSE_INVALID_PROTOCOL },
152 {
"RESPONSE_INVALID_STATUS", HTP_LOG_CODE_RESPONSE_INVALID_STATUS },
153 {
"REQUEST_LINE_INCOMPLETE", HTP_LOG_CODE_REQUEST_LINE_INCOMPLETE },
154 {
"PROTOCOL_CONTAINS_EXTRA_DATA", HTP_LOG_CODE_PROTOCOL_CONTAINS_EXTRA_DATA },
156 "CONTENT_LENGTH_EXTRA_DATA_START",
157 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_START,
160 "CONTENT_LENGTH_EXTRA_DATA_END",
161 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_END,
163 {
"SWITCHING_PROTO_WITH_CONTENT_LENGTH", HTP_LOG_CODE_SWITCHING_PROTO_WITH_CONTENT_LENGTH },
164 {
"DEFORMED_EOL", HTP_LOG_CODE_DEFORMED_EOL },
165 {
"PARSER_STATE_ERROR", HTP_LOG_CODE_PARSER_STATE_ERROR },
166 {
"MISSING_OUTBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_OUTBOUND_TRANSACTION_DATA },
167 {
"MISSING_INBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_INBOUND_TRANSACTION_DATA },
168 {
"ZERO_LENGTH_DATA_CHUNKS", HTP_LOG_CODE_ZERO_LENGTH_DATA_CHUNKS },
169 {
"REQUEST_LINE_UNKNOWN_METHOD", HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD },
170 {
"REQUEST_LINE_UNKNOWN_METHOD_NO_PROTOCOL",
171 HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD_NO_PROTOCOL },
172 {
"REQUEST_LINE_UNKNOWN_METHOD_INVALID_PROTOCOL",
173 HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD_INVALID_PROTOCOL },
174 {
"REQUEST_LINE_MISSING_PROTOCOL", HTP_LOG_CODE_REQUEST_LINE_NO_PROTOCOL },
175 {
"RESPONSE_LINE_INVALID_PROTOCOL", HTP_LOG_CODE_RESPONSE_LINE_INVALID_PROTOCOL },
176 {
"RESPONSE_LINE_INVALID_RESPONSE_STATUS", HTP_LOG_CODE_RESPONSE_LINE_INVALID_RESPONSE_STATUS },
177 {
"RESPONSE_BODY_INTERNAL_ERROR", HTP_LOG_CODE_RESPONSE_BODY_INTERNAL_ERROR },
178 {
"REQUEST_BODY_DATA_CALLBACK_ERROR", HTP_LOG_CODE_REQUEST_BODY_DATA_CALLBACK_ERROR },
179 {
"RESPONSE_INVALID_EMPTY_NAME", HTP_LOG_CODE_RESPONSE_INVALID_EMPTY_NAME },
180 {
"REQUEST_INVALID_EMPTY_NAME", HTP_LOG_CODE_REQUEST_INVALID_EMPTY_NAME },
181 {
"RESPONSE_INVALID_LWS_AFTER_NAME", HTP_LOG_CODE_RESPONSE_INVALID_LWS_AFTER_NAME },
182 {
"RESPONSE_HEADER_NAME_NOT_TOKEN", HTP_LOG_CODE_RESPONSE_HEADER_NAME_NOT_TOKEN },
183 {
"REQUEST_INVALID_LWS_AFTER_NAME", HTP_LOG_CODE_REQUEST_INVALID_LWS_AFTER_NAME },
184 {
"LZMA_DECOMPRESSION_DISABLED", HTP_LOG_CODE_LZMA_DECOMPRESSION_DISABLED },
185 {
"CONNECTION_ALREADY_OPEN", HTP_LOG_CODE_CONNECTION_ALREADY_OPEN },
186 {
"COMPRESSION_BOMB_DOUBLE_LZMA", HTP_LOG_CODE_COMPRESSION_BOMB_DOUBLE_LZMA },
187 {
"INVALID_CONTENT_ENCODING", HTP_LOG_CODE_INVALID_CONTENT_ENCODING },
188 {
"INVALID_GAP", HTP_LOG_CODE_INVALID_GAP },
189 {
"REQUEST_CHUNK_EXTENSION", HTP_LOG_CODE_REQUEST_CHUNK_EXTENSION },
190 {
"RESPONSE_CHUNK_EXTENSION", HTP_LOG_CODE_RESPONSE_CHUNK_EXTENSION },
192 {
"LZMA_MEMLIMIT_REACHED", HTP_LOG_CODE_LZMA_MEMLIMIT_REACHED },
193 {
"COMPRESSION_BOMB", HTP_LOG_CODE_COMPRESSION_BOMB },
194 {
"COMPRESSION_BOMB_LIMIT_REACHED", HTP_LOG_CODE_COMPRESSION_BOMB_LIMIT_REACHED },
196 {
"REQUEST_TOO_MANY_HEADERS", HTP_LOG_CODE_REQUEST_TOO_MANY_HEADERS },
197 {
"RESPONSE_TOO_MANY_HEADERS", HTP_LOG_CODE_RESPONSE_TOO_MANY_HEADERS },
230 static int HTTPGetFrameIdByName(
const char *frame_name)
239 static const char *HTTPGetFrameNameById(
const uint8_t frame_id)
249 HTP_REQUEST_PROGRESS_NOT_STARTED,
253 HTP_REQUEST_PROGRESS_LINE,
257 HTP_REQUEST_PROGRESS_HEADERS,
261 HTP_REQUEST_PROGRESS_BODY,
265 HTP_REQUEST_PROGRESS_TRAILER,
269 HTP_REQUEST_PROGRESS_COMPLETE,
278 HTP_RESPONSE_PROGRESS_NOT_STARTED,
282 HTP_RESPONSE_PROGRESS_LINE,
286 HTP_RESPONSE_PROGRESS_HEADERS,
290 HTP_RESPONSE_PROGRESS_BODY,
294 HTP_RESPONSE_PROGRESS_TRAILER,
298 HTP_RESPONSE_PROGRESS_COMPLETE,
303 static int HtpStateGetStateIdByName(
const char *
name,
const uint8_t direction)
306 direction == STREAM_TOSERVER ? http_state_client_table : http_state_server_table;
315 static const char *HtpStateGetStateNameById(
const int id,
const uint8_t direction)
318 direction == STREAM_TOSERVER ? http_state_client_table : http_state_server_table;
323 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id);
324 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction);
325 static uint64_t HTPStateGetTxCnt(
void *alstate);
327 static void HTPParserRegisterTests(
void);
330 static inline uint64_t HtpGetActiveRequestTxID(
HtpState *s)
332 uint64_t
id = HTPStateGetTxCnt(s);
337 static inline uint64_t HtpGetActiveResponseTxID(
HtpState *s)
350 static const char *HTPLookupPersonalityString(
int p)
352 #define CASE_HTP_PERSONALITY_STRING(p) \
353 case HTP_SERVER_PERSONALITY_##p: \
357 CASE_HTP_PERSONALITY_STRING(MINIMAL);
358 CASE_HTP_PERSONALITY_STRING(GENERIC);
359 CASE_HTP_PERSONALITY_STRING(IDS);
360 CASE_HTP_PERSONALITY_STRING(IIS_4_0);
361 CASE_HTP_PERSONALITY_STRING(IIS_5_0);
362 CASE_HTP_PERSONALITY_STRING(IIS_5_1);
363 CASE_HTP_PERSONALITY_STRING(IIS_6_0);
364 CASE_HTP_PERSONALITY_STRING(IIS_7_0);
365 CASE_HTP_PERSONALITY_STRING(IIS_7_5);
366 CASE_HTP_PERSONALITY_STRING(APACHE_2);
380 static int HTPLookupPersonality(
const char *
str)
382 #define IF_HTP_PERSONALITY_NUM(p) \
383 if (strcasecmp(#p, str) == 0) \
384 return HTP_SERVER_PERSONALITY_##p
396 if (strcasecmp(
"TOMCAT_6_0",
str) == 0) {
398 "longer supported by libhtp.",
401 }
else if ((strcasecmp(
"APACHE",
str) == 0) ||
402 (strcasecmp(
"APACHE_2_2",
str) == 0))
405 "longer supported by libhtp, failing back to "
406 "Apache2 personality.",
408 return HTP_SERVER_PERSONALITY_APACHE_2;
415 const uint8_t dir,
const uint8_t e)
425 const uint64_t tx_id = (dir == STREAM_TOSERVER) ?
426 HtpGetActiveRequestTxID(s) : HtpGetActiveResponseTxID(s);
428 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
429 if (tx == NULL && tx_id > 0)
430 tx = HTPStateGetTx(s, tx_id - 1);
434 if (dir & STREAM_TOCLIENT)
436 if (dir & STREAM_TOSERVER)
447 static void *HTPStateAlloc(
void *orig_state,
AppProto proto_orig)
461 htp_state_memuse +=
sizeof(
HtpState);
462 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
469 static void HtpTxUserDataFree(
void *txud)
505 if (s->
connp != NULL) {
507 htp_connp_destroy_all(s->
connp);
515 htp_state_memuse -=
sizeof(
HtpState);
516 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
527 static void HTPStateTransactionFree(
void *state, uint64_t
id)
534 htp_tx_destroy(s->
connp,
id);
579 static void AppLayerHtpSetStreamDepthFlag(
void *tx,
const uint8_t
flags)
583 if (
flags & STREAM_TOCLIENT) {
592 SCLogDebug(
"cfg->body_limit %u stream_depth %u body->content_len_so_far %" PRIu64,
609 static uint32_t AppLayerHtpComputeChunkLength(uint64_t content_len_so_far, uint32_t body_limit,
610 uint32_t stream_depth, uint8_t
flags, uint32_t data_len)
612 uint32_t chunk_len = 0;
614 (content_len_so_far < (uint64_t)body_limit) &&
615 (content_len_so_far + (uint64_t)data_len) > body_limit)
617 chunk_len = (uint32_t)(body_limit - content_len_so_far);
619 (content_len_so_far < (uint64_t)stream_depth) &&
620 (content_len_so_far + (uint64_t)data_len) > stream_depth)
622 chunk_len = (uint32_t)(stream_depth - content_len_so_far);
625 return (chunk_len == 0 ? data_len : chunk_len);
636 static void HTPHandleError(
HtpState *s,
const uint8_t dir)
638 if (s == NULL || s->
conn == NULL) {
642 htp_log_t *log = htp_conn_next_log(s->
conn);
643 while (log != NULL) {
644 char *msg = htp_log_message(log);
647 log = htp_conn_next_log(s->
conn);
653 htp_log_code_t
id = htp_log_code(log);
654 if (
id != HTP_LOG_CODE_UNKNOWN &&
id != HTP_LOG_CODE_ERROR) {
655 HTPSetEvent(s, NULL, dir, (uint8_t)
id);
657 htp_free_cstring(msg);
664 log = htp_conn_next_log(s->
conn);
669 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s,
const htp_tx_t *tx)
672 BUG_ON(s == NULL || tx == NULL);
674 if (htp_tx_flags(tx) & (HTP_FLAGS_REQUEST_INVALID_T_E | HTP_FLAGS_REQUEST_INVALID_C_L |
675 HTP_FLAGS_HOST_MISSING | HTP_FLAGS_HOST_AMBIGUOUS |
676 HTP_FLAGS_HOSTU_INVALID | HTP_FLAGS_HOSTH_INVALID)) {
679 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_T_E)
680 HTPSetEvent(s, htud, STREAM_TOSERVER,
681 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST);
682 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_C_L)
684 s, htud, STREAM_TOSERVER, HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST);
685 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_MISSING)
686 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_MISSING_HOST_HEADER);
687 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_AMBIGUOUS)
688 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HOST_HEADER_AMBIGUOUS);
689 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTU_INVALID)
690 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_URI_HOST_INVALID);
691 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTH_INVALID)
692 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HEADER_HOST_INVALID);
694 if (htp_tx_request_auth_type(tx) == HTP_AUTH_TYPE_UNRECOGNIZED) {
696 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_AUTH_UNRECOGNIZED);
698 if (htp_tx_is_protocol_0_9(tx) && htp_tx_request_method_number(tx) == HTP_METHOD_UNKNOWN &&
699 (htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_INVALID ||
700 htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_UNKNOWN)) {
702 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_REQUEST_LINE_INVALID);
712 htp_cfg_t *htp = cfglist.
cfg;
713 void *user_data = NULL;
729 if (user_data != NULL) {
730 htp_cfg_rec = user_data;
731 htp = htp_cfg_rec->
cfg;
734 SCLogDebug(
"Using default HTP config: %p", htp);
738 #ifdef DEBUG_VALIDATION
745 hstate->
connp = htp_connp_create(htp);
746 if (hstate->
connp == NULL) {
750 hstate->
conn = (htp_conn_t *)htp_connp_connection(hstate->
connp);
752 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
753 hstate->
cfg = htp_cfg_rec;
758 htp_connp_open(hstate->
connp, NULL,
f->
sp, NULL,
f->
dp, &
tv);
790 if (NULL == hstate->
conn) {
791 if (Setup(
f, hstate) != 0) {
796 hstate->
slice = &stream_slice;
798 const uint8_t *input = StreamSliceGetData(&stream_slice);
799 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
804 const int r = htp_connp_request_data(hstate->
connp, &
ts, input, input_len);
806 case HTP_STREAM_STATE_ERROR:
812 HTPHandleError(hstate, STREAM_TOSERVER);
818 htp_connp_request_close(hstate->
connp, &
ts);
820 SCLogDebug(
"stream eof encountered, closing htp handle for ts");
824 hstate->
slice = NULL;
852 const uint8_t *input = StreamSliceGetData(&stream_slice);
853 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
859 if (NULL == hstate->
conn) {
860 if (Setup(
f, hstate) != 0) {
865 hstate->
slice = &stream_slice;
868 const htp_tx_t *tx = NULL;
869 uint32_t consumed = 0;
871 const int r = htp_connp_response_data(hstate->
connp, &
ts, input, input_len);
873 case HTP_STREAM_STATE_ERROR:
876 case HTP_STREAM_STATE_TUNNEL:
877 tx = htp_connp_get_response_tx(hstate->
connp);
878 if (tx != NULL && htp_tx_response_status_number(tx) == 101) {
879 const htp_header_t *h = htp_tx_response_header(tx,
"Upgrade");
884 if (htp_tx_request_port_number(tx) != -1) {
885 dp = (uint16_t)htp_tx_request_port_number(tx);
887 consumed = (uint32_t)htp_connp_response_data_consumed(hstate->
connp);
888 if (bstr_cmp_c(htp_header_value(h),
"h2c") == 0) {
893 hstate->
slice = NULL;
895 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
900 if (consumed > 0 && consumed < input_len) {
904 }
else if (bstr_cmp_c_nocase(htp_header_value(h),
"WebSocket")) {
909 hstate->
slice = NULL;
911 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
916 if (consumed > 0 && consumed < input_len) {
926 HTPHandleError(hstate, STREAM_TOCLIENT);
932 htp_connp_close(hstate->
connp, &
ts);
937 hstate->
slice = NULL;
948 static int HTTPParseContentDispositionHeader(
const uint8_t *
name,
size_t name_len,
949 const uint8_t *data,
size_t len, uint8_t
const **retptr,
size_t *retlen)
952 printf(
"DATA START: \n");
954 printf(
"DATA END: \n");
959 for (x = 0; x <
len; x++) {
960 if (!(isspace(data[x])))
967 const uint8_t *line = data + x;
968 size_t line_len =
len-x;
971 printf(
"LINE START: \n");
973 printf(
"LINE END: \n");
975 for (x = 0 ; x < line_len; x++) {
977 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
981 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
982 const uint8_t *token = line +
offset;
983 size_t token_len = x -
offset;
985 if ((x + 1) == line_len) {
996 printf(
"TOKEN START: \n");
998 printf(
"TOKEN END: \n");
1000 if (token_len > name_len) {
1001 if (
name == NULL || SCMemcmpLowercase(
name, token, name_len) == 0) {
1002 const uint8_t *value = token + name_len;
1003 size_t value_len = token_len - name_len;
1005 if (value[0] ==
'\"') {
1009 if (value[value_len-1] ==
'\"') {
1013 printf(
"VALUE START: \n");
1015 printf(
"VALUE END: \n");
1018 *retlen = value_len;
1042 static int HtpRequestBodySetupMultipart(
const htp_tx_t *tx,
HtpTxUserData *htud)
1044 const htp_header_t *h = htp_tx_request_header(tx,
"Content-Type");
1045 if (h != NULL && htp_header_value_len(h) > 0) {
1047 SCMimeStateInit(htp_header_value_ptr(h), (uint32_t)htp_header_value_len(h));
1064 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1067 chunks_buffer, chunks_buffer_len,
1071 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1075 if (dir == STREAM_TOSERVER) {
1076 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1078 }
else if (dir == STREAM_TOCLIENT) {
1079 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1086 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len,
bool eof)
1089 printf(
"CHUNK START: \n");
1091 printf(
"CHUNK END: \n");
1097 STREAM_TOSERVER) >= HTP_REQUEST_PROGRESS_COMPLETE);
1099 const uint8_t *cur_buf = chunks_buffer;
1100 uint32_t cur_buf_len = chunks_buffer_len;
1116 const uint8_t *filename = NULL;
1117 uint16_t filename_len = 0;
1120 while (cur_buf_len > 0) {
1121 MimeParserResult r =
1122 SCMimeParse(htud->
mime_state, cur_buf, cur_buf_len, &consumed, &warnings);
1126 if (warnings & MIME_EVENT_FLAG_INVALID_HEADER) {
1130 if (warnings & MIME_EVENT_FLAG_NO_FILEDATA) {
1141 SCMimeStateGetFilename(htud->
mime_state, &filename, &filename_len);
1142 if (filename_len > 0) {
1146 hstate, htud, filename, filename_len, NULL, 0, STREAM_TOSERVER);
1149 }
else if (result == -2) {
1152 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1160 }
else if (result == -2) {
1168 uint32_t lastsize = consumed;
1169 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\n') {
1171 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\r') {
1175 HTPFileClose(htud, cur_buf, lastsize, 0, STREAM_TOSERVER);
1180 cur_buf += consumed;
1181 cur_buf_len -= consumed;
1193 const uint8_t *data, uint32_t data_len)
1200 uint8_t *filename = NULL;
1201 size_t filename_len = 0;
1204 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1205 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1206 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1209 if (filename != NULL) {
1215 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1219 }
else if (result == -2) {
1222 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1236 }
else if (result == -2) {
1249 const uint8_t *data, uint32_t data_len)
1266 const uint8_t *filename = NULL;
1267 size_t filename_len = 0;
1270 const htp_header_t *h = htp_tx_response_header(tx,
"Content-Disposition");
1271 if (h != NULL && htp_header_value_len(h) > 0) {
1273 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1274 htp_header_value_ptr(h), htp_header_value_len(h), &filename, &filename_len);
1278 if (filename == NULL) {
1280 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1281 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1282 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1286 if (filename != NULL) {
1288 const htp_header_t *h_content_range = htp_tx_response_header(tx,
"content-range");
1294 if (h_content_range != NULL) {
1296 data_len, tx, htp_header_value(h_content_range), htud);
1298 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1304 }
else if (result == -2) {
1307 FlagDetectStateNewFile(htud, STREAM_TOCLIENT);
1320 }
else if (result == -2) {
1338 static int HTPCallbackRequestBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1342 const htp_tx_t *tx = htp_tx_data_tx(d);
1347 if (htp_tx_data_is_empty(d))
1351 printf(
"HTPBODY START: \n");
1352 PrintRawDataFp(stdout, (uint8_t *)htp_tx_data_data(d), htp_tx_data_len(d));
1353 printf(
"HTPBODY END: \n");
1356 HtpState *hstate = htp_connp_user_data(connp);
1357 if (hstate == NULL) {
1361 SCLogDebug(
"New request body data available at %p -> %p -> %p, bodylen "
1363 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1366 if (tx_ud == NULL) {
1375 if (htp_tx_request_method_number(tx) == HTP_METHOD_POST) {
1377 int r = HtpRequestBodySetupMultipart(tx, tx_ud);
1380 }
else if (r == 0) {
1384 }
else if (htp_tx_request_method_number(tx) == HTP_METHOD_PUT) {
1400 (uint32_t)htp_tx_data_len(d));
1405 const uint8_t *chunks_buffer = NULL;
1406 uint32_t chunks_buffer_len = 0;
1414 HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len);
1415 if (chunks_buffer == NULL) {
1419 printf(
"REASSCHUNK START: \n");
1421 printf(
"REASSCHUNK END: \n");
1424 HtpRequestBodyHandleMultipart(hstate, tx_ud, htp_tx_data_tx(d), chunks_buffer,
1425 chunks_buffer_len, (htp_tx_data_data(d) == NULL && htp_tx_data_len(d) == 0));
1429 HtpRequestBodyHandlePOSTorPUT(
1430 hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1435 SCLogDebug(
"closing file that was being stored");
1442 if (hstate->
conn != NULL) {
1443 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1444 ", last %" PRIu64
")",
1446 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1455 if ((uint64_t)htp_conn_request_data_counter(hstate->
conn) >
1457 (uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1459 (uint64_t)UINT_MAX) {
1460 uint32_t data_size =
1461 (uint32_t)((uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1482 static int HTPCallbackResponseBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1486 const htp_tx_t *tx = htp_tx_data_tx(d);
1491 if (htp_tx_data_is_empty(d))
1494 HtpState *hstate = htp_connp_user_data(connp);
1495 if (hstate == NULL) {
1499 SCLogDebug(
"New response body data available at %p -> %p -> %p, bodylen "
1501 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1521 (uint32_t)htp_tx_data_len(d));
1526 HtpResponseBodyHandle(hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1529 SCLogDebug(
"closing file that was being stored");
1535 if (hstate->
conn != NULL) {
1536 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1537 ", last %" PRIu64
")",
1539 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1547 if ((uint64_t)htp_conn_response_data_counter(hstate->
conn) >
1549 (uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1551 (uint64_t)UINT_MAX) {
1552 uint32_t data_size =
1553 (uint32_t)((uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1577 SCLogDebug(
"http_state_memcnt %"PRIu64
", http_state_memuse %"PRIu64
"",
1578 htp_state_memcnt, htp_state_memuse);
1595 htp_config_destroy(cfglist.
cfg);
1596 while (nextrec != NULL) {
1598 nextrec = nextrec->
next;
1600 htp_config_destroy(htprec->
cfg);
1608 static int HTPCallbackRequestHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1613 return HTP_STATUS_OK;
1616 static int HTPCallbackResponseHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1621 return HTP_STATUS_OK;
1624 static void *HTPCallbackTxCreate(
bool request)
1643 static int HTPCallbackRequestStart(
const htp_connp_t *connp, htp_tx_t *tx)
1645 HtpState *hstate = htp_connp_user_data(connp);
1646 if (hstate == NULL) {
1650 uint64_t consumed = hstate->
slice->
offset + htp_connp_request_data_consumed(hstate->
connp);
1651 SCLogDebug(
"HTTP request start: data offset %" PRIu64
", in_data_counter %" PRIu64, consumed,
1652 (uint64_t)htp_conn_request_data_counter(hstate->
conn));
1676 static int HTPCallbackResponseStart(
const htp_connp_t *connp, htp_tx_t *tx)
1678 HtpState *hstate = htp_connp_user_data(connp);
1679 if (hstate == NULL) {
1683 uint64_t consumed = hstate->
slice->
offset + htp_connp_response_data_consumed(hstate->
connp);
1684 SCLogDebug(
"HTTP response start: data offset %" PRIu64
", out_data_counter %" PRIu64, consumed,
1685 (uint64_t)htp_conn_response_data_counter(hstate->
conn));
1710 static int HTPCallbackRequestComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1718 HtpState *hstate = htp_connp_user_data(connp);
1719 if (hstate == NULL) {
1723 const uint64_t abs_right_edge =
1732 SCLogDebug(
"HTTP request complete: data offset %" PRIu64
", request_size %" PRIu64,
1734 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1736 frame->
len = (int64_t)request_size;
1742 SCLogDebug(
"transaction_cnt %"PRIu64
", list_size %"PRIu64,
1747 HTPErrorCheckTxRequestFlags(hstate, tx);
1752 SCLogDebug(
"closing file that was being stored");
1755 if (abs_right_edge < (uint64_t)UINT32_MAX) {
1757 hstate->
f->
protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
1774 static int HTPCallbackResponseComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1778 HtpState *hstate = htp_connp_user_data(connp);
1779 if (hstate == NULL) {
1786 const uint64_t abs_right_edge =
1794 SCLogDebug(
"HTTP response complete: data offset %" PRIu64
", response_size %" PRIu64,
1796 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1798 frame->
len = (int64_t)response_size;
1806 SCLogDebug(
"closing file that was being stored");
1816 if (htp_tx_request_method_number(tx) == HTP_METHOD_CONNECT) {
1819 if ((htp_tx_response_status_number(tx) >= 200) &&
1820 (htp_tx_response_status_number(tx) < 300) && (hstate->
transaction_cnt == 1)) {
1822 if (htp_tx_request_port_number(tx) != -1) {
1823 dp = (uint16_t)htp_tx_request_port_number(tx);
1837 static int HTPCallbackRequestLine(
const htp_connp_t *connp, htp_tx_t *tx)
1839 HtpState *hstate = htp_connp_user_data(connp);
1841 if (htp_tx_flags(tx)) {
1842 HTPErrorCheckTxRequestFlags(hstate, tx);
1844 return HTP_STATUS_OK;
1847 static int HTPCallbackRequestHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1850 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1851 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1852 return HTP_STATUS_OK;
1858 return HTP_STATUS_OK;
1864 htp_tx_data_len(tx_data));
1867 if (tx && htp_tx_flags(tx)) {
1868 HtpState *hstate = htp_connp_user_data(connp);
1869 HTPErrorCheckTxRequestFlags(hstate, tx);
1871 return HTP_STATUS_OK;
1874 static int HTPCallbackResponseHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1877 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1878 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1879 return HTP_STATUS_OK;
1886 return HTP_STATUS_OK;
1891 htp_tx_data_len(tx_data));
1894 return HTP_STATUS_OK;
1900 static void HTPConfigSetDefaultsPhase1(
HTPCfgRec *cfg_prec)
1902 htp_config_set_normalized_uri_include_all(cfg_prec->
cfg,
false);
1917 htp_config_register_request_header_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1918 htp_config_register_request_trailer_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1919 htp_config_register_response_header_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1920 htp_config_register_response_trailer_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1922 htp_config_register_request_trailer(cfg_prec->
cfg, HTPCallbackRequestHasTrailer);
1923 htp_config_register_response_trailer(cfg_prec->
cfg, HTPCallbackResponseHasTrailer);
1925 htp_config_register_request_body_data(cfg_prec->
cfg, HTPCallbackRequestBodyData);
1926 htp_config_register_response_body_data(cfg_prec->
cfg, HTPCallbackResponseBodyData);
1928 htp_config_register_tx_create(cfg_prec->
cfg, HTPCallbackTxCreate);
1929 htp_config_register_tx_destroy(cfg_prec->
cfg, HtpTxUserDataFree);
1931 htp_config_register_request_start(cfg_prec->
cfg, HTPCallbackRequestStart);
1932 htp_config_register_request_complete(cfg_prec->
cfg, HTPCallbackRequestComplete);
1934 htp_config_register_response_start(cfg_prec->
cfg, HTPCallbackResponseStart);
1935 htp_config_register_response_complete(cfg_prec->
cfg, HTPCallbackResponseComplete);
1937 htp_config_set_parse_request_cookies(cfg_prec->
cfg, 0);
1938 htp_config_set_allow_space_uri(cfg_prec->
cfg, 1);
1941 htp_config_set_plusspace_decode(cfg_prec->
cfg, 0);
1943 htp_config_set_request_decompression(cfg_prec->
cfg, 1);
1948 #define HTP_CONFIG_DEFAULT_MAX_TX_LIMIT 512
1950 #define HTP_CONFIG_DEFAULT_HEADERS_LIMIT 1024
1958 static int RandomGetWrap(
void)
1964 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
1966 return r % RAND_MAX;
1975 static void HTPConfigSetDefaultsPhase2(
const char *
name,
HTPCfgRec *cfg_prec)
1981 long int r = RandomGetWrap();
1983 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
1985 r = RandomGetWrap();
1987 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
1988 SCLogConfig(
"'%s' server has 'request-body-minimal-inspect-size' set to"
1989 " %u and 'request-body-inspect-window' set to %u after"
1993 r = RandomGetWrap();
1995 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
1997 r = RandomGetWrap();
1999 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2001 SCLogConfig(
"'%s' server has 'response-body-minimal-inspect-size' set to"
2002 " %u and 'response-body-inspect-window' set to %u after"
2007 htp_config_register_request_line(cfg_prec->
cfg, HTPCallbackRequestLine);
2010 static void HTPConfigParseParameters(
HTPCfgRec *cfg_prec,
SCConfNode *s,
struct HTPConfigTree *tree)
2012 if (cfg_prec == NULL || s == NULL || tree == NULL)
2019 if (strcasecmp(
"address",
p->name) == 0) {
2025 if (strchr(pval->
val,
':') != NULL) {
2026 SCLogDebug(
"LIBHTP adding ipv6 server %s at %s: %p",
2030 SCLogWarning(
"LIBHTP failed to add ipv6 server %s, ignoring", pval->
val);
2033 SCLogDebug(
"LIBHTP adding ipv4 server %s at %s: %p",
2037 SCLogWarning(
"LIBHTP failed to add ipv4 server %s, ignoring", pval->
val);
2042 }
else if (strcasecmp(
"personality",
p->name) == 0) {
2044 int personality = HTPLookupPersonality(
p->val);
2045 SCLogDebug(
"LIBHTP default: %s = %s",
p->name,
p->val);
2046 SCLogDebug(
"LIBHTP default: %s = %s",
p->name,
p->val);
2048 if (personality >= 0) {
2049 SCLogDebug(
"LIBHTP default: %s=%s (%d)",
p->name,
p->val,
2051 if (htp_config_set_server_personality(cfg_prec->
cfg, personality) ==
2054 "personality \"%s\", ignoring",
2058 HTPLookupPersonalityString(personality));
2064 htp_config_set_convert_lowercase(cfg_prec->
cfg, 0);
2072 }
else if (strcasecmp(
"request-body-limit",
p->name) == 0 ||
2073 strcasecmp(
"request_body_limit",
p->name) == 0) {
2075 SCLogError(
"Error parsing request-body-limit "
2076 "from conf file - %s. Killing engine",
2081 }
else if (strcasecmp(
"response-body-limit",
p->name) == 0) {
2083 SCLogError(
"Error parsing response-body-limit "
2084 "from conf file - %s. Killing engine",
2089 }
else if (strcasecmp(
"request-body-minimal-inspect-size",
p->name) == 0) {
2091 SCLogError(
"Error parsing request-body-minimal-inspect-size "
2092 "from conf file - %s. Killing engine",
2097 }
else if (strcasecmp(
"request-body-inspect-window",
p->name) == 0) {
2099 SCLogError(
"Error parsing request-body-inspect-window "
2100 "from conf file - %s. Killing engine",
2105 }
else if (strcasecmp(
"double-decode-query",
p->name) == 0) {
2107 }
else if (strcasecmp(
"double-decode-path",
p->name) == 0) {
2109 }
else if (strcasecmp(
"response-body-minimal-inspect-size",
p->name) == 0) {
2111 SCLogError(
"Error parsing response-body-minimal-inspect-size "
2112 "from conf file - %s. Killing engine",
2117 }
else if (strcasecmp(
"response-body-inspect-window",
p->name) == 0) {
2119 SCLogError(
"Error parsing response-body-inspect-window "
2120 "from conf file - %s. Killing engine",
2125 }
else if (strcasecmp(
"response-body-decompress-layer-limit",
p->name) == 0) {
2128 SCLogError(
"Error parsing response-body-inspect-window "
2129 "from conf file - %s. Killing engine",
2133 htp_config_set_decompression_layer_limit(cfg_prec->
cfg, value);
2134 }
else if (strcasecmp(
"path-convert-backslash-separators",
p->name) == 0) {
2136 }
else if (strcasecmp(
"path-bestfit-replacement-char",
p->name) == 0) {
2137 if (strlen(
p->val) == 1) {
2138 htp_config_set_bestfit_replacement_byte(cfg_prec->
cfg,
p->val[0]);
2141 "for libhtp param path-bestfit-replacement-char");
2143 }
else if (strcasecmp(
"path-convert-lowercase",
p->name) == 0) {
2145 }
else if (strcasecmp(
"path-nul-encoded-terminates",
p->name) == 0) {
2147 }
else if (strcasecmp(
"path-nul-raw-terminates",
p->name) == 0) {
2149 }
else if (strcasecmp(
"path-separators-compress",
p->name) == 0) {
2151 }
else if (strcasecmp(
"path-separators-decode",
p->name) == 0) {
2153 }
else if (strcasecmp(
"path-u-encoding-decode",
p->name) == 0) {
2155 }
else if (strcasecmp(
"path-url-encoding-invalid-handling",
p->name) == 0) {
2156 enum htp_url_encoding_handling_t handling;
2157 if (strcasecmp(
p->val,
"preserve_percent") == 0) {
2158 handling = HTP_URL_ENCODING_HANDLING_PRESERVE_PERCENT;
2159 }
else if (strcasecmp(
p->val,
"remove_percent") == 0) {
2160 handling = HTP_URL_ENCODING_HANDLING_REMOVE_PERCENT;
2161 }
else if (strcasecmp(
p->val,
"decode_invalid") == 0) {
2162 handling = HTP_URL_ENCODING_HANDLING_PROCESS_INVALID;
2165 "for libhtp param path-url-encoding-invalid-handling");
2168 htp_config_set_url_encoding_invalid_handling(cfg_prec->
cfg, handling);
2169 }
else if (strcasecmp(
"path-utf8-convert-bestfit",
p->name) == 0) {
2171 }
else if (strcasecmp(
"uri-include-all",
p->name) == 0) {
2174 }
else if (strcasecmp(
"query-plusspace-decode",
p->name) == 0) {
2176 }
else if (strcasecmp(
"meta-field-limit",
p->name) == 0) {
2180 "from conf file - %s. Killing engine",
2186 "from conf file cannot be 0. Killing engine");
2189 htp_config_set_field_limit(cfg_prec->
cfg, (
size_t)limit);
2190 }
else if (strcasecmp(
"lzma-memlimit",
p->name) == 0) {
2193 FatalError(
"failed to parse 'lzma-memlimit' "
2194 "from conf file - %s.",
2199 "from conf file cannot be 0.");
2202 SCLogConfig(
"Setting HTTP LZMA memory limit to %"PRIu32
" bytes", limit);
2203 htp_config_set_lzma_memlimit(cfg_prec->
cfg, (
size_t)limit);
2204 }
else if (strcasecmp(
"lzma-enabled",
p->name) == 0) {
2206 htp_config_set_lzma_layers(cfg_prec->
cfg, 1);
2211 "from conf file - %s.",
2214 SCLogConfig(
"Setting HTTP LZMA decompression layers to %" PRIu32
"", (
int)limit);
2215 htp_config_set_lzma_layers(cfg_prec->
cfg, limit);
2217 }
else if (strcasecmp(
"compression-bomb-count",
p->name) == 0) {
2220 FatalError(
"failed to parse 'compression-bomb-count' "
2221 "from conf file - %s.",
2226 "from conf file cannot be 0.");
2229 SCLogConfig(
"Setting HTTP compression bomb count limit to %" PRIu8, limit);
2230 htp_config_set_max_nb_compression_bombs(cfg_prec->
cfg, (
size_t)limit);
2231 }
else if (strcasecmp(
"compression-bomb-limit",
p->name) == 0) {
2234 FatalError(
"failed to parse 'compression-bomb-limit' "
2235 "from conf file - %s.",
2240 "from conf file cannot be 0.");
2243 SCLogConfig(
"Setting HTTP compression bomb limit to %"PRIu32
" bytes", limit);
2244 htp_config_set_compression_bomb_limit(cfg_prec->
cfg, (
size_t)limit);
2245 }
else if (strcasecmp(
"decompression-time-limit",
p->name) == 0) {
2249 FatalError(
"failed to parse 'decompression-time-limit' "
2250 "from conf file - %s.",
2253 SCLogConfig(
"Setting HTTP decompression time limit to %" PRIu32
" usec", limit);
2254 htp_config_set_compression_time_limit(cfg_prec->
cfg, limit);
2255 }
else if (strcasecmp(
"max-tx",
p->name) == 0) {
2259 "from conf file - %s.",
2263 SCLogConfig(
"Setting HTTP max-tx limit to %" PRIu32
" bytes", limit);
2264 htp_config_set_max_tx(cfg_prec->
cfg, limit);
2265 }
else if (strcasecmp(
"headers-limit",
p->name) == 0) {
2268 FatalError(
"failed to parse 'headers-limit' "
2269 "from conf file - %s.",
2272 SCLogConfig(
"Setting HTTP headers limit to %" PRIu32, limit);
2273 htp_config_set_number_headers_limit(cfg_prec->
cfg, limit);
2274 }
else if (strcasecmp(
"randomize-inspection-sizes",
p->name) == 0) {
2278 }
else if (strcasecmp(
"randomize-inspection-range",
p->name) == 0) {
2281 (
const char *)
p->val, 0, 100) < 0) {
2283 "-inspection-range setting from conf file - \"%s\"."
2284 " It should be a valid integer less than or equal to 100."
2290 }
else if (strcasecmp(
"http-body-inline",
p->name) == 0) {
2296 if (strcmp(
"auto",
p->val) != 0) {
2305 }
else if (strcasecmp(
"swf-decompression",
p->name) == 0) {
2309 if (strcasecmp(
"enabled", pval->
name) == 0) {
2317 }
else if (strcasecmp(
"type", pval->
name) == 0) {
2318 if (strcasecmp(
"no", pval->
val) == 0) {
2320 }
else if (strcasecmp(
"deflate", pval->
val) == 0) {
2322 }
else if (strcasecmp(
"lzma", pval->
val) == 0) {
2324 }
else if (strcasecmp(
"both", pval->
val) == 0) {
2328 "swf-decompression.type: %s - "
2333 }
else if (strcasecmp(
"compress-depth", pval->
name) == 0) {
2336 SCLogError(
"Invalid swf-decompression.compress-depth value %s: the "
2337 "maximum is %u bytes. Killing engine",
2341 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2344 SCLogError(
"Invalid swf-decompression.decompress-depth value %s: the "
2345 "maximum is %u bytes. Killing engine",
2355 "default config: %s",
2365 cfglist.
next = NULL;
2372 cfglist.
cfg = htp_config_create();
2373 if (NULL == cfglist.
cfg) {
2374 FatalError(
"Failed to create HTP default config");
2377 HTPConfigSetDefaultsPhase1(&cfglist);
2378 if (
SCConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2379 HTPConfigParseParameters(&cfglist,
SCConfGetNode(
"libhtp.default-config"), &cfgtree);
2381 HTPConfigParseParameters(&cfglist,
2382 SCConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), &cfgtree);
2384 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2390 if (server_config == NULL) {
2392 if (server_config == NULL) {
2393 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2397 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2416 cfglist.
next = htprec;
2419 cfglist.
next->
cfg = htp_config_create();
2420 if (NULL == cfglist.
next->
cfg) {
2421 FatalError(
"Failed to create HTP server config");
2424 HTPConfigSetDefaultsPhase1(htprec);
2425 HTPConfigParseParameters(htprec, s, &cfgtree);
2426 HTPConfigSetDefaultsPhase2(s->
name, htprec);
2436 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
2450 htp_tx_t *tx = (htp_tx_t *)txv;
2452 if (direction & STREAM_TOCLIENT) {
2460 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
2462 if (direction & STREAM_TOSERVER)
2463 return htp_tx_request_progress((htp_tx_t *)tx);
2465 return htp_tx_response_progress((htp_tx_t *)tx);
2468 static uint64_t HTPStateGetTxCnt(
void *alstate)
2472 if (http_state != NULL && http_state->
connp != NULL) {
2473 const int64_t size = htp_connp_tx_size(http_state->
connp);
2477 return (uint64_t)size;
2483 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
2487 if (http_state != NULL && http_state->
connp != NULL)
2488 return (
void *)htp_connp_tx(http_state->
connp, tx_id);
2497 uint64_t size = HTPStateGetTxCnt(alstate);
2500 while (state->
un.
u64 < size) {
2501 htp_tx_t *tx = htp_connp_tx_index(http_state->
connp, state->
un.
u64);
2505 uint64_t tx_id = htp_tx_index(tx);
2506 if (tx_id < min_tx_id) {
2513 .has_next = (tx_id + 1) < size,
2525 if (http_state != NULL && http_state->
connp != NULL) {
2526 size_t txid = htp_connp_tx_size(http_state->
connp);
2528 return (
void *)htp_connp_tx(http_state->
connp, txid - 1);
2534 static int HTPStateGetEventInfo(
2544 static int HTPStateGetEventInfoById(
2548 if (*event_name == NULL) {
2550 "http's enum map table.",
2563 htp_tx_t *tx = (htp_tx_t *)vtx;
2574 static int HTPRegisterPatternsForProtocolDetection(
void)
2576 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
2577 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
2578 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
2579 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
2580 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
2581 const char *spacings[] = {
"|20|",
"|09|", NULL };
2582 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
2587 int register_result;
2588 char method_buffer[32] =
"";
2591 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
2592 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
2595 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
2602 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
2603 if (register_result < 0) {
2610 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
2612 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
2614 if (register_result < 0) {
2630 const char *proto_name =
"http";
2635 if (HTPRegisterPatternsForProtocolDetection() < 0)
2638 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
2653 ALPROTO_HTTP1, HTP_REQUEST_PROGRESS_COMPLETE, HTP_RESPONSE_PROGRESS_COMPLETE);
2665 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
2667 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
2671 IPPROTO_TCP,
ALPROTO_HTTP1, APP_LAYER_PARSER_OPT_ACCEPT_GAPS);
2673 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
2676 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
2679 IPPROTO_TCP,
ALPROTO_HTTP1, HtpStateGetStateIdByName, HtpStateGetStateNameById);
2683 SCLogInfo(
"Parser disabled for %s protocol. Protocol detection still on.", proto_name);
2708 cfglist_backup = cfglist;
2713 cfglist = cfglist_backup;
2718 static int HTPParserTest01(
void)
2720 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2722 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2725 memset(&
ssn, 0,
sizeof(
ssn));
2739 for (u = 0; u < httplen1; u++) {
2743 flags = STREAM_TOSERVER|STREAM_START;
2744 else if (u == (httplen1 - 1))
2745 flags = STREAM_TOSERVER|STREAM_EOF;
2747 flags = STREAM_TOSERVER;
2756 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2759 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2762 FAIL_IF(bstr_cmp_c(htp_header_value(h),
"Victor/1.0"));
2763 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2764 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2773 static int HTPParserTest01b(
void)
2775 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2777 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2780 memset(&
ssn, 0,
sizeof(
ssn));
2793 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
2800 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2803 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2806 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2807 FAIL_IF(strcmp(v,
"Victor/1.0"));
2809 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2810 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2819 static int HTPParserTest01c(
void)
2821 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2823 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2826 memset(&
ssn, 0,
sizeof(
ssn));
2840 for (u = 0; u < httplen1; u++) {
2844 flags = STREAM_TOSERVER|STREAM_START;
2845 else if (u == (httplen1 - 1))
2846 flags = STREAM_TOSERVER|STREAM_EOF;
2848 flags = STREAM_TOSERVER;
2857 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2860 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2863 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2864 FAIL_IF(strcmp(v,
"Victor/1.0"));
2866 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2867 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2877 static int HTPParserTest01a(
void)
2880 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2882 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2887 memset(&
ssn, 0,
sizeof(
ssn));
2898 for (u = 0; u < httplen1; u++) {
2902 flags = STREAM_TOSERVER|STREAM_START;
2903 else if (u == (httplen1 - 1))
2904 flags = STREAM_TOSERVER|STREAM_EOF;
2906 flags = STREAM_TOSERVER;
2915 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2918 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2921 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2922 FAIL_IF(strcmp(v,
"Victor/1.0"));
2924 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2925 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2934 static int HTPParserTest02(
void)
2937 uint8_t httpbuf1[] =
"POST";
2938 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2943 memset(&
ssn, 0,
sizeof(
ssn));
2954 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
2960 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
2962 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2966 char *method = bstr_util_strdup_to_c(htp_tx_request_method(tx));
2969 FAIL_IF(strcmp(method,
"POST") != 0);
2980 static int HTPParserTest03(
void)
2983 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
2984 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2989 memset(&
ssn, 0,
sizeof(
ssn));
3000 for (u = 0; u < httplen1; u++) {
3003 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3004 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3005 else flags = STREAM_TOSERVER;
3013 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3016 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3018 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3019 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
3029 static int HTPParserTest04(
void)
3033 uint8_t httpbuf1[] =
"World!\r\n";
3034 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3038 memset(&
ssn, 0,
sizeof(
ssn));
3049 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3055 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3057 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3059 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3060 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V0_9);
3070 static int HTPParserTest05(
void)
3072 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3073 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3074 uint8_t httpbuf2[] =
"Post D";
3075 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3076 uint8_t httpbuf3[] =
"ata is c0oL!";
3077 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3079 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3080 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3081 uint8_t httpbuf5[] =
"post R";
3082 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3083 uint8_t httpbuf6[] =
"esults are tha bomb!";
3084 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3087 memset(&
ssn, 0,
sizeof(
ssn));
3125 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3127 FAIL_IF_NOT(htp_tx_request_method_number(tx) == HTP_METHOD_POST);
3128 FAIL_IF_NOT(htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_V1_0);
3130 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3133 FAIL_IF_NOT(htp_tx_response_status_number(tx) == 200);
3143 static int HTPParserTest06(
void)
3145 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3146 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3147 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3148 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3149 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3151 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3152 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3153 "FrontPage/5.0.2.2510\r\n"
3154 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3156 "Content-Type: text/html\r\n\r\n"
3158 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3159 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3160 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3161 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3162 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3163 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3164 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3165 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3166 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3167 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3168 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3169 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3170 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3171 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3172 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3173 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3174 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3175 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3176 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3177 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3178 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3179 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3180 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3181 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3182 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3183 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3184 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3185 "aHA=\r\n0\r\n\r\n";
3186 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3192 memset(&
ssn, 0,
sizeof(
ssn));
3212 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3215 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
3216 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3218 FAIL_IF(htp_tx_response_status_number(tx) != 200);
3219 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3221 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3232 static int HTPParserTest07(
void)
3235 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3236 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3241 memset(&
ssn, 0,
sizeof(
ssn));
3252 for (u = 0; u < httplen1; u++) {
3256 flags = STREAM_TOSERVER|STREAM_START;
3257 else if (u == (httplen1 - 1))
3258 flags = STREAM_TOSERVER|STREAM_EOF;
3260 flags = STREAM_TOSERVER;
3269 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3270 size_t reflen =
sizeof(ref) - 1;
3272 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3274 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3276 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3278 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref, bstr_len(request_uri_normalized)) != 0);
3290 static int HTPParserTest08(
void)
3293 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3294 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3315 memset(&
ssn, 0,
sizeof(
ssn));
3325 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3333 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3335 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3337 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3351 static int HTPParserTest09(
void)
3354 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3355 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3365 personality: Apache_2_2\n\
3377 memset(&
ssn, 0,
sizeof(
ssn));
3387 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3395 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3397 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3399 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3413 static int HTPParserTest10(
void)
3417 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3418 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3423 memset(&
ssn, 0,
sizeof(
ssn));
3434 for (u = 0; u < httplen1; u++) {
3438 flags = STREAM_TOSERVER|STREAM_START;
3439 else if (u == (httplen1 - 1))
3440 flags = STREAM_TOSERVER|STREAM_EOF;
3442 flags = STREAM_TOSERVER;
3451 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3452 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3455 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3459 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3461 FAIL_IF(strcmp(value,
"www.google.com") != 0);
3473 static int HTPParserTest11(
void)
3476 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3477 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3482 memset(&
ssn, 0,
sizeof(
ssn));
3493 for (u = 0; u < httplen1; u++) {
3497 flags = STREAM_TOSERVER|STREAM_START;
3498 else if (u == (httplen1 - 1))
3499 flags = STREAM_TOSERVER|STREAM_EOF;
3501 flags = STREAM_TOSERVER;
3510 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3512 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3515 FAIL_IF(bstr_len(request_uri_normalized) != 4);
3516 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3517 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'%');
3518 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'0');
3519 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'0');
3529 static int HTPParserTest12(
void)
3532 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3533 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3538 memset(&
ssn, 0,
sizeof(
ssn));
3549 for (u = 0; u < httplen1; u++) {
3553 flags = STREAM_TOSERVER|STREAM_START;
3554 else if (u == (httplen1 - 1))
3555 flags = STREAM_TOSERVER|STREAM_EOF;
3557 flags = STREAM_TOSERVER;
3566 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3568 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3571 FAIL_IF(bstr_len(request_uri_normalized) != 7);
3572 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3573 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'?');
3574 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'a');
3575 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'=');
3576 FAIL_IF(bstr_ptr(request_uri_normalized)[4] !=
'%');
3577 FAIL_IF(bstr_ptr(request_uri_normalized)[5] !=
'0');
3578 FAIL_IF(bstr_ptr(request_uri_normalized)[6] !=
'0');
3588 static int HTPParserTest13(
void)
3591 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3592 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3597 memset(&
ssn, 0,
sizeof(
ssn));
3608 for (u = 0; u < httplen1; u++) {
3612 flags = STREAM_TOSERVER|STREAM_START;
3613 else if (u == (httplen1 - 1))
3614 flags = STREAM_TOSERVER|STREAM_EOF;
3616 flags = STREAM_TOSERVER;
3624 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3625 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3628 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3632 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3634 FAIL_IF(strcmp(value,
"www.google.com\rName: Value") != 0);
3646 static int HTPParserConfigTest01(
void)
3659 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3660 personality: Tomcat_6_0\n\
3665 - 192.168.10.0/24\n\
3666 personality: IIS_7_0\n\
3675 outputs =
SCConfGetNode(
"libhtp.default-config.personality");
3686 FAIL_IF(strcmp(node->
name,
"apache-tomcat") != 0);
3693 FAIL_IF(strcmp(node2->
val,
"Tomcat_6_0") != 0);
3703 FAIL_IF(strcmp(n->
val,
"192.168.1.0/24") != 0);
3743 FAIL_IF(strcmp(n->
val,
"192.168.0.0/24") != 0);
3747 FAIL_IF(strcmp(n->
val,
"192.168.10.0/24") != 0);
3762 static int HTPParserConfigTest02(
void)
3775 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3776 personality: Tomcat_6_0\n\
3781 - 192.168.10.0/24\n\
3782 personality: IIS_7_0\n\
3794 htp_cfg_t *htp = cfglist.
cfg;
3797 void *user_data = NULL;
3799 addr =
"192.168.10.42";
3800 FAIL_IF(inet_pton(AF_INET, addr, buf) != 1);
3804 htp = htp_cfg_rec->
cfg;
3810 FAIL_IF(inet_pton(AF_INET6, addr, buf) != 1);
3813 htp_cfg_rec = user_data;
3814 htp = htp_cfg_rec->
cfg;
3827 static int HTPParserConfigTest03(
void)
3830 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3832 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3848 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3849 personality: Tomcat_6_0\n\
3854 - 192.168.10.0/24\n\
3855 personality: IIS_7_0\n\
3866 const char *addr =
"192.168.10.42";
3868 memset(&
ssn, 0,
sizeof(
ssn));
3876 htp_cfg_t *htp = cfglist.
cfg;
3879 void *user_data = NULL;
3884 htp = htp_cfg_rec->
cfg;
3891 for (u = 0; u < httplen1; u++) {
3894 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3895 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3896 else flags = STREAM_TOSERVER;
3905 FAIL_IF(HTPStateGetTxCnt(htp_state) != 2);
3907 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3909 tx = HTPStateGetTx(htp_state, 1);
3928 static int HTPParserDecodingTest01(
void)
3930 uint8_t httpbuf1[] =
3931 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3932 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3933 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
3934 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3945 personality: Apache_2\n\
3953 const char *addr =
"4.3.2.1";
3954 memset(&
ssn, 0,
sizeof(
ssn));
3964 for (uint32_t u = 0; u < httplen1; u++) {
3966 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3967 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3968 else flags = STREAM_TOSERVER;
3977 uint8_t ref1[] =
"/abc%2fdef";
3978 size_t reflen =
sizeof(ref1) - 1;
3980 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3984 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3987 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3988 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
3990 uint8_t ref2[] =
"/abc/def?ghi/jkl";
3991 reflen =
sizeof(ref2) - 1;
3993 tx = HTPStateGetTx(htp_state, 1);
3997 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4000 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4001 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4003 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4004 reflen =
sizeof(ref3) - 1;
4005 tx = HTPStateGetTx(htp_state, 2);
4009 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4012 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4013 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4025 static int HTPParserDecodingTest01a(
void)
4027 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4028 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4029 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4030 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4041 personality: Apache_2\n\
4049 const char *addr =
"4.3.2.1";
4050 memset(&
ssn, 0,
sizeof(
ssn));
4061 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4067 uint8_t ref1[] =
"/abc%2fdef";
4068 size_t reflen =
sizeof(ref1) - 1;
4070 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4074 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4077 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4078 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4080 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4081 reflen =
sizeof(ref2) - 1;
4083 tx = HTPStateGetTx(htp_state, 1);
4086 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4089 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4091 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4093 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4094 reflen =
sizeof(ref3) - 1;
4095 tx = HTPStateGetTx(htp_state, 2);
4098 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4101 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4103 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4121 static int HTPParserDecodingTest02(
void)
4124 uint8_t httpbuf1[] =
4125 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4126 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4127 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4128 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4140 double-decode-path: no\n\
4141 double-decode-query: no\n\
4149 const char *addr =
"4.3.2.1";
4150 memset(&
ssn, 0,
sizeof(
ssn));
4161 for (u = 0; u < httplen1; u++) {
4164 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4165 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4166 else flags = STREAM_TOSERVER;
4175 uint8_t ref1[] =
"/abc/def";
4176 size_t reflen =
sizeof(ref1) - 1;
4178 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4180 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4182 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4183 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4185 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4186 reflen =
sizeof(ref2) - 1;
4188 tx = HTPStateGetTx(htp_state, 1);
4190 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4192 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4194 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4196 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4197 reflen =
sizeof(ref3) - 1;
4198 tx = HTPStateGetTx(htp_state, 2);
4200 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4202 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4204 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4221 static int HTPParserDecodingTest03(
void)
4224 uint8_t httpbuf1[] =
4225 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4226 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4227 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4239 double-decode-path: yes\n\
4240 double-decode-query: yes\n\
4248 const char *addr =
"4.3.2.1";
4249 memset(&
ssn, 0,
sizeof(
ssn));
4260 for (u = 0; u < httplen1; u++) {
4263 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4264 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4265 else flags = STREAM_TOSERVER;
4274 uint8_t ref1[] =
"/abc/def";
4275 size_t reflen =
sizeof(ref1) - 1;
4277 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4279 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4281 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4283 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4285 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4286 reflen =
sizeof(ref2) - 1;
4288 tx = HTPStateGetTx(htp_state, 1);
4290 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4292 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4294 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4308 static int HTPParserDecodingTest04(
void)
4311 uint8_t httpbuf1[] =
4312 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4313 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4325 double-decode-path: yes\n\
4326 double-decode-query: yes\n\
4334 const char *addr =
"4.3.2.1";
4335 memset(&
ssn, 0,
sizeof(
ssn));
4346 for (u = 0; u < httplen1; u++) {
4349 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4350 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4351 else flags = STREAM_TOSERVER;
4360 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
4361 size_t reflen =
sizeof(ref1) - 1;
4363 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4365 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4367 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4369 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4383 static int HTPParserDecodingTest05(
void)
4386 uint8_t httpbuf1[] =
4387 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4388 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4400 double-decode-path: yes\n\
4401 double-decode-query: yes\n\
4409 const char *addr =
"4.3.2.1";
4410 memset(&
ssn, 0,
sizeof(
ssn));
4421 for (u = 0; u < httplen1; u++) {
4424 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4425 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4426 else flags = STREAM_TOSERVER;
4435 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
4436 size_t reflen =
sizeof(ref1) - 1;
4438 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4440 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4442 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4444 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4458 static int HTPParserDecodingTest06(
void)
4461 uint8_t httpbuf1[] =
4462 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4463 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4475 double-decode-path: yes\n\
4476 double-decode-query: yes\n\
4484 const char *addr =
"4.3.2.1";
4485 memset(&
ssn, 0,
sizeof(
ssn));
4496 for (u = 0; u < httplen1; u++) {
4499 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4500 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4501 else flags = STREAM_TOSERVER;
4510 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
4511 size_t reflen =
sizeof(ref1) - 1;
4513 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4515 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4517 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4519 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4533 static int HTPParserDecodingTest07(
void)
4536 uint8_t httpbuf1[] =
4537 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4538 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4550 double-decode-path: yes\n\
4551 double-decode-query: yes\n\
4552 query-plusspace-decode: yes\n\
4560 const char *addr =
"4.3.2.1";
4561 memset(&
ssn, 0,
sizeof(
ssn));
4572 for (u = 0; u < httplen1; u++) {
4575 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4576 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4577 else flags = STREAM_TOSERVER;
4586 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
4587 size_t reflen =
sizeof(ref1) - 1;
4589 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4591 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4593 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4595 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4609 static int HTPParserDecodingTest08(
void)
4612 uint8_t httpbuf1[] =
4613 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4614 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4633 const char *addr =
"4.3.2.1";
4634 memset(&
ssn, 0,
sizeof(
ssn));
4645 for (u = 0; u < httplen1; u++) {
4648 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4649 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4650 else flags = STREAM_TOSERVER;
4659 uint8_t ref1[] =
"/blah/";
4660 size_t reflen =
sizeof(ref1) - 1;
4662 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4664 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4666 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4668 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4682 static int HTPParserDecodingTest09(
void)
4685 uint8_t httpbuf1[] =
4686 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4687 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4699 uri-include-all: true\n\
4707 const char *addr =
"4.3.2.1";
4708 memset(&
ssn, 0,
sizeof(
ssn));
4719 for (u = 0; u < httplen1; u++) {
4722 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4723 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4724 else flags = STREAM_TOSERVER;
4733 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
4734 size_t reflen =
sizeof(ref1) - 1;
4736 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4738 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4740 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4742 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4755 static int HTPBodyReassemblyTest01(
void)
4760 memset(&hstate, 0x00,
sizeof(hstate));
4762 memset(&flow, 0x00,
sizeof(flow));
4764 htp_cfg_t *cfg = htp_config_create();
4766 htp_connp_t *connp = htp_connp_create(cfg);
4768 const htp_tx_t *tx = htp_connp_get_request_tx(connp);
4774 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
4775 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";
4782 const uint8_t *chunks_buffer = NULL;
4783 uint32_t chunks_buffer_len = 0;
4785 HtpRequestBodyReassemble(htud, &chunks_buffer, &chunks_buffer_len);
4788 printf(
"REASSCHUNK START: \n");
4790 printf(
"REASSCHUNK END: \n");
4793 htud->
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
4794 strlen(
"multipart/form-data; boundary=toto"));
4797 HtpRequestBodyHandleMultipart(&hstate, htud, &tx, chunks_buffer, chunks_buffer_len,
false);
4803 htp_connp_destroy_all(connp);
4804 HtpTxUserDataFree(htud);
4806 htp_config_destroy(cfg);
4811 static int HTPSegvTest01(
void)
4814 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";
4815 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4823 double-decode-path: no\n\
4824 double-decode-query: no\n\
4825 request-body-limit: 0\n\
4826 response-body-limit: 0\n\
4839 memset(&
ssn, 0,
sizeof(
ssn));
4849 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
4853 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
4874 static int HTPParserTest14(
void)
4885 double-decode-path: no\n\
4886 double-decode-query: no\n\
4887 request-body-limit: 0\n\
4888 response-body-limit: 0\n\
4893 memset(&
ssn, 0,
sizeof(
ssn));
4903 memset(httpbuf, 0x00,
len);
4906 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4907 "Host: myhost.lan\r\n"
4908 "Connection: keep-alive\r\n"
4910 "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"
4911 "Referer: http://blah.lan/\r\n"
4912 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
4914 size_t o = strlen(httpbuf);
4915 for ( ; o <
len - 4; o++) {
4918 httpbuf[
len - 4] =
'\r';
4919 httpbuf[
len - 3] =
'\n';
4920 httpbuf[
len - 2] =
'\r';
4921 httpbuf[
len - 1] =
'\n';
4932 for (u = 0; u <
len; u++) {
4935 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4936 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4937 else flags = STREAM_TOSERVER;
4945 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4947 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
4948 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
4955 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG);
4970 static int HTPParserTest15(
void)
4973 char *httpbuf = NULL;
4984 double-decode-path: no\n\
4985 double-decode-query: no\n\
4986 request-body-limit: 0\n\
4987 response-body-limit: 0\n\
4988 meta-field-limit: 20000\n\
4992 memset(&
ssn, 0,
sizeof(
ssn));
5003 memset(httpbuf, 0x00,
len);
5006 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5007 "Host: myhost.lan\r\n"
5008 "Connection: keep-alive\r\n"
5010 "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"
5011 "Referer: http://blah.lan/\r\n"
5012 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5014 size_t o = strlen(httpbuf);
5015 for ( ; o <
len - 4; o++) {
5018 httpbuf[
len - 4] =
'\r';
5019 httpbuf[
len - 3] =
'\n';
5020 httpbuf[
len - 2] =
'\r';
5021 httpbuf[
len - 1] =
'\n';
5032 for (u = 0; u <
len; u++) {
5035 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5036 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5037 else flags = STREAM_TOSERVER;
5046 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5048 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5049 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5068 static int HTPParserTest16(
void)
5075 memset(&
ssn, 0,
sizeof(
ssn));
5077 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5078 "Host: myhost.lan\r\n"
5079 "Connection: keep-alive\r\n"
5081 "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"
5082 "Referer: http://blah.lan/\r\n"
5083 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5084 "Cookie: blah\r\n\r\n";
5085 size_t len =
sizeof(httpbuf) - 1;
5095 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5103 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5105 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5106 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5108 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5115 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT);
5116 FAIL_IF(decoder_events->
events[1] != HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT);
5127 static int HTPParserTest20(
void)
5130 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5131 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5132 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5133 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5134 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
5135 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5136 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5137 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5143 memset(&
ssn, 0,
sizeof(
ssn));
5167 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5169 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5172 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5173 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5175 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5176 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5186 static int HTPParserTest21(
void)
5189 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5190 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5191 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5192 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5193 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
5194 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5195 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5196 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5202 memset(&
ssn, 0,
sizeof(
ssn));
5226 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5228 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5231 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5232 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5234 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5235 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5245 static int HTPParserTest22(
void)
5248 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5249 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5250 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5251 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5252 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
5253 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5254 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5260 memset(&
ssn, 0,
sizeof(
ssn));
5280 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5282 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5285 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5286 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5288 FAIL_IF(htp_tx_response_status_number(tx) != -0);
5289 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5299 static int HTPParserTest23(
void)
5302 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5303 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5304 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5305 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5306 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
5307 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5308 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5314 memset(&
ssn, 0,
sizeof(
ssn));
5334 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5336 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5339 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5340 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5342 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5343 FAIL_IF(htp_tx_response_protocol_number(tx) != -2);
5354 static int HTPParserTest24(
void)
5357 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5358 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5359 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5360 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5361 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
5362 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5363 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5369 memset(&
ssn, 0,
sizeof(
ssn));
5389 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5391 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5394 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5395 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5397 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5398 FAIL_IF(htp_tx_response_protocol_number(tx) != HTP_PROTOCOL_V1_0);
5408 static int HTPParserTest25(
void)
5415 memset(&
ssn, 0,
sizeof(
ssn));
5424 const char *
str =
"GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
5426 (uint8_t *)
str, strlen(
str));
5450 str =
"HTTP 1.1 200 OK\r\nServer: Suricata/1.0\r\nContent-Length: 8\r\n\r\nSuricata";
5452 (uint8_t *)
str, strlen(
str));
5486 (uint8_t *)
str, strlen(
str));
5497 (uint8_t *)
str, strlen(
str));
5518 static int HTPParserTest26(
void)
5527 request-body-limit: 1\n\
5528 response-body-limit: 1\n\
5542 uint8_t httpbuf1[] =
"GET /alice.txt HTTP/1.1\r\n\r\n";
5543 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5544 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\n"
5545 "Content-Type: text/plain\r\n"
5546 "Content-Length: 228\r\n\r\n"
5547 "Alice was beginning to get very tired of sitting by her sister on the bank."
5548 "Alice was beginning to get very tired of sitting by her sister on the bank.";
5549 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5550 uint8_t httpbuf3[] =
"Alice was beginning to get very tired of sitting by her sister on the bank.\r\n\r\n";
5551 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5559 memset(&
f, 0,
sizeof(
f));
5560 memset(&
ssn, 0,
sizeof(
ssn));
5588 "(filestore; sid:1; rev:1;)");
5657 static int HTPParserTest27(
void)
5660 memset(&cfg, 0,
sizeof(cfg));
5664 uint32_t
len = 1000;
5689 static void HTPParserRegisterTests(
void)
5711 UtRegisterTest(
"HTPParserDecodingTest01", HTPParserDecodingTest01);
5712 UtRegisterTest(
"HTPParserDecodingTest01a", HTPParserDecodingTest01a);
5713 UtRegisterTest(
"HTPParserDecodingTest02", HTPParserDecodingTest02);
5714 UtRegisterTest(
"HTPParserDecodingTest03", HTPParserDecodingTest03);
5715 UtRegisterTest(
"HTPParserDecodingTest04", HTPParserDecodingTest04);
5716 UtRegisterTest(
"HTPParserDecodingTest05", HTPParserDecodingTest05);
5717 UtRegisterTest(
"HTPParserDecodingTest06", HTPParserDecodingTest06);
5718 UtRegisterTest(
"HTPParserDecodingTest07", HTPParserDecodingTest07);
5719 UtRegisterTest(
"HTPParserDecodingTest08", HTPParserDecodingTest08);
5720 UtRegisterTest(
"HTPParserDecodingTest09", HTPParserDecodingTest09);
5722 UtRegisterTest(
"HTPBodyReassemblyTest01", HTPBodyReassemblyTest01);