79 static struct HTPConfigTree {
95 #define HTP_MAX_MESSAGES 512
101 static uint64_t htp_state_memuse = 0;
102 static uint64_t htp_state_memcnt = 0;
106 {
"UNKNOWN_ERROR", HTP_LOG_CODE_UNKNOWN },
107 {
"GZIP_DECOMPRESSION_FAILED", HTP_LOG_CODE_GZIP_DECOMPRESSION_FAILED },
108 {
"REQUEST_FIELD_MISSING_COLON", HTP_LOG_CODE_REQUEST_FIELD_MISSING_COLON },
109 {
"RESPONSE_FIELD_MISSING_COLON", HTP_LOG_CODE_RESPONSE_FIELD_MISSING_COLON },
110 {
"INVALID_REQUEST_CHUNK_LEN", HTP_LOG_CODE_INVALID_REQUEST_CHUNK_LEN },
111 {
"INVALID_RESPONSE_CHUNK_LEN", HTP_LOG_CODE_INVALID_RESPONSE_CHUNK_LEN },
112 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST",
113 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST },
114 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE",
115 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE },
116 {
"INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST",
117 HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST },
118 {
"INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE",
119 HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE },
120 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST",
121 HTP_LOG_CODE_DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST },
122 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE",
123 HTP_LOG_CODE_DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE },
124 {
"100_CONTINUE_ALREADY_SEEN", HTP_LOG_CODE_CONTINUE_ALREADY_SEEN },
125 {
"UNABLE_TO_MATCH_RESPONSE_TO_REQUEST", HTP_LOG_CODE_UNABLE_TO_MATCH_RESPONSE_TO_REQUEST },
126 {
"INVALID_SERVER_PORT_IN_REQUEST", HTP_LOG_CODE_INVALID_SERVER_PORT_IN_REQUEST },
127 {
"INVALID_AUTHORITY_PORT", HTP_LOG_CODE_INVALID_AUTHORITY_PORT },
128 {
"REQUEST_HEADER_INVALID", HTP_LOG_CODE_REQUEST_HEADER_INVALID },
129 {
"RESPONSE_HEADER_INVALID", HTP_LOG_CODE_RESPONSE_HEADER_INVALID },
130 {
"MISSING_HOST_HEADER", HTP_LOG_CODE_MISSING_HOST_HEADER },
131 {
"HOST_HEADER_AMBIGUOUS", HTP_LOG_CODE_HOST_HEADER_AMBIGUOUS },
132 {
"INVALID_REQUEST_FIELD_FOLDING", HTP_LOG_CODE_INVALID_REQUEST_FIELD_FOLDING },
133 {
"INVALID_RESPONSE_FIELD_FOLDING", HTP_LOG_CODE_INVALID_RESPONSE_FIELD_FOLDING },
134 {
"REQUEST_FIELD_TOO_LONG", HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG },
135 {
"RESPONSE_FIELD_TOO_LONG", HTP_LOG_CODE_RESPONSE_FIELD_TOO_LONG },
136 {
"REQUEST_LINE_INVALID", HTP_LOG_CODE_REQUEST_LINE_INVALID },
137 {
"REQUEST_BODY_UNEXPECTED", HTP_LOG_CODE_REQUEST_BODY_UNEXPECTED },
138 {
"RESPONSE_BODY_UNEXPECTED", HTP_LOG_CODE_RESPONSE_BODY_UNEXPECTED },
139 {
"REQUEST_SERVER_PORT_TCP_PORT_MISMATCH", HTP_LOG_CODE_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH },
140 {
"REQUEST_URI_HOST_INVALID", HTP_LOG_CODE_URI_HOST_INVALID },
141 {
"REQUEST_HEADER_HOST_INVALID", HTP_LOG_CODE_HEADER_HOST_INVALID },
142 {
"REQUEST_AUTH_UNRECOGNIZED", HTP_LOG_CODE_AUTH_UNRECOGNIZED },
143 {
"REQUEST_HEADER_REPETITION", HTP_LOG_CODE_REQUEST_HEADER_REPETITION },
144 {
"RESPONSE_HEADER_REPETITION", HTP_LOG_CODE_RESPONSE_HEADER_REPETITION },
145 {
"DOUBLE_ENCODED_URI", HTP_LOG_CODE_DOUBLE_ENCODED_URI },
146 {
"URI_DELIM_NON_COMPLIANT", HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT },
147 {
"METHOD_DELIM_NON_COMPLIANT", HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT },
148 {
"REQUEST_LINE_LEADING_WHITESPACE", HTP_LOG_CODE_REQUEST_LINE_LEADING_WHITESPACE },
149 {
"TOO_MANY_ENCODING_LAYERS", HTP_LOG_CODE_TOO_MANY_ENCODING_LAYERS },
150 {
"REQUEST_TOO_MANY_LZMA_LAYERS", HTP_LOG_CODE_REQUEST_TOO_MANY_LZMA_LAYERS },
151 {
"RESPONSE_TOO_MANY_LZMA_LAYERS", HTP_LOG_CODE_RESPONSE_TOO_MANY_LZMA_LAYERS },
152 {
"ABNORMAL_CE_HEADER", HTP_LOG_CODE_ABNORMAL_CE_HEADER },
153 {
"RESPONSE_MULTIPART_BYTERANGES", HTP_LOG_CODE_RESPONSE_MULTIPART_BYTERANGES },
154 {
"RESPONSE_ABNORMAL_TRANSFER_ENCODING", HTP_LOG_CODE_RESPONSE_ABNORMAL_TRANSFER_ENCODING },
155 {
"RESPONSE_CHUNKED_OLD_PROTO", HTP_LOG_CODE_RESPONSE_CHUNKED_OLD_PROTO },
156 {
"RESPONSE_INVALID_PROTOCOL", HTP_LOG_CODE_RESPONSE_INVALID_PROTOCOL },
157 {
"RESPONSE_INVALID_STATUS", HTP_LOG_CODE_RESPONSE_INVALID_STATUS },
158 {
"REQUEST_LINE_INCOMPLETE", HTP_LOG_CODE_REQUEST_LINE_INCOMPLETE },
159 {
"PROTOCOL_CONTAINS_EXTRA_DATA", HTP_LOG_CODE_PROTOCOL_CONTAINS_EXTRA_DATA },
161 "CONTENT_LENGTH_EXTRA_DATA_START",
162 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_START,
165 "CONTENT_LENGTH_EXTRA_DATA_END",
166 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_END,
169 "CONTENT_LENGTH_EXTRA_DATA_END",
170 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_END,
172 {
"SWITCHING_PROTO_WITH_CONTENT_LENGTH", HTP_LOG_CODE_SWITCHING_PROTO_WITH_CONTENT_LENGTH },
173 {
"DEFORMED_EOL", HTP_LOG_CODE_DEFORMED_EOL },
174 {
"PARSER_STATE_ERROR", HTP_LOG_CODE_PARSER_STATE_ERROR },
175 {
"MISSING_OUTBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_OUTBOUND_TRANSACTION_DATA },
176 {
"MISSING_INBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_INBOUND_TRANSACTION_DATA },
177 {
"MISSING_INBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_INBOUND_TRANSACTION_DATA },
178 {
"ZERO_LENGTH_DATA_CHUNKS", HTP_LOG_CODE_ZERO_LENGTH_DATA_CHUNKS },
179 {
"REQUEST_LINE_UNKNOWN_METHOD", HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD },
180 {
"REQUEST_LINE_UNKNOWN_METHOD", HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD },
181 {
"REQUEST_LINE_UNKNOWN_METHOD_NO_PROTOCOL",
182 HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD_NO_PROTOCOL },
183 {
"REQUEST_LINE_UNKNOWN_METHOD_INVALID_PROTOCOL",
184 HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD_INVALID_PROTOCOL },
185 {
"REQUEST_LINE_MISSING_PROTOCOL", HTP_LOG_CODE_REQUEST_LINE_NO_PROTOCOL },
186 {
"RESPONSE_LINE_INVALID_PROTOCOL", HTP_LOG_CODE_RESPONSE_LINE_INVALID_PROTOCOL },
187 {
"RESPONSE_LINE_INVALID_RESPONSE_STATUS", HTP_LOG_CODE_RESPONSE_LINE_INVALID_RESPONSE_STATUS },
188 {
"RESPONSE_BODY_INTERNAL_ERROR", HTP_LOG_CODE_RESPONSE_BODY_INTERNAL_ERROR },
189 {
"REQUEST_BODY_DATA_CALLBACK_ERROR", HTP_LOG_CODE_REQUEST_BODY_DATA_CALLBACK_ERROR },
190 {
"RESPONSE_INVALID_EMPTY_NAME", HTP_LOG_CODE_RESPONSE_INVALID_EMPTY_NAME },
191 {
"REQUEST_INVALID_EMPTY_NAME", HTP_LOG_CODE_REQUEST_INVALID_EMPTY_NAME },
192 {
"RESPONSE_INVALID_LWS_AFTER_NAME", HTP_LOG_CODE_RESPONSE_INVALID_LWS_AFTER_NAME },
193 {
"RESPONSE_HEADER_NAME_NOT_TOKEN", HTP_LOG_CODE_RESPONSE_HEADER_NAME_NOT_TOKEN },
194 {
"REQUEST_INVALID_LWS_AFTER_NAME", HTP_LOG_CODE_REQUEST_INVALID_LWS_AFTER_NAME },
195 {
"LZMA_DECOMPRESSION_DISABLED", HTP_LOG_CODE_LZMA_DECOMPRESSION_DISABLED },
196 {
"CONNECTION_ALREADY_OPEN", HTP_LOG_CODE_CONNECTION_ALREADY_OPEN },
197 {
"COMPRESSION_BOMB_DOUBLE_LZMA", HTP_LOG_CODE_COMPRESSION_BOMB_DOUBLE_LZMA },
198 {
"INVALID_CONTENT_ENCODING", HTP_LOG_CODE_INVALID_CONTENT_ENCODING },
199 {
"INVALID_GAP", HTP_LOG_CODE_INVALID_GAP },
200 {
"REQUEST_CHUNK_EXTENSION", HTP_LOG_CODE_REQUEST_CHUNK_EXTENSION },
201 {
"RESPONSE_CHUNK_EXTENSION", HTP_LOG_CODE_RESPONSE_CHUNK_EXTENSION },
203 {
"LZMA_MEMLIMIT_REACHED", HTP_LOG_CODE_LZMA_MEMLIMIT_REACHED },
204 {
"COMPRESSION_BOMB", HTP_LOG_CODE_COMPRESSION_BOMB },
206 {
"REQUEST_TOO_MANY_HEADERS", HTP_LOG_CODE_REQUEST_TOO_MANY_HEADERS },
207 {
"RESPONSE_TOO_MANY_HEADERS", HTP_LOG_CODE_RESPONSE_TOO_MANY_HEADERS },
240 static int HTTPGetFrameIdByName(
const char *frame_name)
249 static const char *HTTPGetFrameNameById(
const uint8_t frame_id)
259 HTP_REQUEST_PROGRESS_NOT_STARTED,
263 HTP_REQUEST_PROGRESS_LINE,
267 HTP_REQUEST_PROGRESS_HEADERS,
271 HTP_REQUEST_PROGRESS_BODY,
275 HTP_REQUEST_PROGRESS_TRAILER,
279 HTP_REQUEST_PROGRESS_COMPLETE,
288 HTP_RESPONSE_PROGRESS_NOT_STARTED,
292 HTP_RESPONSE_PROGRESS_LINE,
296 HTP_RESPONSE_PROGRESS_HEADERS,
300 HTP_RESPONSE_PROGRESS_BODY,
304 HTP_RESPONSE_PROGRESS_TRAILER,
308 HTP_RESPONSE_PROGRESS_COMPLETE,
313 static int HtpStateGetStateIdByName(
const char *
name,
const uint8_t direction)
316 direction == STREAM_TOSERVER ? http_state_client_table : http_state_server_table;
325 static const char *HtpStateGetStateNameById(
const int id,
const uint8_t direction)
328 direction == STREAM_TOSERVER ? http_state_client_table : http_state_server_table;
333 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id);
334 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction);
335 static uint64_t HTPStateGetTxCnt(
void *alstate);
337 static void HTPParserRegisterTests(
void);
340 static inline uint64_t HtpGetActiveRequestTxID(
HtpState *s)
342 uint64_t
id = HTPStateGetTxCnt(s);
347 static inline uint64_t HtpGetActiveResponseTxID(
HtpState *s)
360 static const char *HTPLookupPersonalityString(
int p)
362 #define CASE_HTP_PERSONALITY_STRING(p) \
363 case HTP_SERVER_PERSONALITY_##p: \
367 CASE_HTP_PERSONALITY_STRING(MINIMAL);
368 CASE_HTP_PERSONALITY_STRING(GENERIC);
369 CASE_HTP_PERSONALITY_STRING(IDS);
370 CASE_HTP_PERSONALITY_STRING(IIS_4_0);
371 CASE_HTP_PERSONALITY_STRING(IIS_5_0);
372 CASE_HTP_PERSONALITY_STRING(IIS_5_1);
373 CASE_HTP_PERSONALITY_STRING(IIS_6_0);
374 CASE_HTP_PERSONALITY_STRING(IIS_7_0);
375 CASE_HTP_PERSONALITY_STRING(IIS_7_5);
376 CASE_HTP_PERSONALITY_STRING(APACHE_2);
390 static int HTPLookupPersonality(
const char *
str)
392 #define IF_HTP_PERSONALITY_NUM(p) \
393 if (strcasecmp(#p, str) == 0) \
394 return HTP_SERVER_PERSONALITY_##p
406 if (strcasecmp(
"TOMCAT_6_0",
str) == 0) {
408 "longer supported by libhtp.",
411 }
else if ((strcasecmp(
"APACHE",
str) == 0) ||
412 (strcasecmp(
"APACHE_2_2",
str) == 0))
415 "longer supported by libhtp, failing back to "
416 "Apache2 personality.",
418 return HTP_SERVER_PERSONALITY_APACHE_2;
425 const uint8_t dir,
const uint8_t e)
435 const uint64_t tx_id = (dir == STREAM_TOSERVER) ?
436 HtpGetActiveRequestTxID(s) : HtpGetActiveResponseTxID(s);
438 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
439 if (tx == NULL && tx_id > 0)
440 tx = HTPStateGetTx(s, tx_id - 1);
444 if (dir & STREAM_TOCLIENT)
446 if (dir & STREAM_TOSERVER)
457 static void *HTPStateAlloc(
void *orig_state,
AppProto proto_orig)
471 htp_state_memuse +=
sizeof(
HtpState);
472 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
479 static void HtpTxUserDataFree(
void *txud)
515 if (s->
connp != NULL) {
517 htp_connp_destroy_all(s->
connp);
525 htp_state_memuse -=
sizeof(
HtpState);
526 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
537 static void HTPStateTransactionFree(
void *state, uint64_t
id)
544 htp_tx_destroy(s->
connp,
id);
589 static void AppLayerHtpSetStreamDepthFlag(
void *tx,
const uint8_t
flags)
593 if (
flags & STREAM_TOCLIENT) {
602 SCLogDebug(
"cfg->body_limit %u stream_depth %u body->content_len_so_far %" PRIu64,
619 static uint32_t AppLayerHtpComputeChunkLength(uint64_t content_len_so_far, uint32_t body_limit,
620 uint32_t stream_depth, uint8_t
flags, uint32_t data_len)
622 uint32_t chunk_len = 0;
624 (content_len_so_far < (uint64_t)body_limit) &&
625 (content_len_so_far + (uint64_t)data_len) > body_limit)
627 chunk_len = (uint32_t)(body_limit - content_len_so_far);
629 (content_len_so_far < (uint64_t)stream_depth) &&
630 (content_len_so_far + (uint64_t)data_len) > stream_depth)
632 chunk_len = (uint32_t)(stream_depth - content_len_so_far);
635 return (chunk_len == 0 ? data_len : chunk_len);
646 static void HTPHandleError(
HtpState *s,
const uint8_t dir)
653 htp_log_t *log = htp_conn_next_log(s->
conn);
654 while (log != NULL) {
655 char *msg = htp_log_message(log);
658 log = htp_conn_next_log(s->
conn);
664 htp_log_code_t
id = htp_log_code(log);
665 if (
id != HTP_LOG_CODE_UNKNOWN &&
id != HTP_LOG_CODE_ERROR) {
666 HTPSetEvent(s, NULL, dir, (uint8_t)
id);
668 htp_free_cstring(msg);
678 log = htp_conn_next_log(s->
conn);
683 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s,
const htp_tx_t *tx)
686 BUG_ON(s == NULL || tx == NULL);
688 if (htp_tx_flags(tx) & (HTP_FLAGS_REQUEST_INVALID_T_E | HTP_FLAGS_REQUEST_INVALID_C_L |
689 HTP_FLAGS_HOST_MISSING | HTP_FLAGS_HOST_AMBIGUOUS |
690 HTP_FLAGS_HOSTU_INVALID | HTP_FLAGS_HOSTH_INVALID)) {
693 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_T_E)
694 HTPSetEvent(s, htud, STREAM_TOSERVER,
695 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST);
696 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_C_L)
698 s, htud, STREAM_TOSERVER, HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST);
699 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_MISSING)
700 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_MISSING_HOST_HEADER);
701 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_AMBIGUOUS)
702 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HOST_HEADER_AMBIGUOUS);
703 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTU_INVALID)
704 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_URI_HOST_INVALID);
705 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTH_INVALID)
706 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HEADER_HOST_INVALID);
708 if (htp_tx_request_auth_type(tx) == HTP_AUTH_TYPE_UNRECOGNIZED) {
710 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_AUTH_UNRECOGNIZED);
712 if (htp_tx_is_protocol_0_9(tx) && htp_tx_request_method_number(tx) == HTP_METHOD_UNKNOWN &&
713 (htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_INVALID ||
714 htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_UNKNOWN)) {
716 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_REQUEST_LINE_INVALID);
726 htp_cfg_t *htp = cfglist.
cfg;
727 void *user_data = NULL;
743 if (user_data != NULL) {
744 htp_cfg_rec = user_data;
745 htp = htp_cfg_rec->
cfg;
748 SCLogDebug(
"Using default HTP config: %p", htp);
752 #ifdef DEBUG_VALIDATION
759 hstate->
connp = htp_connp_create(htp);
760 if (hstate->
connp == NULL) {
764 hstate->
conn = (htp_conn_t *)htp_connp_connection(hstate->
connp);
766 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
767 hstate->
cfg = htp_cfg_rec;
772 htp_connp_open(hstate->
connp, NULL, f->
sp, NULL, f->
dp, &
tv);
804 if (NULL == hstate->
conn) {
805 if (Setup(f, hstate) != 0) {
810 hstate->
slice = &stream_slice;
812 const uint8_t *input = StreamSliceGetData(&stream_slice);
813 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
818 const int r = htp_connp_request_data(hstate->
connp, &
ts, input, input_len);
820 case HTP_STREAM_STATE_ERROR:
826 HTPHandleError(hstate, STREAM_TOSERVER);
832 htp_connp_request_close(hstate->
connp, &
ts);
834 SCLogDebug(
"stream eof encountered, closing htp handle for ts");
838 hstate->
slice = NULL;
866 const uint8_t *input = StreamSliceGetData(&stream_slice);
867 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
873 if (NULL == hstate->
conn) {
874 if (Setup(f, hstate) != 0) {
879 hstate->
slice = &stream_slice;
882 const htp_tx_t *tx = NULL;
883 uint32_t consumed = 0;
885 const int r = htp_connp_response_data(hstate->
connp, &
ts, input, input_len);
887 case HTP_STREAM_STATE_ERROR:
890 case HTP_STREAM_STATE_TUNNEL:
891 tx = htp_connp_get_response_tx(hstate->
connp);
892 if (tx != NULL && htp_tx_response_status_number(tx) == 101) {
893 const htp_header_t *h = htp_tx_response_header(tx,
"Upgrade");
898 if (htp_tx_request_port_number(tx) != -1) {
899 dp = (uint16_t)htp_tx_request_port_number(tx);
901 consumed = (uint32_t)htp_connp_response_data_consumed(hstate->
connp);
902 if (bstr_cmp_c(htp_header_value(h),
"h2c") == 0) {
907 hstate->
slice = NULL;
909 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
914 if (consumed > 0 && consumed < input_len) {
918 }
else if (bstr_cmp_c_nocase(htp_header_value(h),
"WebSocket")) {
923 hstate->
slice = NULL;
925 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
930 if (consumed > 0 && consumed < input_len) {
940 HTPHandleError(hstate, STREAM_TOCLIENT);
946 htp_connp_close(hstate->
connp, &
ts);
951 hstate->
slice = NULL;
962 static int HTTPParseContentDispositionHeader(
const uint8_t *
name,
size_t name_len,
963 const uint8_t *data,
size_t len, uint8_t
const **retptr,
size_t *retlen)
966 printf(
"DATA START: \n");
968 printf(
"DATA END: \n");
973 for (x = 0; x <
len; x++) {
974 if (!(isspace(data[x])))
981 const uint8_t *line = data + x;
982 size_t line_len =
len-x;
985 printf(
"LINE START: \n");
987 printf(
"LINE END: \n");
989 for (x = 0 ; x < line_len; x++) {
991 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
995 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
996 const uint8_t *token = line +
offset;
997 size_t token_len = x -
offset;
999 if ((x + 1) == line_len) {
1010 printf(
"TOKEN START: \n");
1012 printf(
"TOKEN END: \n");
1014 if (token_len > name_len) {
1015 if (
name == NULL || SCMemcmpLowercase(
name, token, name_len) == 0) {
1016 const uint8_t *value = token + name_len;
1017 size_t value_len = token_len - name_len;
1019 if (value[0] ==
'\"') {
1023 if (value[value_len-1] ==
'\"') {
1027 printf(
"VALUE START: \n");
1029 printf(
"VALUE END: \n");
1032 *retlen = value_len;
1056 static int HtpRequestBodySetupMultipart(
const htp_tx_t *tx,
HtpTxUserData *htud)
1058 const htp_header_t *h = htp_tx_request_header(tx,
"Content-Type");
1059 if (h != NULL && htp_header_value_len(h) > 0) {
1061 SCMimeStateInit(htp_header_value_ptr(h), (uint32_t)htp_header_value_len(h));
1078 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1081 chunks_buffer, chunks_buffer_len,
1085 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1089 if (dir == STREAM_TOSERVER) {
1090 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1092 }
else if (dir == STREAM_TOCLIENT) {
1093 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1100 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len,
bool eof)
1103 printf(
"CHUNK START: \n");
1105 printf(
"CHUNK END: \n");
1111 STREAM_TOSERVER) >= HTP_REQUEST_PROGRESS_COMPLETE);
1113 const uint8_t *cur_buf = chunks_buffer;
1114 uint32_t cur_buf_len = chunks_buffer_len;
1130 const uint8_t *filename = NULL;
1131 uint16_t filename_len = 0;
1134 while (cur_buf_len > 0) {
1135 MimeParserResult r =
1136 SCMimeParse(htud->
mime_state, cur_buf, cur_buf_len, &consumed, &warnings);
1140 if (warnings & MIME_EVENT_FLAG_INVALID_HEADER) {
1144 if (warnings & MIME_EVENT_FLAG_NO_FILEDATA) {
1155 SCMimeStateGetFilename(htud->
mime_state, &filename, &filename_len);
1156 if (filename_len > 0) {
1160 hstate, htud, filename, filename_len, NULL, 0, STREAM_TOSERVER);
1163 }
else if (result == -2) {
1166 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1174 }
else if (result == -2) {
1182 uint32_t lastsize = consumed;
1183 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\n') {
1185 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\r') {
1189 HTPFileClose(htud, cur_buf, lastsize, 0, STREAM_TOSERVER);
1194 cur_buf += consumed;
1195 cur_buf_len -= consumed;
1207 const uint8_t *data, uint32_t data_len)
1214 uint8_t *filename = NULL;
1215 size_t filename_len = 0;
1218 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1219 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1220 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1223 if (filename != NULL) {
1229 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1233 }
else if (result == -2) {
1236 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1250 }
else if (result == -2) {
1263 const uint8_t *data, uint32_t data_len)
1280 const uint8_t *filename = NULL;
1281 size_t filename_len = 0;
1284 const htp_header_t *h = htp_tx_response_header(tx,
"Content-Disposition");
1285 if (h != NULL && htp_header_value_len(h) > 0) {
1287 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1288 htp_header_value_ptr(h), htp_header_value_len(h), &filename, &filename_len);
1292 if (filename == NULL) {
1294 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1295 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1296 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1300 if (filename != NULL) {
1302 const htp_header_t *h_content_range = htp_tx_response_header(tx,
"content-range");
1308 if (h_content_range != NULL) {
1310 data_len, tx, htp_header_value(h_content_range), htud);
1312 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1318 }
else if (result == -2) {
1321 FlagDetectStateNewFile(htud, STREAM_TOCLIENT);
1334 }
else if (result == -2) {
1352 static int HTPCallbackRequestBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1356 const htp_tx_t *tx = htp_tx_data_tx(d);
1361 if (htp_tx_data_is_empty(d))
1365 printf(
"HTPBODY START: \n");
1366 PrintRawDataFp(stdout, (uint8_t *)htp_tx_data_data(d), htp_tx_data_len(d));
1367 printf(
"HTPBODY END: \n");
1370 HtpState *hstate = htp_connp_user_data(connp);
1371 if (hstate == NULL) {
1375 SCLogDebug(
"New request body data available at %p -> %p -> %p, bodylen "
1377 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1380 if (tx_ud == NULL) {
1389 if (htp_tx_request_method_number(tx) == HTP_METHOD_POST) {
1391 int r = HtpRequestBodySetupMultipart(tx, tx_ud);
1394 }
else if (r == 0) {
1398 }
else if (htp_tx_request_method_number(tx) == HTP_METHOD_PUT) {
1414 (uint32_t)htp_tx_data_len(d));
1419 const uint8_t *chunks_buffer = NULL;
1420 uint32_t chunks_buffer_len = 0;
1428 HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len);
1429 if (chunks_buffer == NULL) {
1433 printf(
"REASSCHUNK START: \n");
1435 printf(
"REASSCHUNK END: \n");
1438 HtpRequestBodyHandleMultipart(hstate, tx_ud, htp_tx_data_tx(d), chunks_buffer,
1439 chunks_buffer_len, (htp_tx_data_data(d) == NULL && htp_tx_data_len(d) == 0));
1443 HtpRequestBodyHandlePOSTorPUT(
1444 hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1449 SCLogDebug(
"closing file that was being stored");
1456 if (hstate->
conn != NULL) {
1457 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1458 ", last %" PRIu64
")",
1460 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1469 if ((uint64_t)htp_conn_request_data_counter(hstate->
conn) >
1471 (uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1473 (uint64_t)UINT_MAX) {
1474 uint32_t data_size =
1475 (uint32_t)((uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1496 static int HTPCallbackResponseBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1500 const htp_tx_t *tx = htp_tx_data_tx(d);
1505 if (htp_tx_data_is_empty(d))
1508 HtpState *hstate = htp_connp_user_data(connp);
1509 if (hstate == NULL) {
1513 SCLogDebug(
"New response body data available at %p -> %p -> %p, bodylen "
1515 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1535 (uint32_t)htp_tx_data_len(d));
1540 HtpResponseBodyHandle(hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1543 SCLogDebug(
"closing file that was being stored");
1549 if (hstate->
conn != NULL) {
1550 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1551 ", last %" PRIu64
")",
1553 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1561 if ((uint64_t)htp_conn_response_data_counter(hstate->
conn) >
1563 (uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1565 (uint64_t)UINT_MAX) {
1566 uint32_t data_size =
1567 (uint32_t)((uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1591 SCLogDebug(
"http_state_memcnt %"PRIu64
", http_state_memuse %"PRIu64
"",
1592 htp_state_memcnt, htp_state_memuse);
1609 htp_config_destroy(cfglist.
cfg);
1610 while (nextrec != NULL) {
1612 nextrec = nextrec->
next;
1614 htp_config_destroy(htprec->
cfg);
1622 static int HTPCallbackRequestHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1627 return HTP_STATUS_OK;
1630 static int HTPCallbackResponseHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1635 return HTP_STATUS_OK;
1638 static void *HTPCallbackTxCreate(
bool request)
1657 static int HTPCallbackRequestStart(
const htp_connp_t *connp, htp_tx_t *tx)
1659 HtpState *hstate = htp_connp_user_data(connp);
1660 if (hstate == NULL) {
1664 uint64_t consumed = hstate->
slice->
offset + htp_connp_request_data_consumed(hstate->
connp);
1665 SCLogDebug(
"HTTP request start: data offset %" PRIu64
", in_data_counter %" PRIu64, consumed,
1666 (uint64_t)htp_conn_request_data_counter(hstate->
conn));
1690 static int HTPCallbackResponseStart(
const htp_connp_t *connp, htp_tx_t *tx)
1692 HtpState *hstate = htp_connp_user_data(connp);
1693 if (hstate == NULL) {
1697 uint64_t consumed = hstate->
slice->
offset + htp_connp_response_data_consumed(hstate->
connp);
1698 SCLogDebug(
"HTTP response start: data offset %" PRIu64
", out_data_counter %" PRIu64, consumed,
1699 (uint64_t)htp_conn_response_data_counter(hstate->
conn));
1724 static int HTPCallbackRequestComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1732 HtpState *hstate = htp_connp_user_data(connp);
1733 if (hstate == NULL) {
1737 const uint64_t abs_right_edge =
1746 SCLogDebug(
"HTTP request complete: data offset %" PRIu64
", request_size %" PRIu64,
1748 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1750 frame->
len = (int64_t)request_size;
1756 SCLogDebug(
"transaction_cnt %"PRIu64
", list_size %"PRIu64,
1761 HTPErrorCheckTxRequestFlags(hstate, tx);
1766 SCLogDebug(
"closing file that was being stored");
1769 if (abs_right_edge < (uint64_t)UINT32_MAX) {
1771 hstate->
f->
protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
1788 static int HTPCallbackResponseComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1792 HtpState *hstate = htp_connp_user_data(connp);
1793 if (hstate == NULL) {
1800 const uint64_t abs_right_edge =
1808 SCLogDebug(
"HTTP response complete: data offset %" PRIu64
", response_size %" PRIu64,
1810 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1812 frame->
len = (int64_t)response_size;
1820 SCLogDebug(
"closing file that was being stored");
1830 if (htp_tx_request_method_number(tx) == HTP_METHOD_CONNECT) {
1833 if ((htp_tx_response_status_number(tx) >= 200) &&
1834 (htp_tx_response_status_number(tx) < 300) && (hstate->
transaction_cnt == 1)) {
1836 if (htp_tx_request_port_number(tx) != -1) {
1837 dp = (uint16_t)htp_tx_request_port_number(tx);
1851 static int HTPCallbackRequestLine(
const htp_connp_t *connp, htp_tx_t *tx)
1853 HtpState *hstate = htp_connp_user_data(connp);
1855 if (htp_tx_flags(tx)) {
1856 HTPErrorCheckTxRequestFlags(hstate, tx);
1858 return HTP_STATUS_OK;
1861 static int HTPCallbackRequestHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1864 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1865 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1866 return HTP_STATUS_OK;
1872 return HTP_STATUS_OK;
1878 htp_tx_data_len(tx_data));
1881 if (tx && htp_tx_flags(tx)) {
1882 HtpState *hstate = htp_connp_user_data(connp);
1883 HTPErrorCheckTxRequestFlags(hstate, tx);
1885 return HTP_STATUS_OK;
1888 static int HTPCallbackResponseHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1891 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1892 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1893 return HTP_STATUS_OK;
1900 return HTP_STATUS_OK;
1905 htp_tx_data_len(tx_data));
1908 return HTP_STATUS_OK;
1914 static void HTPConfigSetDefaultsPhase1(
HTPCfgRec *cfg_prec)
1916 htp_config_set_normalized_uri_include_all(cfg_prec->
cfg,
false);
1931 htp_config_register_request_header_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1932 htp_config_register_request_trailer_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1933 htp_config_register_response_header_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1934 htp_config_register_response_trailer_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1936 htp_config_register_request_trailer(cfg_prec->
cfg, HTPCallbackRequestHasTrailer);
1937 htp_config_register_response_trailer(cfg_prec->
cfg, HTPCallbackResponseHasTrailer);
1939 htp_config_register_request_body_data(cfg_prec->
cfg, HTPCallbackRequestBodyData);
1940 htp_config_register_response_body_data(cfg_prec->
cfg, HTPCallbackResponseBodyData);
1942 htp_config_register_tx_create(cfg_prec->
cfg, HTPCallbackTxCreate);
1943 htp_config_register_tx_destroy(cfg_prec->
cfg, HtpTxUserDataFree);
1945 htp_config_register_request_start(cfg_prec->
cfg, HTPCallbackRequestStart);
1946 htp_config_register_request_complete(cfg_prec->
cfg, HTPCallbackRequestComplete);
1948 htp_config_register_response_start(cfg_prec->
cfg, HTPCallbackResponseStart);
1949 htp_config_register_response_complete(cfg_prec->
cfg, HTPCallbackResponseComplete);
1951 htp_config_set_parse_request_cookies(cfg_prec->
cfg, 0);
1952 htp_config_set_allow_space_uri(cfg_prec->
cfg, 1);
1955 htp_config_set_plusspace_decode(cfg_prec->
cfg, 0);
1957 htp_config_set_request_decompression(cfg_prec->
cfg, 1);
1962 #define HTP_CONFIG_DEFAULT_MAX_TX_LIMIT 512
1964 #define HTP_CONFIG_DEFAULT_HEADERS_LIMIT 1024
1972 static int RandomGetWrap(
void)
1978 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
1980 return r % RAND_MAX;
1989 static void HTPConfigSetDefaultsPhase2(
const char *
name,
HTPCfgRec *cfg_prec)
1995 long int r = RandomGetWrap();
1997 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
1999 r = RandomGetWrap();
2001 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2002 SCLogConfig(
"'%s' server has 'request-body-minimal-inspect-size' set to"
2003 " %u and 'request-body-inspect-window' set to %u after"
2007 r = RandomGetWrap();
2009 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2011 r = RandomGetWrap();
2013 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2015 SCLogConfig(
"'%s' server has 'response-body-minimal-inspect-size' set to"
2016 " %u and 'response-body-inspect-window' set to %u after"
2021 htp_config_register_request_line(cfg_prec->
cfg, HTPCallbackRequestLine);
2024 static void HTPConfigParseParameters(
HTPCfgRec *cfg_prec,
SCConfNode *s,
struct HTPConfigTree *tree)
2026 if (cfg_prec == NULL || s == NULL || tree == NULL)
2033 if (strcasecmp(
"address", p->
name) == 0) {
2039 if (strchr(pval->
val,
':') != NULL) {
2040 SCLogDebug(
"LIBHTP adding ipv6 server %s at %s: %p",
2044 SCLogWarning(
"LIBHTP failed to add ipv6 server %s, ignoring", pval->
val);
2047 SCLogDebug(
"LIBHTP adding ipv4 server %s at %s: %p",
2051 SCLogWarning(
"LIBHTP failed to add ipv4 server %s, ignoring", pval->
val);
2056 }
else if (strcasecmp(
"personality", p->
name) == 0) {
2058 int personality = HTPLookupPersonality(p->
val);
2062 if (personality >= 0) {
2065 if (htp_config_set_server_personality(cfg_prec->
cfg, personality) ==
2068 "personality \"%s\", ignoring",
2072 HTPLookupPersonalityString(personality));
2078 htp_config_set_convert_lowercase(cfg_prec->
cfg, 0);
2086 }
else if (strcasecmp(
"request-body-limit", p->
name) == 0 ||
2087 strcasecmp(
"request_body_limit", p->
name) == 0) {
2089 SCLogError(
"Error parsing request-body-limit "
2090 "from conf file - %s. Killing engine",
2095 }
else if (strcasecmp(
"response-body-limit", p->
name) == 0) {
2097 SCLogError(
"Error parsing response-body-limit "
2098 "from conf file - %s. Killing engine",
2103 }
else if (strcasecmp(
"request-body-minimal-inspect-size", p->
name) == 0) {
2105 SCLogError(
"Error parsing request-body-minimal-inspect-size "
2106 "from conf file - %s. Killing engine",
2111 }
else if (strcasecmp(
"request-body-inspect-window", p->
name) == 0) {
2113 SCLogError(
"Error parsing request-body-inspect-window "
2114 "from conf file - %s. Killing engine",
2119 }
else if (strcasecmp(
"double-decode-query", p->
name) == 0) {
2121 }
else if (strcasecmp(
"double-decode-path", p->
name) == 0) {
2123 }
else if (strcasecmp(
"response-body-minimal-inspect-size", p->
name) == 0) {
2125 SCLogError(
"Error parsing response-body-minimal-inspect-size "
2126 "from conf file - %s. Killing engine",
2131 }
else if (strcasecmp(
"response-body-inspect-window", p->
name) == 0) {
2133 SCLogError(
"Error parsing response-body-inspect-window "
2134 "from conf file - %s. Killing engine",
2139 }
else if (strcasecmp(
"response-body-decompress-layer-limit", p->
name) == 0) {
2142 SCLogError(
"Error parsing response-body-inspect-window "
2143 "from conf file - %s. Killing engine",
2147 htp_config_set_decompression_layer_limit(cfg_prec->
cfg, value);
2148 }
else if (strcasecmp(
"path-convert-backslash-separators", p->
name) == 0) {
2150 }
else if (strcasecmp(
"path-bestfit-replacement-char", p->
name) == 0) {
2151 if (strlen(p->
val) == 1) {
2152 htp_config_set_bestfit_replacement_byte(cfg_prec->
cfg, p->
val[0]);
2155 "for libhtp param path-bestfit-replacement-char");
2157 }
else if (strcasecmp(
"path-convert-lowercase", p->
name) == 0) {
2159 }
else if (strcasecmp(
"path-nul-encoded-terminates", p->
name) == 0) {
2161 }
else if (strcasecmp(
"path-nul-raw-terminates", p->
name) == 0) {
2163 }
else if (strcasecmp(
"path-separators-compress", p->
name) == 0) {
2165 }
else if (strcasecmp(
"path-separators-decode", p->
name) == 0) {
2167 }
else if (strcasecmp(
"path-u-encoding-decode", p->
name) == 0) {
2169 }
else if (strcasecmp(
"path-url-encoding-invalid-handling", p->
name) == 0) {
2170 enum htp_url_encoding_handling_t handling;
2171 if (strcasecmp(p->
val,
"preserve_percent") == 0) {
2172 handling = HTP_URL_ENCODING_HANDLING_PRESERVE_PERCENT;
2173 }
else if (strcasecmp(p->
val,
"remove_percent") == 0) {
2174 handling = HTP_URL_ENCODING_HANDLING_REMOVE_PERCENT;
2175 }
else if (strcasecmp(p->
val,
"decode_invalid") == 0) {
2176 handling = HTP_URL_ENCODING_HANDLING_PROCESS_INVALID;
2179 "for libhtp param path-url-encoding-invalid-handling");
2182 htp_config_set_url_encoding_invalid_handling(cfg_prec->
cfg, handling);
2183 }
else if (strcasecmp(
"path-utf8-convert-bestfit", p->
name) == 0) {
2185 }
else if (strcasecmp(
"uri-include-all", p->
name) == 0) {
2188 }
else if (strcasecmp(
"query-plusspace-decode", p->
name) == 0) {
2190 }
else if (strcasecmp(
"meta-field-limit", p->
name) == 0) {
2194 "from conf file - %s. Killing engine",
2200 "from conf file cannot be 0. Killing engine");
2203 htp_config_set_field_limit(cfg_prec->
cfg, (
size_t)limit);
2204 }
else if (strcasecmp(
"lzma-memlimit", p->
name) == 0) {
2207 FatalError(
"failed to parse 'lzma-memlimit' "
2208 "from conf file - %s.",
2213 "from conf file cannot be 0.");
2216 SCLogConfig(
"Setting HTTP LZMA memory limit to %"PRIu32
" bytes", limit);
2217 htp_config_set_lzma_memlimit(cfg_prec->
cfg, (
size_t)limit);
2218 }
else if (strcasecmp(
"lzma-enabled", p->
name) == 0) {
2220 htp_config_set_lzma_layers(cfg_prec->
cfg, 1);
2225 "from conf file - %s.",
2228 SCLogConfig(
"Setting HTTP LZMA decompression layers to %" PRIu32
"", (
int)limit);
2229 htp_config_set_lzma_layers(cfg_prec->
cfg, 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) {
2335 SCLogError(
"Error parsing swf-decompression.compression-depth "
2336 "from conf file - %s. Killing engine",
2340 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2342 SCLogError(
"Error parsing swf-decompression.decompression-depth "
2343 "from conf file - %s. Killing engine",
2353 "default config: %s",
2363 cfglist.
next = NULL;
2370 cfglist.
cfg = htp_config_create();
2371 if (NULL == cfglist.
cfg) {
2372 FatalError(
"Failed to create HTP default config");
2375 HTPConfigSetDefaultsPhase1(&cfglist);
2376 if (
SCConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2377 HTPConfigParseParameters(&cfglist,
SCConfGetNode(
"libhtp.default-config"), &cfgtree);
2379 HTPConfigParseParameters(&cfglist,
2380 SCConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), &cfgtree);
2382 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2388 if (server_config == NULL) {
2390 if (server_config == NULL) {
2391 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2395 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2414 cfglist.
next = htprec;
2417 cfglist.
next->
cfg = htp_config_create();
2418 if (NULL == cfglist.
next->
cfg) {
2419 FatalError(
"Failed to create HTP server config");
2422 HTPConfigSetDefaultsPhase1(htprec);
2423 HTPConfigParseParameters(htprec, s, &cfgtree);
2424 HTPConfigSetDefaultsPhase2(s->
name, htprec);
2434 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
2448 htp_tx_t *tx = (htp_tx_t *)txv;
2450 if (direction & STREAM_TOCLIENT) {
2458 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
2460 if (direction & STREAM_TOSERVER)
2461 return htp_tx_request_progress((htp_tx_t *)tx);
2463 return htp_tx_response_progress((htp_tx_t *)tx);
2466 static uint64_t HTPStateGetTxCnt(
void *alstate)
2470 if (http_state != NULL && http_state->
connp != NULL) {
2471 const int64_t size = htp_connp_tx_size(http_state->
connp);
2475 return (uint64_t)size;
2481 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
2485 if (http_state != NULL && http_state->
connp != NULL)
2486 return (
void *)htp_connp_tx(http_state->
connp, tx_id);
2495 uint64_t size = HTPStateGetTxCnt(alstate);
2498 while (state->
un.
u64 < size) {
2499 htp_tx_t *tx = htp_connp_tx_index(http_state->
connp, state->
un.
u64);
2503 uint64_t tx_id = htp_tx_index(tx);
2504 if (tx_id < min_tx_id) {
2511 .has_next = state->
un.
u64 < size,
2523 if (http_state != NULL && http_state->
connp != NULL) {
2524 size_t txid = htp_connp_tx_size(http_state->
connp);
2526 return (
void *)htp_connp_tx(http_state->
connp, txid - 1);
2532 static int HTPStateGetEventInfo(
2542 static int HTPStateGetEventInfoById(
2546 if (*event_name == NULL) {
2548 "http's enum map table.",
2561 htp_tx_t *tx = (htp_tx_t *)vtx;
2572 static int HTPRegisterPatternsForProtocolDetection(
void)
2574 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
2575 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
2576 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
2577 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
2578 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
2579 const char *spacings[] = {
"|20|",
"|09|", NULL };
2580 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
2585 int register_result;
2586 char method_buffer[32] =
"";
2589 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
2590 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
2593 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
2600 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
2601 if (register_result < 0) {
2608 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
2610 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
2612 if (register_result < 0) {
2628 const char *proto_name =
"http";
2633 if (HTPRegisterPatternsForProtocolDetection() < 0)
2636 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
2651 ALPROTO_HTTP1, HTP_REQUEST_PROGRESS_COMPLETE, HTP_RESPONSE_PROGRESS_COMPLETE);
2663 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
2665 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
2669 IPPROTO_TCP,
ALPROTO_HTTP1, APP_LAYER_PARSER_OPT_ACCEPT_GAPS);
2671 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
2674 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
2677 IPPROTO_TCP,
ALPROTO_HTTP1, HtpStateGetStateIdByName, HtpStateGetStateNameById);
2681 SCLogInfo(
"Parser disabled for %s protocol. Protocol detection still on.", proto_name);
2697 cfglist_backup = cfglist;
2702 cfglist = cfglist_backup;
2707 static int HTPParserTest01(
void)
2709 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2711 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2714 memset(&ssn, 0,
sizeof(ssn));
2722 f->
proto = IPPROTO_TCP;
2728 for (u = 0; u < httplen1; u++) {
2732 flags = STREAM_TOSERVER|STREAM_START;
2733 else if (u == (httplen1 - 1))
2734 flags = STREAM_TOSERVER|STREAM_EOF;
2736 flags = STREAM_TOSERVER;
2745 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2748 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2751 FAIL_IF(bstr_cmp_c(htp_header_value(h),
"Victor/1.0"));
2752 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2753 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2762 static int HTPParserTest01b(
void)
2764 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2766 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2769 memset(&ssn, 0,
sizeof(ssn));
2777 f->
proto = IPPROTO_TCP;
2782 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
2789 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2792 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2795 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2796 FAIL_IF(strcmp(v,
"Victor/1.0"));
2798 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2799 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2808 static int HTPParserTest01c(
void)
2810 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2812 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2815 memset(&ssn, 0,
sizeof(ssn));
2823 f->
proto = IPPROTO_TCP;
2829 for (u = 0; u < httplen1; u++) {
2833 flags = STREAM_TOSERVER|STREAM_START;
2834 else if (u == (httplen1 - 1))
2835 flags = STREAM_TOSERVER|STREAM_EOF;
2837 flags = STREAM_TOSERVER;
2846 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2849 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2852 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2853 FAIL_IF(strcmp(v,
"Victor/1.0"));
2855 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2856 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2866 static int HTPParserTest01a(
void)
2869 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2871 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2876 memset(&ssn, 0,
sizeof(ssn));
2878 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2881 f->
proto = IPPROTO_TCP;
2887 for (u = 0; u < httplen1; u++) {
2891 flags = STREAM_TOSERVER|STREAM_START;
2892 else if (u == (httplen1 - 1))
2893 flags = STREAM_TOSERVER|STREAM_EOF;
2895 flags = STREAM_TOSERVER;
2904 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2907 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2910 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2911 FAIL_IF(strcmp(v,
"Victor/1.0"));
2913 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2914 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2923 static int HTPParserTest02(
void)
2926 uint8_t httpbuf1[] =
"POST";
2927 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2932 memset(&ssn, 0,
sizeof(ssn));
2934 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2937 f->
proto = IPPROTO_TCP;
2943 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
2949 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
2951 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2955 char *method = bstr_util_strdup_to_c(htp_tx_request_method(tx));
2958 FAIL_IF(strcmp(method,
"POST") != 0);
2969 static int HTPParserTest03(
void)
2972 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
2973 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2978 memset(&ssn, 0,
sizeof(ssn));
2980 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2983 f->
proto = IPPROTO_TCP;
2989 for (u = 0; u < httplen1; u++) {
2992 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
2993 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
2994 else flags = STREAM_TOSERVER;
3002 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3005 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3007 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3008 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
3018 static int HTPParserTest04(
void)
3022 uint8_t httpbuf1[] =
"World!\r\n";
3023 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3027 memset(&ssn, 0,
sizeof(ssn));
3029 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3032 f->
proto = IPPROTO_TCP;
3038 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3044 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3046 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3048 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3049 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V0_9);
3059 static int HTPParserTest05(
void)
3061 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3062 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3063 uint8_t httpbuf2[] =
"Post D";
3064 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3065 uint8_t httpbuf3[] =
"ata is c0oL!";
3066 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3068 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3069 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3070 uint8_t httpbuf5[] =
"post R";
3071 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3072 uint8_t httpbuf6[] =
"esults are tha bomb!";
3073 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3076 memset(&ssn, 0,
sizeof(ssn));
3084 f->
proto = IPPROTO_TCP;
3114 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3116 FAIL_IF_NOT(htp_tx_request_method_number(tx) == HTP_METHOD_POST);
3117 FAIL_IF_NOT(htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_V1_0);
3119 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3122 FAIL_IF_NOT(htp_tx_response_status_number(tx) == 200);
3132 static int HTPParserTest06(
void)
3134 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3135 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3136 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3137 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3138 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3140 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3141 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3142 "FrontPage/5.0.2.2510\r\n"
3143 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3145 "Content-Type: text/html\r\n\r\n"
3147 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3148 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3149 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3150 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3151 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3152 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3153 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3154 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3155 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3156 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3157 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3158 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3159 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3160 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3161 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3162 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3163 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3164 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3165 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3166 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3167 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3168 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3169 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3170 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3171 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3172 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3173 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3174 "aHA=\r\n0\r\n\r\n";
3175 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3181 memset(&ssn, 0,
sizeof(ssn));
3186 f->
proto = IPPROTO_TCP;
3201 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3204 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
3205 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3207 FAIL_IF(htp_tx_response_status_number(tx) != 200);
3208 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3210 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3221 static int HTPParserTest07(
void)
3224 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3225 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3230 memset(&ssn, 0,
sizeof(ssn));
3232 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3235 f->
proto = IPPROTO_TCP;
3241 for (u = 0; u < httplen1; u++) {
3245 flags = STREAM_TOSERVER|STREAM_START;
3246 else if (u == (httplen1 - 1))
3247 flags = STREAM_TOSERVER|STREAM_EOF;
3249 flags = STREAM_TOSERVER;
3258 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3259 size_t reflen =
sizeof(ref) - 1;
3261 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3263 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3265 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3267 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref, bstr_len(request_uri_normalized)) != 0);
3279 static int HTPParserTest08(
void)
3282 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3283 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3304 memset(&ssn, 0,
sizeof(ssn));
3306 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3309 f->
proto = IPPROTO_TCP;
3314 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3322 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3324 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3326 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3340 static int HTPParserTest09(
void)
3343 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3344 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3354 personality: Apache_2_2\n\
3366 memset(&ssn, 0,
sizeof(ssn));
3368 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3371 f->
proto = IPPROTO_TCP;
3376 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3384 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3386 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3388 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3402 static int HTPParserTest10(
void)
3406 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3407 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3412 memset(&ssn, 0,
sizeof(ssn));
3414 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3417 f->
proto = IPPROTO_TCP;
3423 for (u = 0; u < httplen1; u++) {
3427 flags = STREAM_TOSERVER|STREAM_START;
3428 else if (u == (httplen1 - 1))
3429 flags = STREAM_TOSERVER|STREAM_EOF;
3431 flags = STREAM_TOSERVER;
3440 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3441 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3444 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3448 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3450 FAIL_IF(strcmp(value,
"www.google.com") != 0);
3462 static int HTPParserTest11(
void)
3465 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3466 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3471 memset(&ssn, 0,
sizeof(ssn));
3473 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3476 f->
proto = IPPROTO_TCP;
3482 for (u = 0; u < httplen1; u++) {
3486 flags = STREAM_TOSERVER|STREAM_START;
3487 else if (u == (httplen1 - 1))
3488 flags = STREAM_TOSERVER|STREAM_EOF;
3490 flags = STREAM_TOSERVER;
3499 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3501 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3504 FAIL_IF(bstr_len(request_uri_normalized) != 4);
3505 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3506 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'%');
3507 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'0');
3508 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'0');
3518 static int HTPParserTest12(
void)
3521 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3522 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3527 memset(&ssn, 0,
sizeof(ssn));
3529 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3532 f->
proto = IPPROTO_TCP;
3538 for (u = 0; u < httplen1; u++) {
3542 flags = STREAM_TOSERVER|STREAM_START;
3543 else if (u == (httplen1 - 1))
3544 flags = STREAM_TOSERVER|STREAM_EOF;
3546 flags = STREAM_TOSERVER;
3555 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3557 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3560 FAIL_IF(bstr_len(request_uri_normalized) != 7);
3561 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3562 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'?');
3563 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'a');
3564 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'=');
3565 FAIL_IF(bstr_ptr(request_uri_normalized)[4] !=
'%');
3566 FAIL_IF(bstr_ptr(request_uri_normalized)[5] !=
'0');
3567 FAIL_IF(bstr_ptr(request_uri_normalized)[6] !=
'0');
3577 static int HTPParserTest13(
void)
3580 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3581 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3586 memset(&ssn, 0,
sizeof(ssn));
3588 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3591 f->
proto = IPPROTO_TCP;
3597 for (u = 0; u < httplen1; u++) {
3601 flags = STREAM_TOSERVER|STREAM_START;
3602 else if (u == (httplen1 - 1))
3603 flags = STREAM_TOSERVER|STREAM_EOF;
3605 flags = STREAM_TOSERVER;
3613 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3614 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3617 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3621 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3623 FAIL_IF(strcmp(value,
"www.google.com\rName: Value") != 0);
3635 static int HTPParserConfigTest01(
void)
3648 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3649 personality: Tomcat_6_0\n\
3654 - 192.168.10.0/24\n\
3655 personality: IIS_7_0\n\
3664 outputs =
SCConfGetNode(
"libhtp.default-config.personality");
3675 FAIL_IF(strcmp(node->
name,
"apache-tomcat") != 0);
3682 FAIL_IF(strcmp(node2->
val,
"Tomcat_6_0") != 0);
3692 FAIL_IF(strcmp(n->
val,
"192.168.1.0/24") != 0);
3732 FAIL_IF(strcmp(n->
val,
"192.168.0.0/24") != 0);
3736 FAIL_IF(strcmp(n->
val,
"192.168.10.0/24") != 0);
3751 static int HTPParserConfigTest02(
void)
3764 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3765 personality: Tomcat_6_0\n\
3770 - 192.168.10.0/24\n\
3771 personality: IIS_7_0\n\
3783 htp_cfg_t *htp = cfglist.
cfg;
3786 void *user_data = NULL;
3788 addr =
"192.168.10.42";
3789 FAIL_IF(inet_pton(AF_INET, addr, buf) != 1);
3793 htp = htp_cfg_rec->
cfg;
3799 FAIL_IF(inet_pton(AF_INET6, addr, buf) != 1);
3802 htp_cfg_rec = user_data;
3803 htp = htp_cfg_rec->
cfg;
3816 static int HTPParserConfigTest03(
void)
3819 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3821 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3837 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3838 personality: Tomcat_6_0\n\
3843 - 192.168.10.0/24\n\
3844 personality: IIS_7_0\n\
3855 const char *addr =
"192.168.10.42";
3857 memset(&ssn, 0,
sizeof(ssn));
3862 f->
proto = IPPROTO_TCP;
3865 htp_cfg_t *htp = cfglist.
cfg;
3868 void *user_data = NULL;
3873 htp = htp_cfg_rec->
cfg;
3880 for (u = 0; u < httplen1; u++) {
3883 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3884 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3885 else flags = STREAM_TOSERVER;
3894 FAIL_IF(HTPStateGetTxCnt(htp_state) != 2);
3896 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3898 tx = HTPStateGetTx(htp_state, 1);
3917 static int HTPParserDecodingTest01(
void)
3919 uint8_t httpbuf1[] =
3920 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3921 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3922 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
3923 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3934 personality: Apache_2\n\
3942 const char *addr =
"4.3.2.1";
3943 memset(&ssn, 0,
sizeof(ssn));
3948 f->
proto = IPPROTO_TCP;
3953 for (uint32_t u = 0; u < httplen1; u++) {
3955 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3956 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3957 else flags = STREAM_TOSERVER;
3966 uint8_t ref1[] =
"/abc%2fdef";
3967 size_t reflen =
sizeof(ref1) - 1;
3969 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3973 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3976 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3977 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
3979 uint8_t ref2[] =
"/abc/def?ghi/jkl";
3980 reflen =
sizeof(ref2) - 1;
3982 tx = HTPStateGetTx(htp_state, 1);
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), ref2, bstr_len(request_uri_normalized)) != 0);
3992 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
3993 reflen =
sizeof(ref3) - 1;
3994 tx = HTPStateGetTx(htp_state, 2);
3998 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4001 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4002 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4014 static int HTPParserDecodingTest01a(
void)
4016 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4017 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4018 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4019 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4030 personality: Apache_2\n\
4038 const char *addr =
"4.3.2.1";
4039 memset(&ssn, 0,
sizeof(ssn));
4044 f->
proto = IPPROTO_TCP;
4050 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4056 uint8_t ref1[] =
"/abc%2fdef";
4057 size_t reflen =
sizeof(ref1) - 1;
4059 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4063 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4066 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4067 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4069 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4070 reflen =
sizeof(ref2) - 1;
4072 tx = HTPStateGetTx(htp_state, 1);
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), ref2, bstr_len(request_uri_normalized)) != 0);
4082 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4083 reflen =
sizeof(ref3) - 1;
4084 tx = HTPStateGetTx(htp_state, 2);
4087 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4090 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4092 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4110 static int HTPParserDecodingTest02(
void)
4113 uint8_t httpbuf1[] =
4114 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4115 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4116 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4117 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4129 double-decode-path: no\n\
4130 double-decode-query: no\n\
4138 const char *addr =
"4.3.2.1";
4139 memset(&ssn, 0,
sizeof(ssn));
4144 f->
proto = IPPROTO_TCP;
4150 for (u = 0; u < httplen1; u++) {
4153 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4154 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4155 else flags = STREAM_TOSERVER;
4164 uint8_t ref1[] =
"/abc/def";
4165 size_t reflen =
sizeof(ref1) - 1;
4167 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4169 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4171 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4172 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4174 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4175 reflen =
sizeof(ref2) - 1;
4177 tx = HTPStateGetTx(htp_state, 1);
4179 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4181 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4183 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4185 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4186 reflen =
sizeof(ref3) - 1;
4187 tx = HTPStateGetTx(htp_state, 2);
4189 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4191 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4193 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4210 static int HTPParserDecodingTest03(
void)
4213 uint8_t httpbuf1[] =
4214 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4215 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4216 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4228 double-decode-path: yes\n\
4229 double-decode-query: yes\n\
4237 const char *addr =
"4.3.2.1";
4238 memset(&ssn, 0,
sizeof(ssn));
4243 f->
proto = IPPROTO_TCP;
4249 for (u = 0; u < httplen1; u++) {
4252 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4253 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4254 else flags = STREAM_TOSERVER;
4263 uint8_t ref1[] =
"/abc/def";
4264 size_t reflen =
sizeof(ref1) - 1;
4266 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4268 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4270 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4272 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4274 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4275 reflen =
sizeof(ref2) - 1;
4277 tx = HTPStateGetTx(htp_state, 1);
4279 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), ref2, bstr_len(request_uri_normalized)) != 0);
4297 static int HTPParserDecodingTest04(
void)
4300 uint8_t httpbuf1[] =
4301 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4302 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4314 double-decode-path: yes\n\
4315 double-decode-query: yes\n\
4323 const char *addr =
"4.3.2.1";
4324 memset(&ssn, 0,
sizeof(ssn));
4329 f->
proto = IPPROTO_TCP;
4335 for (u = 0; u < httplen1; u++) {
4338 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4339 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4340 else flags = STREAM_TOSERVER;
4349 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
4350 size_t reflen =
sizeof(ref1) - 1;
4352 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4354 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4356 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4358 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4372 static int HTPParserDecodingTest05(
void)
4375 uint8_t httpbuf1[] =
4376 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4377 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4389 double-decode-path: yes\n\
4390 double-decode-query: yes\n\
4398 const char *addr =
"4.3.2.1";
4399 memset(&ssn, 0,
sizeof(ssn));
4404 f->
proto = IPPROTO_TCP;
4410 for (u = 0; u < httplen1; u++) {
4413 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4414 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4415 else flags = STREAM_TOSERVER;
4424 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
4425 size_t reflen =
sizeof(ref1) - 1;
4427 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4429 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4431 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4433 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4447 static int HTPParserDecodingTest06(
void)
4450 uint8_t httpbuf1[] =
4451 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4452 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4464 double-decode-path: yes\n\
4465 double-decode-query: yes\n\
4473 const char *addr =
"4.3.2.1";
4474 memset(&ssn, 0,
sizeof(ssn));
4479 f->
proto = IPPROTO_TCP;
4485 for (u = 0; u < httplen1; u++) {
4488 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4489 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4490 else flags = STREAM_TOSERVER;
4499 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
4500 size_t reflen =
sizeof(ref1) - 1;
4502 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4504 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4506 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4508 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4522 static int HTPParserDecodingTest07(
void)
4525 uint8_t httpbuf1[] =
4526 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4527 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4539 double-decode-path: yes\n\
4540 double-decode-query: yes\n\
4541 query-plusspace-decode: yes\n\
4549 const char *addr =
"4.3.2.1";
4550 memset(&ssn, 0,
sizeof(ssn));
4555 f->
proto = IPPROTO_TCP;
4561 for (u = 0; u < httplen1; u++) {
4564 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4565 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4566 else flags = STREAM_TOSERVER;
4575 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
4576 size_t reflen =
sizeof(ref1) - 1;
4578 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4580 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4582 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4584 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4598 static int HTPParserDecodingTest08(
void)
4601 uint8_t httpbuf1[] =
4602 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4603 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4622 const char *addr =
"4.3.2.1";
4623 memset(&ssn, 0,
sizeof(ssn));
4628 f->
proto = IPPROTO_TCP;
4634 for (u = 0; u < httplen1; u++) {
4637 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4638 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4639 else flags = STREAM_TOSERVER;
4648 uint8_t ref1[] =
"/blah/";
4649 size_t reflen =
sizeof(ref1) - 1;
4651 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4653 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4655 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4657 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4671 static int HTPParserDecodingTest09(
void)
4674 uint8_t httpbuf1[] =
4675 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4676 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4688 uri-include-all: true\n\
4696 const char *addr =
"4.3.2.1";
4697 memset(&ssn, 0,
sizeof(ssn));
4702 f->
proto = IPPROTO_TCP;
4708 for (u = 0; u < httplen1; u++) {
4711 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4712 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4713 else flags = STREAM_TOSERVER;
4722 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
4723 size_t reflen =
sizeof(ref1) - 1;
4725 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4727 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4729 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4731 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4744 static int HTPBodyReassemblyTest01(
void)
4749 memset(&hstate, 0x00,
sizeof(hstate));
4751 memset(&flow, 0x00,
sizeof(flow));
4753 htp_cfg_t *cfg = htp_config_create();
4755 htp_connp_t *connp = htp_connp_create(cfg);
4757 const htp_tx_t *tx = htp_connp_get_request_tx(connp);
4763 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
4764 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";
4771 const uint8_t *chunks_buffer = NULL;
4772 uint32_t chunks_buffer_len = 0;
4774 HtpRequestBodyReassemble(htud, &chunks_buffer, &chunks_buffer_len);
4777 printf(
"REASSCHUNK START: \n");
4779 printf(
"REASSCHUNK END: \n");
4782 htud->
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
4783 strlen(
"multipart/form-data; boundary=toto"));
4786 HtpRequestBodyHandleMultipart(&hstate, htud, &tx, chunks_buffer, chunks_buffer_len,
false);
4792 htp_connp_destroy_all(connp);
4793 HtpTxUserDataFree(htud);
4795 htp_config_destroy(cfg);
4800 static int HTPSegvTest01(
void)
4803 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";
4804 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4812 double-decode-path: no\n\
4813 double-decode-query: no\n\
4814 request-body-limit: 0\n\
4815 response-body-limit: 0\n\
4828 memset(&ssn, 0,
sizeof(ssn));
4830 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4833 f->
proto = IPPROTO_TCP;
4838 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
4842 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
4863 static int HTPParserTest14(
void)
4874 double-decode-path: no\n\
4875 double-decode-query: no\n\
4876 request-body-limit: 0\n\
4877 response-body-limit: 0\n\
4882 memset(&ssn, 0,
sizeof(ssn));
4892 memset(httpbuf, 0x00,
len);
4895 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4896 "Host: myhost.lan\r\n"
4897 "Connection: keep-alive\r\n"
4899 "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"
4900 "Referer: http://blah.lan/\r\n"
4901 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
4903 size_t o = strlen(httpbuf);
4904 for ( ; o <
len - 4; o++) {
4907 httpbuf[
len - 4] =
'\r';
4908 httpbuf[
len - 3] =
'\n';
4909 httpbuf[
len - 2] =
'\r';
4910 httpbuf[
len - 1] =
'\n';
4916 f->
proto = IPPROTO_TCP;
4921 for (u = 0; u <
len; u++) {
4924 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4925 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4926 else flags = STREAM_TOSERVER;
4934 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4936 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
4937 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
4944 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG);
4959 static int HTPParserTest15(
void)
4962 char *httpbuf = NULL;
4973 double-decode-path: no\n\
4974 double-decode-query: no\n\
4975 request-body-limit: 0\n\
4976 response-body-limit: 0\n\
4977 meta-field-limit: 20000\n\
4981 memset(&ssn, 0,
sizeof(ssn));
4992 memset(httpbuf, 0x00,
len);
4995 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4996 "Host: myhost.lan\r\n"
4997 "Connection: keep-alive\r\n"
4999 "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"
5000 "Referer: http://blah.lan/\r\n"
5001 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5003 size_t o = strlen(httpbuf);
5004 for ( ; o <
len - 4; o++) {
5007 httpbuf[
len - 4] =
'\r';
5008 httpbuf[
len - 3] =
'\n';
5009 httpbuf[
len - 2] =
'\r';
5010 httpbuf[
len - 1] =
'\n';
5012 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5015 f->
proto = IPPROTO_TCP;
5021 for (u = 0; u <
len; u++) {
5024 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5025 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5026 else flags = STREAM_TOSERVER;
5035 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5037 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5038 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5057 static int HTPParserTest16(
void)
5064 memset(&ssn, 0,
sizeof(ssn));
5066 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5067 "Host: myhost.lan\r\n"
5068 "Connection: keep-alive\r\n"
5070 "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"
5071 "Referer: http://blah.lan/\r\n"
5072 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5073 "Cookie: blah\r\n\r\n";
5074 size_t len =
sizeof(httpbuf) - 1;
5076 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5079 f->
proto = IPPROTO_TCP;
5084 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5092 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5094 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5095 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5097 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5104 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT);
5105 FAIL_IF(decoder_events->
events[1] != HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT);
5116 static int HTPParserTest20(
void)
5119 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5120 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5121 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5122 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5123 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
5124 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5125 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5126 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5132 memset(&ssn, 0,
sizeof(ssn));
5134 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5137 f->
proto = IPPROTO_TCP;
5156 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5158 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5161 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5162 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5164 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5165 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5175 static int HTPParserTest21(
void)
5178 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5179 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5180 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5181 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5182 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
5183 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5184 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5185 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5191 memset(&ssn, 0,
sizeof(ssn));
5193 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5196 f->
proto = IPPROTO_TCP;
5215 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5217 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5220 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5221 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5223 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5224 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5234 static int HTPParserTest22(
void)
5237 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5238 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5239 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5240 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5241 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
5242 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5243 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5249 memset(&ssn, 0,
sizeof(ssn));
5251 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5254 f->
proto = IPPROTO_TCP;
5269 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5271 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5274 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5275 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5277 FAIL_IF(htp_tx_response_status_number(tx) != -0);
5278 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5288 static int HTPParserTest23(
void)
5291 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5292 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5293 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5294 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5295 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
5296 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5297 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5303 memset(&ssn, 0,
sizeof(ssn));
5305 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5308 f->
proto = IPPROTO_TCP;
5323 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5325 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5328 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5329 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5331 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5332 FAIL_IF(htp_tx_response_protocol_number(tx) != -2);
5343 static int HTPParserTest24(
void)
5346 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5347 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5348 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5349 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5350 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
5351 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5352 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5358 memset(&ssn, 0,
sizeof(ssn));
5360 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5363 f->
proto = IPPROTO_TCP;
5378 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5380 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5383 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5384 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5386 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5387 FAIL_IF(htp_tx_response_protocol_number(tx) != HTP_PROTOCOL_V1_0);
5397 static int HTPParserTest25(
void)
5404 memset(&ssn, 0,
sizeof(ssn));
5409 f->
proto = IPPROTO_TCP;
5413 const char *
str =
"GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
5415 (uint8_t *)
str, strlen(
str));
5439 str =
"HTTP 1.1 200 OK\r\nServer: Suricata/1.0\r\nContent-Length: 8\r\n\r\nSuricata";
5441 (uint8_t *)
str, strlen(
str));
5475 (uint8_t *)
str, strlen(
str));
5486 (uint8_t *)
str, strlen(
str));
5507 static int HTPParserTest26(
void)
5516 request-body-limit: 1\n\
5517 response-body-limit: 1\n\
5531 uint8_t httpbuf1[] =
"GET /alice.txt HTTP/1.1\r\n\r\n";
5532 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5533 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\n"
5534 "Content-Type: text/plain\r\n"
5535 "Content-Length: 228\r\n\r\n"
5536 "Alice was beginning to get very tired of sitting by her sister on the bank."
5537 "Alice was beginning to get very tired of sitting by her sister on the bank.";
5538 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5539 uint8_t httpbuf3[] =
"Alice was beginning to get very tired of sitting by her sister on the bank.\r\n\r\n";
5540 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5546 memset(&th_v, 0,
sizeof(th_v));
5548 memset(&f, 0,
sizeof(f));
5549 memset(&ssn, 0,
sizeof(ssn));
5556 f.
proto = IPPROTO_TCP;
5577 "(filestore; sid:1; rev:1;)");
5646 static int HTPParserTest27(
void)
5649 memset(&cfg, 0,
sizeof(cfg));
5653 uint32_t
len = 1000;
5678 static void HTPParserRegisterTests(
void)
5700 UtRegisterTest(
"HTPParserDecodingTest01", HTPParserDecodingTest01);
5701 UtRegisterTest(
"HTPParserDecodingTest01a", HTPParserDecodingTest01a);
5702 UtRegisterTest(
"HTPParserDecodingTest02", HTPParserDecodingTest02);
5703 UtRegisterTest(
"HTPParserDecodingTest03", HTPParserDecodingTest03);
5704 UtRegisterTest(
"HTPParserDecodingTest04", HTPParserDecodingTest04);
5705 UtRegisterTest(
"HTPParserDecodingTest05", HTPParserDecodingTest05);
5706 UtRegisterTest(
"HTPParserDecodingTest06", HTPParserDecodingTest06);
5707 UtRegisterTest(
"HTPParserDecodingTest07", HTPParserDecodingTest07);
5708 UtRegisterTest(
"HTPParserDecodingTest08", HTPParserDecodingTest08);
5709 UtRegisterTest(
"HTPParserDecodingTest09", HTPParserDecodingTest09);
5711 UtRegisterTest(
"HTPBodyReassemblyTest01", HTPBodyReassemblyTest01);