78 static struct HTPConfigTree {
94 #define HTP_MAX_MESSAGES 512
100 static uint64_t htp_state_memuse = 0;
101 static uint64_t htp_state_memcnt = 0;
105 {
"UNKNOWN_ERROR", HTP_LOG_CODE_UNKNOWN },
106 {
"GZIP_DECOMPRESSION_FAILED", HTP_LOG_CODE_GZIP_DECOMPRESSION_FAILED },
107 {
"REQUEST_FIELD_MISSING_COLON", HTP_LOG_CODE_REQUEST_FIELD_MISSING_COLON },
108 {
"RESPONSE_FIELD_MISSING_COLON", HTP_LOG_CODE_RESPONSE_FIELD_MISSING_COLON },
109 {
"INVALID_REQUEST_CHUNK_LEN", HTP_LOG_CODE_INVALID_REQUEST_CHUNK_LEN },
110 {
"INVALID_RESPONSE_CHUNK_LEN", HTP_LOG_CODE_INVALID_RESPONSE_CHUNK_LEN },
111 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST",
112 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST },
113 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE",
114 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE },
115 {
"INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST",
116 HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST },
117 {
"INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE",
118 HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE },
119 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST",
120 HTP_LOG_CODE_DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST },
121 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE",
122 HTP_LOG_CODE_DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE },
123 {
"100_CONTINUE_ALREADY_SEEN", HTP_LOG_CODE_CONTINUE_ALREADY_SEEN },
124 {
"UNABLE_TO_MATCH_RESPONSE_TO_REQUEST", HTP_LOG_CODE_UNABLE_TO_MATCH_RESPONSE_TO_REQUEST },
125 {
"INVALID_SERVER_PORT_IN_REQUEST", HTP_LOG_CODE_INVALID_SERVER_PORT_IN_REQUEST },
126 {
"INVALID_AUTHORITY_PORT", HTP_LOG_CODE_INVALID_AUTHORITY_PORT },
127 {
"REQUEST_HEADER_INVALID", HTP_LOG_CODE_REQUEST_HEADER_INVALID },
128 {
"RESPONSE_HEADER_INVALID", HTP_LOG_CODE_RESPONSE_HEADER_INVALID },
129 {
"MISSING_HOST_HEADER", HTP_LOG_CODE_MISSING_HOST_HEADER },
130 {
"HOST_HEADER_AMBIGUOUS", HTP_LOG_CODE_HOST_HEADER_AMBIGUOUS },
131 {
"INVALID_REQUEST_FIELD_FOLDING", HTP_LOG_CODE_INVALID_REQUEST_FIELD_FOLDING },
132 {
"INVALID_RESPONSE_FIELD_FOLDING", HTP_LOG_CODE_INVALID_RESPONSE_FIELD_FOLDING },
133 {
"REQUEST_FIELD_TOO_LONG", HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG },
134 {
"RESPONSE_FIELD_TOO_LONG", HTP_LOG_CODE_RESPONSE_FIELD_TOO_LONG },
135 {
"REQUEST_LINE_INVALID", HTP_LOG_CODE_REQUEST_LINE_INVALID },
136 {
"REQUEST_BODY_UNEXPECTED", HTP_LOG_CODE_REQUEST_BODY_UNEXPECTED },
137 {
"RESPONSE_BODY_UNEXPECTED", HTP_LOG_CODE_RESPONSE_BODY_UNEXPECTED },
138 {
"REQUEST_SERVER_PORT_TCP_PORT_MISMATCH", HTP_LOG_CODE_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH },
139 {
"REQUEST_URI_HOST_INVALID", HTP_LOG_CODE_URI_HOST_INVALID },
140 {
"REQUEST_HEADER_HOST_INVALID", HTP_LOG_CODE_HEADER_HOST_INVALID },
141 {
"REQUEST_AUTH_UNRECOGNIZED", HTP_LOG_CODE_AUTH_UNRECOGNIZED },
142 {
"REQUEST_HEADER_REPETITION", HTP_LOG_CODE_REQUEST_HEADER_REPETITION },
143 {
"RESPONSE_HEADER_REPETITION", HTP_LOG_CODE_RESPONSE_HEADER_REPETITION },
144 {
"DOUBLE_ENCODED_URI", HTP_LOG_CODE_DOUBLE_ENCODED_URI },
145 {
"URI_DELIM_NON_COMPLIANT", HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT },
146 {
"METHOD_DELIM_NON_COMPLIANT", HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT },
147 {
"REQUEST_LINE_LEADING_WHITESPACE", HTP_LOG_CODE_REQUEST_LINE_LEADING_WHITESPACE },
148 {
"TOO_MANY_ENCODING_LAYERS", HTP_LOG_CODE_TOO_MANY_ENCODING_LAYERS },
149 {
"REQUEST_TOO_MANY_LZMA_LAYERS", HTP_LOG_CODE_REQUEST_TOO_MANY_LZMA_LAYERS },
150 {
"RESPONSE_TOO_MANY_LZMA_LAYERS", HTP_LOG_CODE_RESPONSE_TOO_MANY_LZMA_LAYERS },
151 {
"ABNORMAL_CE_HEADER", HTP_LOG_CODE_ABNORMAL_CE_HEADER },
152 {
"RESPONSE_MULTIPART_BYTERANGES", HTP_LOG_CODE_RESPONSE_MULTIPART_BYTERANGES },
153 {
"RESPONSE_ABNORMAL_TRANSFER_ENCODING", HTP_LOG_CODE_RESPONSE_ABNORMAL_TRANSFER_ENCODING },
154 {
"RESPONSE_CHUNKED_OLD_PROTO", HTP_LOG_CODE_RESPONSE_CHUNKED_OLD_PROTO },
155 {
"RESPONSE_INVALID_PROTOCOL", HTP_LOG_CODE_RESPONSE_INVALID_PROTOCOL },
156 {
"RESPONSE_INVALID_STATUS", HTP_LOG_CODE_RESPONSE_INVALID_STATUS },
157 {
"REQUEST_LINE_INCOMPLETE", HTP_LOG_CODE_REQUEST_LINE_INCOMPLETE },
158 {
"PROTOCOL_CONTAINS_EXTRA_DATA", HTP_LOG_CODE_PROTOCOL_CONTAINS_EXTRA_DATA },
160 "CONTENT_LENGTH_EXTRA_DATA_START",
161 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_START,
164 "CONTENT_LENGTH_EXTRA_DATA_END",
165 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_END,
168 "CONTENT_LENGTH_EXTRA_DATA_END",
169 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_END,
171 {
"SWITCHING_PROTO_WITH_CONTENT_LENGTH", HTP_LOG_CODE_SWITCHING_PROTO_WITH_CONTENT_LENGTH },
172 {
"DEFORMED_EOL", HTP_LOG_CODE_DEFORMED_EOL },
173 {
"PARSER_STATE_ERROR", HTP_LOG_CODE_PARSER_STATE_ERROR },
174 {
"MISSING_OUTBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_OUTBOUND_TRANSACTION_DATA },
175 {
"MISSING_INBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_INBOUND_TRANSACTION_DATA },
176 {
"MISSING_INBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_INBOUND_TRANSACTION_DATA },
177 {
"ZERO_LENGTH_DATA_CHUNKS", HTP_LOG_CODE_ZERO_LENGTH_DATA_CHUNKS },
178 {
"REQUEST_LINE_UNKNOWN_METHOD", HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD },
179 {
"REQUEST_LINE_UNKNOWN_METHOD", HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD },
180 {
"REQUEST_LINE_UNKNOWN_METHOD_NO_PROTOCOL",
181 HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD_NO_PROTOCOL },
182 {
"REQUEST_LINE_UNKNOWN_METHOD_INVALID_PROTOCOL",
183 HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD_INVALID_PROTOCOL },
184 {
"REQUEST_LINE_MISSING_PROTOCOL", HTP_LOG_CODE_REQUEST_LINE_NO_PROTOCOL },
185 {
"RESPONSE_LINE_INVALID_PROTOCOL", HTP_LOG_CODE_RESPONSE_LINE_INVALID_PROTOCOL },
186 {
"RESPONSE_LINE_INVALID_RESPONSE_STATUS", HTP_LOG_CODE_RESPONSE_LINE_INVALID_RESPONSE_STATUS },
187 {
"RESPONSE_BODY_INTERNAL_ERROR", HTP_LOG_CODE_RESPONSE_BODY_INTERNAL_ERROR },
188 {
"REQUEST_BODY_DATA_CALLBACK_ERROR", HTP_LOG_CODE_REQUEST_BODY_DATA_CALLBACK_ERROR },
189 {
"RESPONSE_INVALID_EMPTY_NAME", HTP_LOG_CODE_RESPONSE_INVALID_EMPTY_NAME },
190 {
"REQUEST_INVALID_EMPTY_NAME", HTP_LOG_CODE_REQUEST_INVALID_EMPTY_NAME },
191 {
"RESPONSE_INVALID_LWS_AFTER_NAME", HTP_LOG_CODE_RESPONSE_INVALID_LWS_AFTER_NAME },
192 {
"RESPONSE_HEADER_NAME_NOT_TOKEN", HTP_LOG_CODE_RESPONSE_HEADER_NAME_NOT_TOKEN },
193 {
"REQUEST_INVALID_LWS_AFTER_NAME", HTP_LOG_CODE_REQUEST_INVALID_LWS_AFTER_NAME },
194 {
"LZMA_DECOMPRESSION_DISABLED", HTP_LOG_CODE_LZMA_DECOMPRESSION_DISABLED },
195 {
"CONNECTION_ALREADY_OPEN", HTP_LOG_CODE_CONNECTION_ALREADY_OPEN },
196 {
"COMPRESSION_BOMB_DOUBLE_LZMA", HTP_LOG_CODE_COMPRESSION_BOMB_DOUBLE_LZMA },
197 {
"INVALID_CONTENT_ENCODING", HTP_LOG_CODE_INVALID_CONTENT_ENCODING },
198 {
"INVALID_GAP", HTP_LOG_CODE_INVALID_GAP },
199 {
"REQUEST_CHUNK_EXTENSION", HTP_LOG_CODE_REQUEST_CHUNK_EXTENSION },
200 {
"RESPONSE_CHUNK_EXTENSION", HTP_LOG_CODE_RESPONSE_CHUNK_EXTENSION },
202 {
"LZMA_MEMLIMIT_REACHED", HTP_LOG_CODE_LZMA_MEMLIMIT_REACHED },
203 {
"COMPRESSION_BOMB", HTP_LOG_CODE_COMPRESSION_BOMB },
205 {
"REQUEST_TOO_MANY_HEADERS", HTP_LOG_CODE_REQUEST_TOO_MANY_HEADERS },
206 {
"RESPONSE_TOO_MANY_HEADERS", HTP_LOG_CODE_RESPONSE_TOO_MANY_HEADERS },
239 static int HTTPGetFrameIdByName(
const char *frame_name)
248 static const char *HTTPGetFrameNameById(
const uint8_t frame_id)
258 HTP_REQUEST_PROGRESS_NOT_STARTED,
262 HTP_REQUEST_PROGRESS_LINE,
266 HTP_REQUEST_PROGRESS_HEADERS,
270 HTP_REQUEST_PROGRESS_BODY,
274 HTP_REQUEST_PROGRESS_TRAILER,
278 HTP_REQUEST_PROGRESS_COMPLETE,
287 HTP_RESPONSE_PROGRESS_NOT_STARTED,
291 HTP_RESPONSE_PROGRESS_LINE,
295 HTP_RESPONSE_PROGRESS_HEADERS,
299 HTP_RESPONSE_PROGRESS_BODY,
303 HTP_RESPONSE_PROGRESS_TRAILER,
307 HTP_RESPONSE_PROGRESS_COMPLETE,
312 static int HtpStateGetStateIdByName(
const char *
name,
const uint8_t direction)
315 direction == STREAM_TOSERVER ? http_state_client_table : http_state_server_table;
324 static const char *HtpStateGetStateNameById(
const int id,
const uint8_t direction)
327 direction == STREAM_TOSERVER ? http_state_client_table : http_state_server_table;
332 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id);
333 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction);
334 static uint64_t HTPStateGetTxCnt(
void *alstate);
336 static void HTPParserRegisterTests(
void);
339 static inline uint64_t HtpGetActiveRequestTxID(
HtpState *s)
341 uint64_t
id = HTPStateGetTxCnt(s);
346 static inline uint64_t HtpGetActiveResponseTxID(
HtpState *s)
359 static const char *HTPLookupPersonalityString(
int p)
361 #define CASE_HTP_PERSONALITY_STRING(p) \
362 case HTP_SERVER_PERSONALITY_##p: \
366 CASE_HTP_PERSONALITY_STRING(MINIMAL);
367 CASE_HTP_PERSONALITY_STRING(GENERIC);
368 CASE_HTP_PERSONALITY_STRING(IDS);
369 CASE_HTP_PERSONALITY_STRING(IIS_4_0);
370 CASE_HTP_PERSONALITY_STRING(IIS_5_0);
371 CASE_HTP_PERSONALITY_STRING(IIS_5_1);
372 CASE_HTP_PERSONALITY_STRING(IIS_6_0);
373 CASE_HTP_PERSONALITY_STRING(IIS_7_0);
374 CASE_HTP_PERSONALITY_STRING(IIS_7_5);
375 CASE_HTP_PERSONALITY_STRING(APACHE_2);
389 static int HTPLookupPersonality(
const char *
str)
391 #define IF_HTP_PERSONALITY_NUM(p) \
392 if (strcasecmp(#p, str) == 0) \
393 return HTP_SERVER_PERSONALITY_##p
405 if (strcasecmp(
"TOMCAT_6_0",
str) == 0) {
407 "longer supported by libhtp.",
410 }
else if ((strcasecmp(
"APACHE",
str) == 0) ||
411 (strcasecmp(
"APACHE_2_2",
str) == 0))
414 "longer supported by libhtp, failing back to "
415 "Apache2 personality.",
417 return HTP_SERVER_PERSONALITY_APACHE_2;
424 const uint8_t dir,
const uint8_t e)
434 const uint64_t tx_id = (dir == STREAM_TOSERVER) ?
435 HtpGetActiveRequestTxID(s) : HtpGetActiveResponseTxID(s);
437 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
438 if (tx == NULL && tx_id > 0)
439 tx = HTPStateGetTx(s, tx_id - 1);
452 static void *HTPStateAlloc(
void *orig_state,
AppProto proto_orig)
466 htp_state_memuse +=
sizeof(
HtpState);
467 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
474 static void HtpTxUserDataFree(
void *txud)
486 SCAppLayerTxDataCleanup(&htud->
tx_data);
510 if (s->
connp != NULL) {
512 htp_connp_destroy_all(s->
connp);
520 htp_state_memuse -=
sizeof(
HtpState);
521 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
532 static void HTPStateTransactionFree(
void *state, uint64_t
id)
540 htp_tx_t *tx = HTPStateGetTx(s,
id);
542 htp_tx_destroy(s->
connp, tx);
588 static void AppLayerHtpSetStreamDepthFlag(
void *tx,
const uint8_t
flags)
592 if (
flags & STREAM_TOCLIENT) {
601 SCLogDebug(
"cfg->body_limit %u stream_depth %u body->content_len_so_far %" PRIu64,
618 static uint32_t AppLayerHtpComputeChunkLength(uint64_t content_len_so_far, uint32_t body_limit,
619 uint32_t stream_depth, uint8_t
flags, uint32_t data_len)
621 uint32_t chunk_len = 0;
623 (content_len_so_far < (uint64_t)body_limit) &&
624 (content_len_so_far + (uint64_t)data_len) > body_limit)
626 chunk_len = (uint32_t)(body_limit - content_len_so_far);
628 (content_len_so_far < (uint64_t)stream_depth) &&
629 (content_len_so_far + (uint64_t)data_len) > stream_depth)
631 chunk_len = (uint32_t)(stream_depth - content_len_so_far);
634 return (chunk_len == 0 ? data_len : chunk_len);
645 static void HTPHandleError(
HtpState *s,
const uint8_t dir)
652 htp_log_t *log = htp_conn_next_log(s->
conn);
653 while (log != NULL) {
654 char *msg = htp_log_message(log);
657 log = htp_conn_next_log(s->
conn);
663 htp_log_code_t
id = htp_log_code(log);
664 if (
id != HTP_LOG_CODE_UNKNOWN &&
id != HTP_LOG_CODE_ERROR) {
665 HTPSetEvent(s, NULL, dir, (uint8_t)
id);
667 htp_free_cstring(msg);
677 log = htp_conn_next_log(s->
conn);
682 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s,
const htp_tx_t *tx)
685 BUG_ON(s == NULL || tx == NULL);
687 if (htp_tx_flags(tx) & (HTP_FLAGS_REQUEST_INVALID_T_E | HTP_FLAGS_REQUEST_INVALID_C_L |
688 HTP_FLAGS_HOST_MISSING | HTP_FLAGS_HOST_AMBIGUOUS |
689 HTP_FLAGS_HOSTU_INVALID | HTP_FLAGS_HOSTH_INVALID)) {
692 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_T_E)
693 HTPSetEvent(s, htud, STREAM_TOSERVER,
694 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST);
695 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_C_L)
697 s, htud, STREAM_TOSERVER, HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST);
698 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_MISSING)
699 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_MISSING_HOST_HEADER);
700 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_AMBIGUOUS)
701 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HOST_HEADER_AMBIGUOUS);
702 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTU_INVALID)
703 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_URI_HOST_INVALID);
704 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTH_INVALID)
705 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HEADER_HOST_INVALID);
707 if (htp_tx_request_auth_type(tx) == HTP_AUTH_TYPE_UNRECOGNIZED) {
709 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_AUTH_UNRECOGNIZED);
711 if (htp_tx_is_protocol_0_9(tx) && htp_tx_request_method_number(tx) == HTP_METHOD_UNKNOWN &&
712 (htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_INVALID ||
713 htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_UNKNOWN)) {
715 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_REQUEST_LINE_INVALID);
725 htp_cfg_t *htp = cfglist.
cfg;
726 void *user_data = NULL;
742 if (user_data != NULL) {
743 htp_cfg_rec = user_data;
744 htp = htp_cfg_rec->
cfg;
747 SCLogDebug(
"Using default HTP config: %p", htp);
751 #ifdef DEBUG_VALIDATION
758 hstate->
connp = htp_connp_create(htp);
759 if (hstate->
connp == NULL) {
763 hstate->
conn = (htp_conn_t *)htp_connp_connection(hstate->
connp);
765 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
766 hstate->
cfg = htp_cfg_rec;
771 htp_connp_open(hstate->
connp, NULL, f->
sp, NULL, f->
dp, &
tv);
793 StreamSlice stream_slice,
void *local_data)
803 if (NULL == hstate->
conn) {
804 if (Setup(f, hstate) != 0) {
809 hstate->
slice = &stream_slice;
811 const uint8_t *input = StreamSliceGetData(&stream_slice);
812 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
817 const int r = htp_connp_request_data(hstate->
connp, &
ts, input, input_len);
819 case HTP_STREAM_STATE_ERROR:
825 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;
860 StreamSlice stream_slice,
void *local_data)
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);
947 htp_connp_close(hstate->
connp, &
ts);
952 hstate->
slice = NULL;
963 static int HTTPParseContentDispositionHeader(
const uint8_t *
name,
size_t name_len,
964 const uint8_t *data,
size_t len, uint8_t
const **retptr,
size_t *retlen)
967 printf(
"DATA START: \n");
969 printf(
"DATA END: \n");
974 for (x = 0; x <
len; x++) {
975 if (!(isspace(data[x])))
982 const uint8_t *line = data + x;
983 size_t line_len =
len-x;
986 printf(
"LINE START: \n");
988 printf(
"LINE END: \n");
990 for (x = 0 ; x < line_len; x++) {
992 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
996 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
997 const uint8_t *token = line +
offset;
998 size_t token_len = x -
offset;
1000 if ((x + 1) == line_len) {
1011 printf(
"TOKEN START: \n");
1013 printf(
"TOKEN END: \n");
1015 if (token_len > name_len) {
1016 if (
name == NULL || SCMemcmpLowercase(
name, token, name_len) == 0) {
1017 const uint8_t *value = token + name_len;
1018 size_t value_len = token_len - name_len;
1020 if (value[0] ==
'\"') {
1024 if (value[value_len-1] ==
'\"') {
1028 printf(
"VALUE START: \n");
1030 printf(
"VALUE END: \n");
1033 *retlen = value_len;
1057 static int HtpRequestBodySetupMultipart(
const htp_tx_t *tx,
HtpTxUserData *htud)
1059 const htp_header_t *h = htp_tx_request_header(tx,
"Content-Type");
1060 if (h != NULL && htp_header_value_len(h) > 0) {
1062 SCMimeStateInit(htp_header_value_ptr(h), (uint32_t)htp_header_value_len(h));
1079 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1082 chunks_buffer, chunks_buffer_len,
1086 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1089 if (tx && tx->
tx_data.de_state) {
1090 if (dir == STREAM_TOSERVER) {
1091 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1093 }
else if (dir == STREAM_TOCLIENT) {
1094 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1101 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len,
bool eof)
1104 printf(
"CHUNK START: \n");
1106 printf(
"CHUNK END: \n");
1112 STREAM_TOSERVER) >= HTP_REQUEST_PROGRESS_COMPLETE);
1114 const uint8_t *cur_buf = chunks_buffer;
1115 uint32_t cur_buf_len = chunks_buffer_len;
1131 const uint8_t *filename = NULL;
1132 uint16_t filename_len = 0;
1135 while (cur_buf_len > 0) {
1136 MimeParserResult r =
1137 SCMimeParse(htud->
mime_state, cur_buf, cur_buf_len, &consumed, &warnings);
1141 if (warnings & MIME_EVENT_FLAG_INVALID_HEADER) {
1145 if (warnings & MIME_EVENT_FLAG_NO_FILEDATA) {
1156 SCMimeStateGetFilename(htud->
mime_state, &filename, &filename_len);
1157 if (filename_len > 0) {
1161 hstate, htud, filename, filename_len, NULL, 0, STREAM_TOSERVER);
1164 }
else if (result == -2) {
1167 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1175 }
else if (result == -2) {
1183 uint32_t lastsize = consumed;
1184 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\n') {
1186 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\r') {
1190 HTPFileClose(htud, cur_buf, lastsize, 0, STREAM_TOSERVER);
1195 cur_buf += consumed;
1196 cur_buf_len -= consumed;
1208 const uint8_t *data, uint32_t data_len)
1215 uint8_t *filename = NULL;
1216 size_t filename_len = 0;
1219 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1220 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1221 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1224 if (filename != NULL) {
1230 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1234 }
else if (result == -2) {
1237 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1251 }
else if (result == -2) {
1264 const uint8_t *data, uint32_t data_len)
1277 const uint8_t *filename = NULL;
1278 size_t filename_len = 0;
1281 const htp_header_t *h = htp_tx_response_header(tx,
"Content-Disposition");
1282 if (h != NULL && htp_header_value_len(h) > 0) {
1284 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1285 htp_header_value_ptr(h), htp_header_value_len(h), &filename, &filename_len);
1289 if (filename == NULL) {
1291 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1292 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1293 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1297 if (filename != NULL) {
1299 const htp_header_t *h_content_range = htp_tx_response_header(tx,
"content-range");
1305 if (h_content_range != NULL) {
1307 data_len, tx, htp_header_value(h_content_range), htud);
1309 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1315 }
else if (result == -2) {
1318 FlagDetectStateNewFile(htud, STREAM_TOCLIENT);
1331 }
else if (result == -2) {
1349 static int HTPCallbackRequestBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1353 const htp_tx_t *tx = htp_tx_data_tx(d);
1358 if (htp_tx_data_is_empty(d))
1362 printf(
"HTPBODY START: \n");
1363 PrintRawDataFp(stdout, (uint8_t *)htp_tx_data_data(d), htp_tx_data_len(d));
1364 printf(
"HTPBODY END: \n");
1367 HtpState *hstate = htp_connp_user_data(connp);
1368 if (hstate == NULL) {
1372 SCLogDebug(
"New request body data available at %p -> %p -> %p, bodylen "
1374 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1377 if (tx_ud == NULL) {
1380 tx_ud->
tx_data.updated_ts =
true;
1386 if (htp_tx_request_method_number(tx) == HTP_METHOD_POST) {
1388 int r = HtpRequestBodySetupMultipart(tx, tx_ud);
1391 }
else if (r == 0) {
1395 }
else if (htp_tx_request_method_number(tx) == HTP_METHOD_PUT) {
1411 (uint32_t)htp_tx_data_len(d));
1412 BUG_ON(
len > (uint32_t)htp_tx_data_len(d));
1416 const uint8_t *chunks_buffer = NULL;
1417 uint32_t chunks_buffer_len = 0;
1425 HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len);
1426 if (chunks_buffer == NULL) {
1430 printf(
"REASSCHUNK START: \n");
1432 printf(
"REASSCHUNK END: \n");
1435 HtpRequestBodyHandleMultipart(hstate, tx_ud, htp_tx_data_tx(d), chunks_buffer,
1436 chunks_buffer_len, (htp_tx_data_data(d) == NULL && htp_tx_data_len(d) == 0));
1440 HtpRequestBodyHandlePOSTorPUT(
1441 hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1446 SCLogDebug(
"closing file that was being stored");
1453 if (hstate->
conn != NULL) {
1454 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1455 ", last %" PRIu64
")",
1457 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1466 if ((uint64_t)htp_conn_request_data_counter(hstate->
conn) >
1468 (uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1470 (uint64_t)UINT_MAX) {
1471 uint32_t data_size =
1472 (uint32_t)((uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1493 static int HTPCallbackResponseBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1497 const htp_tx_t *tx = htp_tx_data_tx(d);
1502 if (htp_tx_data_is_empty(d))
1505 HtpState *hstate = htp_connp_user_data(connp);
1506 if (hstate == NULL) {
1510 SCLogDebug(
"New response body data available at %p -> %p -> %p, bodylen "
1512 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1515 tx_ud->
tx_data.updated_tc =
true;
1532 (uint32_t)htp_tx_data_len(d));
1533 BUG_ON(
len > (uint32_t)htp_tx_data_len(d));
1537 HtpResponseBodyHandle(hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1540 SCLogDebug(
"closing file that was being stored");
1546 if (hstate->
conn != NULL) {
1547 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1548 ", last %" PRIu64
")",
1550 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1558 if ((uint64_t)htp_conn_response_data_counter(hstate->
conn) >
1560 (uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1562 (uint64_t)UINT_MAX) {
1563 uint32_t data_size =
1564 (uint32_t)((uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1588 SCLogDebug(
"http_state_memcnt %"PRIu64
", http_state_memuse %"PRIu64
"",
1589 htp_state_memcnt, htp_state_memuse);
1607 htp_config_destroy(cfglist.
cfg);
1608 while (nextrec != NULL) {
1610 nextrec = nextrec->
next;
1612 htp_config_destroy(htprec->
cfg);
1620 static int HTPCallbackRequestHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1623 htud->
tx_data.updated_ts =
true;
1625 return HTP_STATUS_OK;
1628 static int HTPCallbackResponseHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1631 htud->
tx_data.updated_tc =
true;
1633 return HTP_STATUS_OK;
1636 static void *HTPCallbackTxCreate(
bool request)
1644 tx_ud->
tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT;
1646 tx_ud->
tx_data.file_tx = STREAM_TOCLIENT;
1655 static int HTPCallbackRequestStart(
const htp_connp_t *connp, htp_tx_t *tx)
1657 HtpState *hstate = htp_connp_user_data(connp);
1658 if (hstate == NULL) {
1662 uint64_t consumed = hstate->
slice->offset + htp_connp_request_data_consumed(hstate->
connp);
1663 SCLogDebug(
"HTTP request start: data offset %" PRIu64
", in_data_counter %" PRIu64, consumed,
1664 (uint64_t)htp_conn_request_data_counter(hstate->
conn));
1680 tx_ud->
tx_data.updated_ts =
true;
1688 static int HTPCallbackResponseStart(
const htp_connp_t *connp, htp_tx_t *tx)
1690 HtpState *hstate = htp_connp_user_data(connp);
1691 if (hstate == NULL) {
1695 uint64_t consumed = hstate->
slice->offset + htp_connp_response_data_consumed(hstate->
connp);
1696 SCLogDebug(
"HTTP response start: data offset %" PRIu64
", out_data_counter %" PRIu64, consumed,
1697 (uint64_t)htp_conn_response_data_counter(hstate->
conn));
1712 tx_ud->
tx_data.updated_tc =
true;
1722 static int HTPCallbackRequestComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1730 HtpState *hstate = htp_connp_user_data(connp);
1731 if (hstate == NULL) {
1735 const uint64_t abs_right_edge =
1736 hstate->
slice->offset + htp_connp_request_data_consumed(hstate->
connp);
1744 SCLogDebug(
"HTTP request complete: data offset %" PRIu64
", request_size %" PRIu64,
1746 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1748 frame->
len = (int64_t)request_size;
1754 SCLogDebug(
"transaction_cnt %"PRIu64
", list_size %"PRIu64,
1759 HTPErrorCheckTxRequestFlags(hstate, tx);
1762 htud->
tx_data.updated_ts =
true;
1764 SCLogDebug(
"closing file that was being stored");
1767 if (abs_right_edge < (uint64_t)UINT32_MAX) {
1769 hstate->
f->
protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
1786 static int HTPCallbackResponseComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1790 HtpState *hstate = htp_connp_user_data(connp);
1791 if (hstate == NULL) {
1798 const uint64_t abs_right_edge =
1799 hstate->
slice->offset + htp_connp_response_data_consumed(hstate->
connp);
1806 SCLogDebug(
"HTTP response complete: data offset %" PRIu64
", response_size %" PRIu64,
1808 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1810 frame->
len = (int64_t)response_size;
1816 htud->
tx_data.updated_tc =
true;
1818 SCLogDebug(
"closing file that was being stored");
1828 if (htp_tx_request_method_number(tx) == HTP_METHOD_CONNECT) {
1831 if ((htp_tx_response_status_number(tx) >= 200) &&
1832 (htp_tx_response_status_number(tx) < 300) && (hstate->
transaction_cnt == 1)) {
1834 if (htp_tx_request_port_number(tx) != -1) {
1835 dp = (uint16_t)htp_tx_request_port_number(tx);
1849 static int HTPCallbackRequestLine(
const htp_connp_t *connp, htp_tx_t *tx)
1851 HtpState *hstate = htp_connp_user_data(connp);
1853 if (htp_tx_flags(tx)) {
1854 HTPErrorCheckTxRequestFlags(hstate, tx);
1856 return HTP_STATUS_OK;
1859 static int HTPCallbackRequestHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1862 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1863 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1864 return HTP_STATUS_OK;
1870 return HTP_STATUS_OK;
1873 tx_ud->
tx_data.updated_ts =
true;
1876 htp_tx_data_len(tx_data));
1879 if (tx && htp_tx_flags(tx)) {
1880 HtpState *hstate = htp_connp_user_data(connp);
1881 HTPErrorCheckTxRequestFlags(hstate, tx);
1883 return HTP_STATUS_OK;
1886 static int HTPCallbackResponseHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1889 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1890 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1891 return HTP_STATUS_OK;
1894 tx_ud->
tx_data.updated_tc =
true;
1898 return HTP_STATUS_OK;
1903 htp_tx_data_len(tx_data));
1906 return HTP_STATUS_OK;
1912 static void HTPConfigSetDefaultsPhase1(
HTPCfgRec *cfg_prec)
1914 htp_config_set_normalized_uri_include_all(cfg_prec->
cfg,
false);
1929 htp_config_register_request_header_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1930 htp_config_register_request_trailer_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1931 htp_config_register_response_header_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1932 htp_config_register_response_trailer_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1934 htp_config_register_request_trailer(cfg_prec->
cfg, HTPCallbackRequestHasTrailer);
1935 htp_config_register_response_trailer(cfg_prec->
cfg, HTPCallbackResponseHasTrailer);
1937 htp_config_register_request_body_data(cfg_prec->
cfg, HTPCallbackRequestBodyData);
1938 htp_config_register_response_body_data(cfg_prec->
cfg, HTPCallbackResponseBodyData);
1940 htp_config_register_tx_create(cfg_prec->
cfg, HTPCallbackTxCreate);
1941 htp_config_register_tx_destroy(cfg_prec->
cfg, HtpTxUserDataFree);
1943 htp_config_register_request_start(cfg_prec->
cfg, HTPCallbackRequestStart);
1944 htp_config_register_request_complete(cfg_prec->
cfg, HTPCallbackRequestComplete);
1946 htp_config_register_response_start(cfg_prec->
cfg, HTPCallbackResponseStart);
1947 htp_config_register_response_complete(cfg_prec->
cfg, HTPCallbackResponseComplete);
1949 htp_config_set_parse_request_cookies(cfg_prec->
cfg, 0);
1950 htp_config_set_allow_space_uri(cfg_prec->
cfg, 1);
1953 htp_config_set_plusspace_decode(cfg_prec->
cfg, 0);
1955 htp_config_set_request_decompression(cfg_prec->
cfg, 1);
1960 #define HTP_CONFIG_DEFAULT_MAX_TX_LIMIT 512
1962 #define HTP_CONFIG_DEFAULT_HEADERS_LIMIT 1024
1970 static int RandomGetWrap(
void)
1976 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
1978 return r % RAND_MAX;
1987 static void HTPConfigSetDefaultsPhase2(
const char *
name,
HTPCfgRec *cfg_prec)
1993 long int r = RandomGetWrap();
1995 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
1997 r = RandomGetWrap();
1999 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2000 SCLogConfig(
"'%s' server has 'request-body-minimal-inspect-size' set to"
2001 " %u and 'request-body-inspect-window' set to %u after"
2005 r = RandomGetWrap();
2007 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2009 r = RandomGetWrap();
2011 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2013 SCLogConfig(
"'%s' server has 'response-body-minimal-inspect-size' set to"
2014 " %u and 'response-body-inspect-window' set to %u after"
2019 htp_config_register_request_line(cfg_prec->
cfg, HTPCallbackRequestLine);
2022 static void HTPConfigParseParameters(
HTPCfgRec *cfg_prec,
SCConfNode *s,
struct HTPConfigTree *tree)
2024 if (cfg_prec == NULL || s == NULL || tree == NULL)
2031 if (strcasecmp(
"address", p->
name) == 0) {
2037 if (strchr(pval->
val,
':') != NULL) {
2038 SCLogDebug(
"LIBHTP adding ipv6 server %s at %s: %p",
2042 SCLogWarning(
"LIBHTP failed to add ipv6 server %s, ignoring", pval->
val);
2045 SCLogDebug(
"LIBHTP adding ipv4 server %s at %s: %p",
2049 SCLogWarning(
"LIBHTP failed to add ipv4 server %s, ignoring", pval->
val);
2054 }
else if (strcasecmp(
"personality", p->
name) == 0) {
2056 int personality = HTPLookupPersonality(p->
val);
2060 if (personality >= 0) {
2063 if (htp_config_set_server_personality(cfg_prec->
cfg, personality) ==
2066 "personality \"%s\", ignoring",
2070 HTPLookupPersonalityString(personality));
2076 htp_config_set_convert_lowercase(cfg_prec->
cfg, 0);
2084 }
else if (strcasecmp(
"request-body-limit", p->
name) == 0 ||
2085 strcasecmp(
"request_body_limit", p->
name) == 0) {
2087 SCLogError(
"Error parsing request-body-limit "
2088 "from conf file - %s. Killing engine",
2093 }
else if (strcasecmp(
"response-body-limit", p->
name) == 0) {
2095 SCLogError(
"Error parsing response-body-limit "
2096 "from conf file - %s. Killing engine",
2101 }
else if (strcasecmp(
"request-body-minimal-inspect-size", p->
name) == 0) {
2103 SCLogError(
"Error parsing request-body-minimal-inspect-size "
2104 "from conf file - %s. Killing engine",
2109 }
else if (strcasecmp(
"request-body-inspect-window", p->
name) == 0) {
2111 SCLogError(
"Error parsing request-body-inspect-window "
2112 "from conf file - %s. Killing engine",
2117 }
else if (strcasecmp(
"double-decode-query", p->
name) == 0) {
2119 }
else if (strcasecmp(
"double-decode-path", p->
name) == 0) {
2121 }
else if (strcasecmp(
"response-body-minimal-inspect-size", p->
name) == 0) {
2123 SCLogError(
"Error parsing response-body-minimal-inspect-size "
2124 "from conf file - %s. Killing engine",
2129 }
else if (strcasecmp(
"response-body-inspect-window", p->
name) == 0) {
2131 SCLogError(
"Error parsing response-body-inspect-window "
2132 "from conf file - %s. Killing engine",
2137 }
else if (strcasecmp(
"response-body-decompress-layer-limit", p->
name) == 0) {
2140 SCLogError(
"Error parsing response-body-inspect-window "
2141 "from conf file - %s. Killing engine",
2145 htp_config_set_decompression_layer_limit(cfg_prec->
cfg, value);
2146 }
else if (strcasecmp(
"path-convert-backslash-separators", p->
name) == 0) {
2148 }
else if (strcasecmp(
"path-bestfit-replacement-char", p->
name) == 0) {
2149 if (strlen(p->
val) == 1) {
2150 htp_config_set_bestfit_replacement_byte(cfg_prec->
cfg, p->
val[0]);
2153 "for libhtp param path-bestfit-replacement-char");
2155 }
else if (strcasecmp(
"path-convert-lowercase", p->
name) == 0) {
2157 }
else if (strcasecmp(
"path-nul-encoded-terminates", p->
name) == 0) {
2159 }
else if (strcasecmp(
"path-nul-raw-terminates", p->
name) == 0) {
2161 }
else if (strcasecmp(
"path-separators-compress", p->
name) == 0) {
2163 }
else if (strcasecmp(
"path-separators-decode", p->
name) == 0) {
2165 }
else if (strcasecmp(
"path-u-encoding-decode", p->
name) == 0) {
2167 }
else if (strcasecmp(
"path-url-encoding-invalid-handling", p->
name) == 0) {
2168 enum htp_url_encoding_handling_t handling;
2169 if (strcasecmp(p->
val,
"preserve_percent") == 0) {
2170 handling = HTP_URL_ENCODING_HANDLING_PRESERVE_PERCENT;
2171 }
else if (strcasecmp(p->
val,
"remove_percent") == 0) {
2172 handling = HTP_URL_ENCODING_HANDLING_REMOVE_PERCENT;
2173 }
else if (strcasecmp(p->
val,
"decode_invalid") == 0) {
2174 handling = HTP_URL_ENCODING_HANDLING_PROCESS_INVALID;
2177 "for libhtp param path-url-encoding-invalid-handling");
2180 htp_config_set_url_encoding_invalid_handling(cfg_prec->
cfg, handling);
2181 }
else if (strcasecmp(
"path-utf8-convert-bestfit", p->
name) == 0) {
2183 }
else if (strcasecmp(
"uri-include-all", p->
name) == 0) {
2186 }
else if (strcasecmp(
"query-plusspace-decode", p->
name) == 0) {
2188 }
else if (strcasecmp(
"meta-field-limit", p->
name) == 0) {
2192 "from conf file - %s. Killing engine",
2198 "from conf file cannot be 0. Killing engine");
2201 htp_config_set_field_limit(cfg_prec->
cfg, (
size_t)limit);
2202 }
else if (strcasecmp(
"lzma-memlimit", p->
name) == 0) {
2205 FatalError(
"failed to parse 'lzma-memlimit' "
2206 "from conf file - %s.",
2211 "from conf file cannot be 0.");
2214 SCLogConfig(
"Setting HTTP LZMA memory limit to %"PRIu32
" bytes", limit);
2215 htp_config_set_lzma_memlimit(cfg_prec->
cfg, (
size_t)limit);
2216 }
else if (strcasecmp(
"lzma-enabled", p->
name) == 0) {
2218 htp_config_set_lzma_layers(cfg_prec->
cfg, 1);
2223 "from conf file - %s.",
2226 SCLogConfig(
"Setting HTTP LZMA decompression layers to %" PRIu32
"", (
int)limit);
2227 htp_config_set_lzma_layers(cfg_prec->
cfg, limit);
2229 }
else if (strcasecmp(
"compression-bomb-limit", p->
name) == 0) {
2232 FatalError(
"failed to parse 'compression-bomb-limit' "
2233 "from conf file - %s.",
2238 "from conf file cannot be 0.");
2241 SCLogConfig(
"Setting HTTP compression bomb limit to %"PRIu32
" bytes", limit);
2242 htp_config_set_compression_bomb_limit(cfg_prec->
cfg, (
size_t)limit);
2243 }
else if (strcasecmp(
"decompression-time-limit", p->
name) == 0) {
2247 FatalError(
"failed to parse 'decompression-time-limit' "
2248 "from conf file - %s.",
2251 SCLogConfig(
"Setting HTTP decompression time limit to %" PRIu32
" usec", limit);
2252 htp_config_set_compression_time_limit(cfg_prec->
cfg, limit);
2253 }
else if (strcasecmp(
"max-tx", p->
name) == 0) {
2257 "from conf file - %s.",
2261 SCLogConfig(
"Setting HTTP max-tx limit to %" PRIu32
" bytes", limit);
2262 htp_config_set_max_tx(cfg_prec->
cfg, limit);
2263 }
else if (strcasecmp(
"headers-limit", p->
name) == 0) {
2266 FatalError(
"failed to parse 'headers-limit' "
2267 "from conf file - %s.",
2270 SCLogConfig(
"Setting HTTP headers limit to %" PRIu32, limit);
2271 htp_config_set_number_headers_limit(cfg_prec->
cfg, limit);
2272 }
else if (strcasecmp(
"randomize-inspection-sizes", p->
name) == 0) {
2276 }
else if (strcasecmp(
"randomize-inspection-range", p->
name) == 0) {
2279 (
const char *)p->
val, 0, 100) < 0) {
2281 "-inspection-range setting from conf file - \"%s\"."
2282 " It should be a valid integer less than or equal to 100."
2288 }
else if (strcasecmp(
"http-body-inline", p->
name) == 0) {
2294 if (strcmp(
"auto", p->
val) != 0) {
2303 }
else if (strcasecmp(
"swf-decompression", p->
name) == 0) {
2307 if (strcasecmp(
"enabled", pval->
name) == 0) {
2315 }
else if (strcasecmp(
"type", pval->
name) == 0) {
2316 if (strcasecmp(
"no", pval->
val) == 0) {
2318 }
else if (strcasecmp(
"deflate", pval->
val) == 0) {
2320 }
else if (strcasecmp(
"lzma", pval->
val) == 0) {
2322 }
else if (strcasecmp(
"both", pval->
val) == 0) {
2326 "swf-decompression.type: %s - "
2331 }
else if (strcasecmp(
"compress-depth", pval->
name) == 0) {
2333 SCLogError(
"Error parsing swf-decompression.compression-depth "
2334 "from conf file - %s. Killing engine",
2338 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2340 SCLogError(
"Error parsing swf-decompression.decompression-depth "
2341 "from conf file - %s. Killing engine",
2351 "default config: %s",
2361 cfglist.
next = NULL;
2368 cfglist.
cfg = htp_config_create();
2369 if (NULL == cfglist.
cfg) {
2370 FatalError(
"Failed to create HTP default config");
2373 HTPConfigSetDefaultsPhase1(&cfglist);
2374 if (
SCConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2375 HTPConfigParseParameters(&cfglist,
SCConfGetNode(
"libhtp.default-config"), &cfgtree);
2377 HTPConfigParseParameters(&cfglist,
2378 SCConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), &cfgtree);
2380 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2386 if (server_config == NULL) {
2388 if (server_config == NULL) {
2389 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2393 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2412 cfglist.
next = htprec;
2415 cfglist.
next->
cfg = htp_config_create();
2416 if (NULL == cfglist.
next->
cfg) {
2417 FatalError(
"Failed to create HTP server config");
2420 HTPConfigSetDefaultsPhase1(htprec);
2421 HTPConfigParseParameters(htprec, s, &cfgtree);
2422 HTPConfigSetDefaultsPhase2(s->
name, htprec);
2432 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
2443 static AppLayerGetFileState HTPGetTxFiles(
void *txv, uint8_t direction)
2445 AppLayerGetFileState files = { .fc = NULL, .cfg = &
htp_sbcfg };
2446 htp_tx_t *tx = (htp_tx_t *)txv;
2448 if (direction & STREAM_TOCLIENT) {
2456 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
2458 if (direction & STREAM_TOSERVER)
2459 return htp_tx_request_progress((htp_tx_t *)tx);
2461 return htp_tx_response_progress((htp_tx_t *)tx);
2464 static uint64_t HTPStateGetTxCnt(
void *alstate)
2468 if (http_state != NULL && http_state->
connp != NULL) {
2469 const int64_t size = htp_connp_tx_size(http_state->
connp);
2473 return (uint64_t)size;
2479 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
2483 if (http_state != NULL && http_state->
connp != NULL)
2484 return (
void *)htp_connp_tx(http_state->
connp, tx_id);
2493 if (http_state != NULL && http_state->
connp != NULL) {
2494 size_t txid = htp_connp_tx_size(http_state->
connp);
2496 return (
void *)htp_connp_tx(http_state->
connp, txid - 1);
2502 static int HTPStateGetEventInfo(
2503 const char *event_name, uint8_t *event_id, AppLayerEventType *event_type)
2506 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2512 static int HTPStateGetEventInfoById(
2513 uint8_t event_id,
const char **event_name, AppLayerEventType *event_type)
2516 if (*event_name == NULL) {
2518 "http's enum map table.",
2524 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2531 htp_tx_t *tx = (htp_tx_t *)vtx;
2536 static AppLayerStateData *HTPGetStateData(
void *vstate)
2542 static int HTPRegisterPatternsForProtocolDetection(
void)
2544 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
2545 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
2546 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
2547 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
2548 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
2549 const char *spacings[] = {
"|20|",
"|09|", NULL };
2550 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
2555 int register_result;
2556 char method_buffer[32] =
"";
2559 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
2560 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
2563 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
2570 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
2571 if (register_result < 0) {
2578 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
2580 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
2582 if (register_result < 0) {
2598 const char *proto_name =
"http";
2603 if (HTPRegisterPatternsForProtocolDetection() < 0)
2606 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
2621 ALPROTO_HTTP1, HTP_REQUEST_PROGRESS_COMPLETE, HTP_RESPONSE_PROGRESS_COMPLETE);
2633 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
2635 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
2641 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
2644 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
2647 IPPROTO_TCP,
ALPROTO_HTTP1, HtpStateGetStateIdByName, HtpStateGetStateNameById);
2651 SCLogInfo(
"Parser disabled for %s protocol. Protocol detection still on.", proto_name);
2667 cfglist_backup = cfglist;
2672 cfglist = cfglist_backup;
2677 static int HTPParserTest01(
void)
2679 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2681 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2684 memset(&ssn, 0,
sizeof(ssn));
2692 f->
proto = IPPROTO_TCP;
2698 for (u = 0; u < httplen1; u++) {
2702 flags = STREAM_TOSERVER|STREAM_START;
2703 else if (u == (httplen1 - 1))
2704 flags = STREAM_TOSERVER|STREAM_EOF;
2706 flags = STREAM_TOSERVER;
2715 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2718 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2721 FAIL_IF(bstr_cmp_c(htp_header_value(h),
"Victor/1.0"));
2722 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2723 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2732 static int HTPParserTest01b(
void)
2734 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2736 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2739 memset(&ssn, 0,
sizeof(ssn));
2747 f->
proto = IPPROTO_TCP;
2752 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
2759 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2762 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2765 FAIL_IF(strcmp(bstr_util_strdup_to_c(htp_header_value(h)),
"Victor/1.0"));
2766 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2767 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2776 static int HTPParserTest01c(
void)
2778 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2780 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2783 memset(&ssn, 0,
sizeof(ssn));
2791 f->
proto = IPPROTO_TCP;
2797 for (u = 0; u < httplen1; u++) {
2801 flags = STREAM_TOSERVER|STREAM_START;
2802 else if (u == (httplen1 - 1))
2803 flags = STREAM_TOSERVER|STREAM_EOF;
2805 flags = STREAM_TOSERVER;
2814 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2817 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2820 FAIL_IF(strcmp(bstr_util_strdup_to_c(htp_header_value(h)),
"Victor/1.0"));
2821 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2822 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2832 static int HTPParserTest01a(
void)
2835 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2837 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2842 memset(&ssn, 0,
sizeof(ssn));
2844 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2847 f->
proto = IPPROTO_TCP;
2853 for (u = 0; u < httplen1; u++) {
2857 flags = STREAM_TOSERVER|STREAM_START;
2858 else if (u == (httplen1 - 1))
2859 flags = STREAM_TOSERVER|STREAM_EOF;
2861 flags = STREAM_TOSERVER;
2870 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2873 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2876 FAIL_IF(strcmp(bstr_util_strdup_to_c(htp_header_value(h)),
"Victor/1.0"));
2877 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2878 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2887 static int HTPParserTest02(
void)
2890 uint8_t httpbuf1[] =
"POST";
2891 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2896 memset(&ssn, 0,
sizeof(ssn));
2898 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2901 f->
proto = IPPROTO_TCP;
2907 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
2913 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
2915 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2919 char *method = bstr_util_strdup_to_c(htp_tx_request_method(tx));
2922 FAIL_IF(strcmp(method,
"POST") != 0);
2933 static int HTPParserTest03(
void)
2936 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
2937 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2942 memset(&ssn, 0,
sizeof(ssn));
2944 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2947 f->
proto = IPPROTO_TCP;
2953 for (u = 0; u < httplen1; u++) {
2956 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
2957 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
2958 else flags = STREAM_TOSERVER;
2966 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2969 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2971 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
2972 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2982 static int HTPParserTest04(
void)
2986 uint8_t httpbuf1[] =
"World!\r\n";
2987 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2991 memset(&ssn, 0,
sizeof(ssn));
2993 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2996 f->
proto = IPPROTO_TCP;
3002 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3008 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3010 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3012 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3013 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V0_9);
3023 static int HTPParserTest05(
void)
3025 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3026 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3027 uint8_t httpbuf2[] =
"Post D";
3028 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3029 uint8_t httpbuf3[] =
"ata is c0oL!";
3030 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3032 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3033 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3034 uint8_t httpbuf5[] =
"post R";
3035 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3036 uint8_t httpbuf6[] =
"esults are tha bomb!";
3037 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3040 memset(&ssn, 0,
sizeof(ssn));
3048 f->
proto = IPPROTO_TCP;
3078 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3080 FAIL_IF_NOT(htp_tx_request_method_number(tx) == HTP_METHOD_POST);
3081 FAIL_IF_NOT(htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_V1_0);
3083 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3086 FAIL_IF_NOT(htp_tx_response_status_number(tx) == 200);
3096 static int HTPParserTest06(
void)
3098 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3099 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3100 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3101 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3102 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3104 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3105 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3106 "FrontPage/5.0.2.2510\r\n"
3107 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3109 "Content-Type: text/html\r\n\r\n"
3111 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3112 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3113 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3114 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3115 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3116 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3117 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3118 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3119 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3120 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3121 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3122 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3123 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3124 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3125 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3126 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3127 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3128 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3129 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3130 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3131 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3132 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3133 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3134 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3135 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3136 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3137 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3138 "aHA=\r\n0\r\n\r\n";
3139 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3145 memset(&ssn, 0,
sizeof(ssn));
3150 f->
proto = IPPROTO_TCP;
3165 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3168 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
3169 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3171 FAIL_IF(htp_tx_response_status_number(tx) != 200);
3172 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3174 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3185 static int HTPParserTest07(
void)
3188 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3189 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3194 memset(&ssn, 0,
sizeof(ssn));
3196 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3199 f->
proto = IPPROTO_TCP;
3205 for (u = 0; u < httplen1; u++) {
3209 flags = STREAM_TOSERVER|STREAM_START;
3210 else if (u == (httplen1 - 1))
3211 flags = STREAM_TOSERVER|STREAM_EOF;
3213 flags = STREAM_TOSERVER;
3222 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3223 size_t reflen =
sizeof(ref) - 1;
3225 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3227 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3229 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3231 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref, bstr_len(request_uri_normalized)) != 0);
3243 static int HTPParserTest08(
void)
3246 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3247 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3268 memset(&ssn, 0,
sizeof(ssn));
3270 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3273 f->
proto = IPPROTO_TCP;
3278 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3286 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3288 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3290 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3304 static int HTPParserTest09(
void)
3307 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3308 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3318 personality: Apache_2_2\n\
3330 memset(&ssn, 0,
sizeof(ssn));
3332 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3335 f->
proto = IPPROTO_TCP;
3340 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3348 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3350 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3352 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3366 static int HTPParserTest10(
void)
3370 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3371 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3376 memset(&ssn, 0,
sizeof(ssn));
3378 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3381 f->
proto = IPPROTO_TCP;
3387 for (u = 0; u < httplen1; u++) {
3391 flags = STREAM_TOSERVER|STREAM_START;
3392 else if (u == (httplen1 - 1))
3393 flags = STREAM_TOSERVER|STREAM_EOF;
3395 flags = STREAM_TOSERVER;
3404 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3405 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3408 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3412 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3414 FAIL_IF(strcmp(value,
"www.google.com") != 0);
3426 static int HTPParserTest11(
void)
3429 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3430 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3435 memset(&ssn, 0,
sizeof(ssn));
3437 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3440 f->
proto = IPPROTO_TCP;
3446 for (u = 0; u < httplen1; u++) {
3450 flags = STREAM_TOSERVER|STREAM_START;
3451 else if (u == (httplen1 - 1))
3452 flags = STREAM_TOSERVER|STREAM_EOF;
3454 flags = STREAM_TOSERVER;
3463 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3465 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3468 FAIL_IF(bstr_len(request_uri_normalized) != 4);
3469 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3470 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'%');
3471 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'0');
3472 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'0');
3482 static int HTPParserTest12(
void)
3485 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3486 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3491 memset(&ssn, 0,
sizeof(ssn));
3493 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3496 f->
proto = IPPROTO_TCP;
3502 for (u = 0; u < httplen1; u++) {
3506 flags = STREAM_TOSERVER|STREAM_START;
3507 else if (u == (httplen1 - 1))
3508 flags = STREAM_TOSERVER|STREAM_EOF;
3510 flags = STREAM_TOSERVER;
3519 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3521 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3524 FAIL_IF(bstr_len(request_uri_normalized) != 7);
3525 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3526 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'?');
3527 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'a');
3528 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'=');
3529 FAIL_IF(bstr_ptr(request_uri_normalized)[4] !=
'%');
3530 FAIL_IF(bstr_ptr(request_uri_normalized)[5] !=
'0');
3531 FAIL_IF(bstr_ptr(request_uri_normalized)[6] !=
'0');
3541 static int HTPParserTest13(
void)
3544 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3545 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3550 memset(&ssn, 0,
sizeof(ssn));
3552 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3555 f->
proto = IPPROTO_TCP;
3561 for (u = 0; u < httplen1; u++) {
3565 flags = STREAM_TOSERVER|STREAM_START;
3566 else if (u == (httplen1 - 1))
3567 flags = STREAM_TOSERVER|STREAM_EOF;
3569 flags = STREAM_TOSERVER;
3577 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3578 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3581 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3585 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3587 FAIL_IF(strcmp(value,
"www.google.com\rName: Value") != 0);
3599 static int HTPParserConfigTest01(
void)
3612 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3613 personality: Tomcat_6_0\n\
3618 - 192.168.10.0/24\n\
3619 personality: IIS_7_0\n\
3628 outputs =
SCConfGetNode(
"libhtp.default-config.personality");
3639 FAIL_IF(strcmp(node->
name,
"apache-tomcat") != 0);
3646 FAIL_IF(strcmp(node2->
val,
"Tomcat_6_0") != 0);
3656 FAIL_IF(strcmp(n->
val,
"192.168.1.0/24") != 0);
3696 FAIL_IF(strcmp(n->
val,
"192.168.0.0/24") != 0);
3700 FAIL_IF(strcmp(n->
val,
"192.168.10.0/24") != 0);
3715 static int HTPParserConfigTest02(
void)
3728 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3729 personality: Tomcat_6_0\n\
3734 - 192.168.10.0/24\n\
3735 personality: IIS_7_0\n\
3747 htp_cfg_t *htp = cfglist.
cfg;
3750 void *user_data = NULL;
3752 addr =
"192.168.10.42";
3753 FAIL_IF(inet_pton(AF_INET, addr, buf) != 1);
3757 htp = htp_cfg_rec->
cfg;
3763 FAIL_IF(inet_pton(AF_INET6, addr, buf) != 1);
3766 htp_cfg_rec = user_data;
3767 htp = htp_cfg_rec->
cfg;
3780 static int HTPParserConfigTest03(
void)
3783 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3785 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3801 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3802 personality: Tomcat_6_0\n\
3807 - 192.168.10.0/24\n\
3808 personality: IIS_7_0\n\
3819 const char *addr =
"192.168.10.42";
3821 memset(&ssn, 0,
sizeof(ssn));
3826 f->
proto = IPPROTO_TCP;
3829 htp_cfg_t *htp = cfglist.
cfg;
3832 void *user_data = NULL;
3837 htp = htp_cfg_rec->
cfg;
3844 for (u = 0; u < httplen1; u++) {
3847 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3848 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3849 else flags = STREAM_TOSERVER;
3858 FAIL_IF(HTPStateGetTxCnt(htp_state) != 2);
3860 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3862 tx = HTPStateGetTx(htp_state, 1);
3882 static int HTPParserDecodingTest01(
void)
3884 uint8_t httpbuf1[] =
3885 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3886 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3887 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
3888 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3899 personality: Apache_2\n\
3907 const char *addr =
"4.3.2.1";
3908 memset(&ssn, 0,
sizeof(ssn));
3913 f->
proto = IPPROTO_TCP;
3918 for (uint32_t u = 0; u < httplen1; u++) {
3920 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3921 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3922 else flags = STREAM_TOSERVER;
3931 uint8_t ref1[] =
"/abc%2fdef";
3932 size_t reflen =
sizeof(ref1) - 1;
3934 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3938 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3941 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3942 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
3944 uint8_t ref2[] =
"/abc/def?ghi/jkl";
3945 reflen =
sizeof(ref2) - 1;
3947 tx = HTPStateGetTx(htp_state, 1);
3951 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3954 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3955 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
3957 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
3958 reflen =
sizeof(ref3) - 1;
3959 tx = HTPStateGetTx(htp_state, 2);
3963 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3966 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3967 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
3980 static int HTPParserDecodingTest01a(
void)
3982 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3983 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3984 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
3985 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3996 personality: Apache_2\n\
4004 const char *addr =
"4.3.2.1";
4005 memset(&ssn, 0,
sizeof(ssn));
4010 f->
proto = IPPROTO_TCP;
4016 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4022 uint8_t ref1[] =
"/abc%2fdef";
4023 size_t reflen =
sizeof(ref1) - 1;
4025 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4029 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4032 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4033 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4035 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4036 reflen =
sizeof(ref2) - 1;
4038 tx = HTPStateGetTx(htp_state, 1);
4041 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4044 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4046 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4048 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4049 reflen =
sizeof(ref3) - 1;
4050 tx = HTPStateGetTx(htp_state, 2);
4053 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4056 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4058 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4077 static int HTPParserDecodingTest02(
void)
4080 uint8_t httpbuf1[] =
4081 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4082 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4083 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4084 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4096 double-decode-path: no\n\
4097 double-decode-query: no\n\
4105 const char *addr =
"4.3.2.1";
4106 memset(&ssn, 0,
sizeof(ssn));
4111 f->
proto = IPPROTO_TCP;
4117 for (u = 0; u < httplen1; u++) {
4120 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4121 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4122 else flags = STREAM_TOSERVER;
4131 uint8_t ref1[] =
"/abc/def";
4132 size_t reflen =
sizeof(ref1) - 1;
4134 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4136 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4138 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4139 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4141 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4142 reflen =
sizeof(ref2) - 1;
4144 tx = HTPStateGetTx(htp_state, 1);
4146 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4148 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4150 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4152 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4153 reflen =
sizeof(ref3) - 1;
4154 tx = HTPStateGetTx(htp_state, 2);
4156 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4158 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4160 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4178 static int HTPParserDecodingTest03(
void)
4181 uint8_t httpbuf1[] =
4182 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4183 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4184 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4196 double-decode-path: yes\n\
4197 double-decode-query: yes\n\
4205 const char *addr =
"4.3.2.1";
4206 memset(&ssn, 0,
sizeof(ssn));
4211 f->
proto = IPPROTO_TCP;
4217 for (u = 0; u < httplen1; u++) {
4220 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4221 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4222 else flags = STREAM_TOSERVER;
4231 uint8_t ref1[] =
"/abc/def";
4232 size_t reflen =
sizeof(ref1) - 1;
4234 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4236 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4238 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4240 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4242 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4243 reflen =
sizeof(ref2) - 1;
4245 tx = HTPStateGetTx(htp_state, 1);
4247 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4249 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4251 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4266 static int HTPParserDecodingTest04(
void)
4269 uint8_t httpbuf1[] =
4270 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4271 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4283 double-decode-path: yes\n\
4284 double-decode-query: yes\n\
4292 const char *addr =
"4.3.2.1";
4293 memset(&ssn, 0,
sizeof(ssn));
4298 f->
proto = IPPROTO_TCP;
4304 for (u = 0; u < httplen1; u++) {
4307 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4308 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4309 else flags = STREAM_TOSERVER;
4318 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
4319 size_t reflen =
sizeof(ref1) - 1;
4321 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4323 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4325 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4327 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4342 static int HTPParserDecodingTest05(
void)
4345 uint8_t httpbuf1[] =
4346 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4347 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4359 double-decode-path: yes\n\
4360 double-decode-query: yes\n\
4368 const char *addr =
"4.3.2.1";
4369 memset(&ssn, 0,
sizeof(ssn));
4374 f->
proto = IPPROTO_TCP;
4380 for (u = 0; u < httplen1; u++) {
4383 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4384 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4385 else flags = STREAM_TOSERVER;
4394 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
4395 size_t reflen =
sizeof(ref1) - 1;
4397 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4399 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4401 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4403 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4418 static int HTPParserDecodingTest06(
void)
4421 uint8_t httpbuf1[] =
4422 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4423 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4435 double-decode-path: yes\n\
4436 double-decode-query: yes\n\
4444 const char *addr =
"4.3.2.1";
4445 memset(&ssn, 0,
sizeof(ssn));
4450 f->
proto = IPPROTO_TCP;
4456 for (u = 0; u < httplen1; u++) {
4459 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4460 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4461 else flags = STREAM_TOSERVER;
4470 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
4471 size_t reflen =
sizeof(ref1) - 1;
4473 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4475 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4477 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4479 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4494 static int HTPParserDecodingTest07(
void)
4497 uint8_t httpbuf1[] =
4498 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4499 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4511 double-decode-path: yes\n\
4512 double-decode-query: yes\n\
4513 query-plusspace-decode: yes\n\
4521 const char *addr =
"4.3.2.1";
4522 memset(&ssn, 0,
sizeof(ssn));
4527 f->
proto = IPPROTO_TCP;
4533 for (u = 0; u < httplen1; u++) {
4536 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4537 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4538 else flags = STREAM_TOSERVER;
4547 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
4548 size_t reflen =
sizeof(ref1) - 1;
4550 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4552 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4554 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4556 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4571 static int HTPParserDecodingTest08(
void)
4574 uint8_t httpbuf1[] =
4575 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4576 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4595 const char *addr =
"4.3.2.1";
4596 memset(&ssn, 0,
sizeof(ssn));
4601 f->
proto = IPPROTO_TCP;
4607 for (u = 0; u < httplen1; u++) {
4610 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4611 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4612 else flags = STREAM_TOSERVER;
4621 uint8_t ref1[] =
"/blah/";
4622 size_t reflen =
sizeof(ref1) - 1;
4624 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4626 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4628 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4630 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4645 static int HTPParserDecodingTest09(
void)
4648 uint8_t httpbuf1[] =
4649 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4650 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4662 uri-include-all: true\n\
4670 const char *addr =
"4.3.2.1";
4671 memset(&ssn, 0,
sizeof(ssn));
4676 f->
proto = IPPROTO_TCP;
4682 for (u = 0; u < httplen1; u++) {
4685 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4686 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4687 else flags = STREAM_TOSERVER;
4696 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
4697 size_t reflen =
sizeof(ref1) - 1;
4699 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4701 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4703 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4705 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4719 static int HTPBodyReassemblyTest01(
void)
4722 memset(&htud, 0x00,
sizeof(htud));
4724 memset(&hstate, 0x00,
sizeof(hstate));
4726 memset(&flow, 0x00,
sizeof(flow));
4728 htp_cfg_t *cfg = htp_config_create();
4730 htp_connp_t *connp = htp_connp_create(cfg);
4732 const htp_tx_t *tx = htp_connp_get_request_tx(connp);
4738 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
4739 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";
4746 const uint8_t *chunks_buffer = NULL;
4747 uint32_t chunks_buffer_len = 0;
4749 HtpRequestBodyReassemble(&htud, &chunks_buffer, &chunks_buffer_len);
4752 printf(
"REASSCHUNK START: \n");
4754 printf(
"REASSCHUNK END: \n");
4757 htud.
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
4758 strlen(
"multipart/form-data; boundary=toto"));
4761 HtpRequestBodyHandleMultipart(&hstate, &htud, &tx, chunks_buffer, chunks_buffer_len,
false);
4771 static int HTPSegvTest01(
void)
4774 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";
4775 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4783 double-decode-path: no\n\
4784 double-decode-query: no\n\
4785 request-body-limit: 0\n\
4786 response-body-limit: 0\n\
4799 memset(&ssn, 0,
sizeof(ssn));
4801 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4804 f->
proto = IPPROTO_TCP;
4809 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
4813 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
4834 static int HTPParserTest14(
void)
4845 double-decode-path: no\n\
4846 double-decode-query: no\n\
4847 request-body-limit: 0\n\
4848 response-body-limit: 0\n\
4853 memset(&ssn, 0,
sizeof(ssn));
4863 memset(httpbuf, 0x00,
len);
4866 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4867 "Host: myhost.lan\r\n"
4868 "Connection: keep-alive\r\n"
4870 "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"
4871 "Referer: http://blah.lan/\r\n"
4872 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
4874 size_t o = strlen(httpbuf);
4875 for ( ; o <
len - 4; o++) {
4878 httpbuf[
len - 4] =
'\r';
4879 httpbuf[
len - 3] =
'\n';
4880 httpbuf[
len - 2] =
'\r';
4881 httpbuf[
len - 1] =
'\n';
4887 f->
proto = IPPROTO_TCP;
4892 for (u = 0; u <
len; u++) {
4895 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4896 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4897 else flags = STREAM_TOSERVER;
4905 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4907 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
4908 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
4915 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG);
4930 static int HTPParserTest15(
void)
4933 char *httpbuf = NULL;
4944 double-decode-path: no\n\
4945 double-decode-query: no\n\
4946 request-body-limit: 0\n\
4947 response-body-limit: 0\n\
4948 meta-field-limit: 20000\n\
4952 memset(&ssn, 0,
sizeof(ssn));
4963 memset(httpbuf, 0x00,
len);
4966 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4967 "Host: myhost.lan\r\n"
4968 "Connection: keep-alive\r\n"
4970 "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"
4971 "Referer: http://blah.lan/\r\n"
4972 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
4974 size_t o = strlen(httpbuf);
4975 for ( ; o <
len - 4; o++) {
4978 httpbuf[
len - 4] =
'\r';
4979 httpbuf[
len - 3] =
'\n';
4980 httpbuf[
len - 2] =
'\r';
4981 httpbuf[
len - 1] =
'\n';
4983 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4986 f->
proto = IPPROTO_TCP;
4992 for (u = 0; u <
len; u++) {
4995 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4996 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4997 else flags = STREAM_TOSERVER;
5006 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5008 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5009 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5028 static int HTPParserTest16(
void)
5035 memset(&ssn, 0,
sizeof(ssn));
5037 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5038 "Host: myhost.lan\r\n"
5039 "Connection: keep-alive\r\n"
5041 "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"
5042 "Referer: http://blah.lan/\r\n"
5043 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5044 "Cookie: blah\r\n\r\n";
5045 size_t len =
sizeof(httpbuf) - 1;
5047 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5050 f->
proto = IPPROTO_TCP;
5055 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5063 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5065 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5066 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5068 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5075 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT);
5076 FAIL_IF(decoder_events->
events[1] != HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT);
5087 static int HTPParserTest20(
void)
5090 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5091 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5092 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5093 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5094 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
5095 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5096 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5097 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5103 memset(&ssn, 0,
sizeof(ssn));
5105 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5108 f->
proto = IPPROTO_TCP;
5127 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5129 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5132 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5133 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5135 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5136 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5146 static int HTPParserTest21(
void)
5149 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5150 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5151 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5152 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5153 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
5154 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5155 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5156 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5162 memset(&ssn, 0,
sizeof(ssn));
5164 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5167 f->
proto = IPPROTO_TCP;
5186 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5188 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5191 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5192 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5194 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5195 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5205 static int HTPParserTest22(
void)
5208 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5209 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5210 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5211 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5212 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
5213 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5214 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5220 memset(&ssn, 0,
sizeof(ssn));
5222 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5225 f->
proto = IPPROTO_TCP;
5240 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5242 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5245 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5246 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5248 FAIL_IF(htp_tx_response_status_number(tx) != -0);
5249 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5259 static int HTPParserTest23(
void)
5262 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5263 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5264 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5265 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5266 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
5267 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5268 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5274 memset(&ssn, 0,
sizeof(ssn));
5276 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5279 f->
proto = IPPROTO_TCP;
5294 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5296 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5299 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5300 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5302 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5303 FAIL_IF(htp_tx_response_protocol_number(tx) != -2);
5313 static int HTPParserTest24(
void)
5316 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5317 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5318 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5319 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5320 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
5321 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5322 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5328 memset(&ssn, 0,
sizeof(ssn));
5330 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5333 f->
proto = IPPROTO_TCP;
5348 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5350 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5353 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5354 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5356 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5357 FAIL_IF(htp_tx_response_protocol_number(tx) != HTP_PROTOCOL_V1_0);
5366 static int HTPParserTest25(
void)
5373 memset(&ssn, 0,
sizeof(ssn));
5378 f->
proto = IPPROTO_TCP;
5382 const char *
str =
"GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
5384 (uint8_t *)
str, strlen(
str));
5408 str =
"HTTP 1.1 200 OK\r\nServer: Suricata/1.0\r\nContent-Length: 8\r\n\r\nSuricata";
5410 (uint8_t *)
str, strlen(
str));
5444 (uint8_t *)
str, strlen(
str));
5455 (uint8_t *)
str, strlen(
str));
5475 static int HTPParserTest26(
void)
5484 request-body-limit: 1\n\
5485 response-body-limit: 1\n\
5499 uint8_t httpbuf1[] =
"GET /alice.txt HTTP/1.1\r\n\r\n";
5500 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5501 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\n"
5502 "Content-Type: text/plain\r\n"
5503 "Content-Length: 228\r\n\r\n"
5504 "Alice was beginning to get very tired of sitting by her sister on the bank."
5505 "Alice was beginning to get very tired of sitting by her sister on the bank.";
5506 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5507 uint8_t httpbuf3[] =
"Alice was beginning to get very tired of sitting by her sister on the bank.\r\n\r\n";
5508 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5514 memset(&th_v, 0,
sizeof(th_v));
5515 memset(&f, 0,
sizeof(f));
5516 memset(&ssn, 0,
sizeof(ssn));
5523 f.
proto = IPPROTO_TCP;
5544 "(filestore; sid:1; rev:1;)");
5589 AppLayerGetFileState files = HTPGetTxFiles(tx_ptr, STREAM_TOCLIENT);
5611 static int HTPParserTest27(
void)
5614 memset(&cfg, 0,
sizeof(cfg));
5618 uint32_t
len = 1000;
5643 static void HTPParserRegisterTests(
void)
5665 UtRegisterTest(
"HTPParserDecodingTest01", HTPParserDecodingTest01);
5666 UtRegisterTest(
"HTPParserDecodingTest01a", HTPParserDecodingTest01a);
5667 UtRegisterTest(
"HTPParserDecodingTest02", HTPParserDecodingTest02);
5668 UtRegisterTest(
"HTPParserDecodingTest03", HTPParserDecodingTest03);
5669 UtRegisterTest(
"HTPParserDecodingTest04", HTPParserDecodingTest04);
5670 UtRegisterTest(
"HTPParserDecodingTest05", HTPParserDecodingTest05);
5671 UtRegisterTest(
"HTPParserDecodingTest06", HTPParserDecodingTest06);
5672 UtRegisterTest(
"HTPParserDecodingTest07", HTPParserDecodingTest07);
5673 UtRegisterTest(
"HTPParserDecodingTest08", HTPParserDecodingTest08);
5674 UtRegisterTest(
"HTPParserDecodingTest09", HTPParserDecodingTest09);
5676 UtRegisterTest(
"HTPBodyReassemblyTest01", HTPBodyReassemblyTest01);