80 static struct HTPConfigTree {
96 #define HTP_MAX_MESSAGES 512
102 static uint64_t htp_state_memuse = 0;
103 static uint64_t htp_state_memcnt = 0;
107 {
"UNKNOWN_ERROR", HTP_LOG_CODE_UNKNOWN },
108 {
"GZIP_DECOMPRESSION_FAILED", HTP_LOG_CODE_GZIP_DECOMPRESSION_FAILED },
109 {
"REQUEST_FIELD_MISSING_COLON", HTP_LOG_CODE_REQUEST_FIELD_MISSING_COLON },
110 {
"RESPONSE_FIELD_MISSING_COLON", HTP_LOG_CODE_RESPONSE_FIELD_MISSING_COLON },
111 {
"INVALID_REQUEST_CHUNK_LEN", HTP_LOG_CODE_INVALID_REQUEST_CHUNK_LEN },
112 {
"INVALID_RESPONSE_CHUNK_LEN", HTP_LOG_CODE_INVALID_RESPONSE_CHUNK_LEN },
113 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST",
114 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST },
115 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE",
116 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE },
117 {
"INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST",
118 HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST },
119 {
"INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE",
120 HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE },
121 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST",
122 HTP_LOG_CODE_DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST },
123 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE",
124 HTP_LOG_CODE_DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE },
125 {
"100_CONTINUE_ALREADY_SEEN", HTP_LOG_CODE_CONTINUE_ALREADY_SEEN },
126 {
"UNABLE_TO_MATCH_RESPONSE_TO_REQUEST", HTP_LOG_CODE_UNABLE_TO_MATCH_RESPONSE_TO_REQUEST },
127 {
"INVALID_SERVER_PORT_IN_REQUEST", HTP_LOG_CODE_INVALID_SERVER_PORT_IN_REQUEST },
128 {
"INVALID_AUTHORITY_PORT", HTP_LOG_CODE_INVALID_AUTHORITY_PORT },
129 {
"REQUEST_HEADER_INVALID", HTP_LOG_CODE_REQUEST_HEADER_INVALID },
130 {
"RESPONSE_HEADER_INVALID", HTP_LOG_CODE_RESPONSE_HEADER_INVALID },
131 {
"MISSING_HOST_HEADER", HTP_LOG_CODE_MISSING_HOST_HEADER },
132 {
"HOST_HEADER_AMBIGUOUS", HTP_LOG_CODE_HOST_HEADER_AMBIGUOUS },
133 {
"INVALID_REQUEST_FIELD_FOLDING", HTP_LOG_CODE_INVALID_REQUEST_FIELD_FOLDING },
134 {
"INVALID_RESPONSE_FIELD_FOLDING", HTP_LOG_CODE_INVALID_RESPONSE_FIELD_FOLDING },
135 {
"REQUEST_FIELD_TOO_LONG", HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG },
136 {
"RESPONSE_FIELD_TOO_LONG", HTP_LOG_CODE_RESPONSE_FIELD_TOO_LONG },
137 {
"REQUEST_LINE_INVALID", HTP_LOG_CODE_REQUEST_LINE_INVALID },
138 {
"REQUEST_BODY_UNEXPECTED", HTP_LOG_CODE_REQUEST_BODY_UNEXPECTED },
139 {
"RESPONSE_BODY_UNEXPECTED", HTP_LOG_CODE_RESPONSE_BODY_UNEXPECTED },
140 {
"REQUEST_SERVER_PORT_TCP_PORT_MISMATCH", HTP_LOG_CODE_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH },
141 {
"REQUEST_URI_HOST_INVALID", HTP_LOG_CODE_URI_HOST_INVALID },
142 {
"REQUEST_HEADER_HOST_INVALID", HTP_LOG_CODE_HEADER_HOST_INVALID },
143 {
"REQUEST_AUTH_UNRECOGNIZED", HTP_LOG_CODE_AUTH_UNRECOGNIZED },
144 {
"REQUEST_HEADER_REPETITION", HTP_LOG_CODE_REQUEST_HEADER_REPETITION },
145 {
"RESPONSE_HEADER_REPETITION", HTP_LOG_CODE_RESPONSE_HEADER_REPETITION },
146 {
"DOUBLE_ENCODED_URI", HTP_LOG_CODE_DOUBLE_ENCODED_URI },
147 {
"URI_DELIM_NON_COMPLIANT", HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT },
148 {
"METHOD_DELIM_NON_COMPLIANT", HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT },
149 {
"REQUEST_LINE_LEADING_WHITESPACE", HTP_LOG_CODE_REQUEST_LINE_LEADING_WHITESPACE },
150 {
"TOO_MANY_ENCODING_LAYERS", HTP_LOG_CODE_TOO_MANY_ENCODING_LAYERS },
151 {
"REQUEST_TOO_MANY_LZMA_LAYERS", HTP_LOG_CODE_REQUEST_TOO_MANY_LZMA_LAYERS },
152 {
"RESPONSE_TOO_MANY_LZMA_LAYERS", HTP_LOG_CODE_RESPONSE_TOO_MANY_LZMA_LAYERS },
153 {
"ABNORMAL_CE_HEADER", HTP_LOG_CODE_ABNORMAL_CE_HEADER },
154 {
"RESPONSE_MULTIPART_BYTERANGES", HTP_LOG_CODE_RESPONSE_MULTIPART_BYTERANGES },
155 {
"RESPONSE_ABNORMAL_TRANSFER_ENCODING", HTP_LOG_CODE_RESPONSE_ABNORMAL_TRANSFER_ENCODING },
156 {
"RESPONSE_CHUNKED_OLD_PROTO", HTP_LOG_CODE_RESPONSE_CHUNKED_OLD_PROTO },
157 {
"RESPONSE_INVALID_PROTOCOL", HTP_LOG_CODE_RESPONSE_INVALID_PROTOCOL },
158 {
"RESPONSE_INVALID_STATUS", HTP_LOG_CODE_RESPONSE_INVALID_STATUS },
159 {
"REQUEST_LINE_INCOMPLETE", HTP_LOG_CODE_REQUEST_LINE_INCOMPLETE },
160 {
"PROTOCOL_CONTAINS_EXTRA_DATA", HTP_LOG_CODE_PROTOCOL_CONTAINS_EXTRA_DATA },
162 "CONTENT_LENGTH_EXTRA_DATA_START",
163 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_START,
166 "CONTENT_LENGTH_EXTRA_DATA_END",
167 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_END,
169 {
"SWITCHING_PROTO_WITH_CONTENT_LENGTH", HTP_LOG_CODE_SWITCHING_PROTO_WITH_CONTENT_LENGTH },
170 {
"DEFORMED_EOL", HTP_LOG_CODE_DEFORMED_EOL },
171 {
"PARSER_STATE_ERROR", HTP_LOG_CODE_PARSER_STATE_ERROR },
172 {
"MISSING_OUTBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_OUTBOUND_TRANSACTION_DATA },
173 {
"MISSING_INBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_INBOUND_TRANSACTION_DATA },
174 {
"ZERO_LENGTH_DATA_CHUNKS", HTP_LOG_CODE_ZERO_LENGTH_DATA_CHUNKS },
175 {
"REQUEST_LINE_UNKNOWN_METHOD", HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD },
176 {
"REQUEST_LINE_UNKNOWN_METHOD_NO_PROTOCOL",
177 HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD_NO_PROTOCOL },
178 {
"REQUEST_LINE_UNKNOWN_METHOD_INVALID_PROTOCOL",
179 HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD_INVALID_PROTOCOL },
180 {
"REQUEST_LINE_MISSING_PROTOCOL", HTP_LOG_CODE_REQUEST_LINE_NO_PROTOCOL },
181 {
"RESPONSE_LINE_INVALID_PROTOCOL", HTP_LOG_CODE_RESPONSE_LINE_INVALID_PROTOCOL },
182 {
"RESPONSE_LINE_INVALID_RESPONSE_STATUS", HTP_LOG_CODE_RESPONSE_LINE_INVALID_RESPONSE_STATUS },
183 {
"RESPONSE_BODY_INTERNAL_ERROR", HTP_LOG_CODE_RESPONSE_BODY_INTERNAL_ERROR },
184 {
"REQUEST_BODY_DATA_CALLBACK_ERROR", HTP_LOG_CODE_REQUEST_BODY_DATA_CALLBACK_ERROR },
185 {
"RESPONSE_INVALID_EMPTY_NAME", HTP_LOG_CODE_RESPONSE_INVALID_EMPTY_NAME },
186 {
"REQUEST_INVALID_EMPTY_NAME", HTP_LOG_CODE_REQUEST_INVALID_EMPTY_NAME },
187 {
"RESPONSE_INVALID_LWS_AFTER_NAME", HTP_LOG_CODE_RESPONSE_INVALID_LWS_AFTER_NAME },
188 {
"RESPONSE_HEADER_NAME_NOT_TOKEN", HTP_LOG_CODE_RESPONSE_HEADER_NAME_NOT_TOKEN },
189 {
"REQUEST_INVALID_LWS_AFTER_NAME", HTP_LOG_CODE_REQUEST_INVALID_LWS_AFTER_NAME },
190 {
"LZMA_DECOMPRESSION_DISABLED", HTP_LOG_CODE_LZMA_DECOMPRESSION_DISABLED },
191 {
"CONNECTION_ALREADY_OPEN", HTP_LOG_CODE_CONNECTION_ALREADY_OPEN },
192 {
"COMPRESSION_BOMB_DOUBLE_LZMA", HTP_LOG_CODE_COMPRESSION_BOMB_DOUBLE_LZMA },
193 {
"INVALID_CONTENT_ENCODING", HTP_LOG_CODE_INVALID_CONTENT_ENCODING },
194 {
"INVALID_GAP", HTP_LOG_CODE_INVALID_GAP },
195 {
"REQUEST_CHUNK_EXTENSION", HTP_LOG_CODE_REQUEST_CHUNK_EXTENSION },
196 {
"RESPONSE_CHUNK_EXTENSION", HTP_LOG_CODE_RESPONSE_CHUNK_EXTENSION },
198 {
"LZMA_MEMLIMIT_REACHED", HTP_LOG_CODE_LZMA_MEMLIMIT_REACHED },
199 {
"COMPRESSION_BOMB", HTP_LOG_CODE_COMPRESSION_BOMB },
200 {
"COMPRESSION_BOMB_LIMIT_REACHED", HTP_LOG_CODE_COMPRESSION_BOMB_LIMIT_REACHED },
202 {
"REQUEST_TOO_MANY_HEADERS", HTP_LOG_CODE_REQUEST_TOO_MANY_HEADERS },
203 {
"RESPONSE_TOO_MANY_HEADERS", HTP_LOG_CODE_RESPONSE_TOO_MANY_HEADERS },
236 static int HTTPGetFrameIdByName(
const char *frame_name)
245 static const char *HTTPGetFrameNameById(
const uint8_t frame_id)
255 HTP_REQUEST_PROGRESS_NOT_STARTED,
259 HTP_REQUEST_PROGRESS_LINE,
263 HTP_REQUEST_PROGRESS_HEADERS,
267 HTP_REQUEST_PROGRESS_BODY,
271 HTP_REQUEST_PROGRESS_TRAILER,
275 HTP_REQUEST_PROGRESS_COMPLETE,
284 HTP_RESPONSE_PROGRESS_NOT_STARTED,
288 HTP_RESPONSE_PROGRESS_LINE,
292 HTP_RESPONSE_PROGRESS_HEADERS,
296 HTP_RESPONSE_PROGRESS_BODY,
300 HTP_RESPONSE_PROGRESS_TRAILER,
304 HTP_RESPONSE_PROGRESS_COMPLETE,
309 static int HtpStateGetStateIdByName(
const char *
name,
const uint8_t direction)
312 direction == STREAM_TOSERVER ? http_state_client_table : http_state_server_table;
321 static const char *HtpStateGetStateNameById(
const int id,
const uint8_t direction)
324 direction == STREAM_TOSERVER ? http_state_client_table : http_state_server_table;
329 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id);
330 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction);
331 static uint64_t HTPStateGetTxCnt(
void *alstate);
333 static void HTPParserRegisterTests(
void);
336 static inline uint64_t HtpGetActiveRequestTxID(
HtpState *s)
338 uint64_t
id = HTPStateGetTxCnt(s);
343 static inline uint64_t HtpGetActiveResponseTxID(
HtpState *s)
356 static const char *HTPLookupPersonalityString(
int p)
358 #define CASE_HTP_PERSONALITY_STRING(p) \
359 case HTP_SERVER_PERSONALITY_##p: \
363 CASE_HTP_PERSONALITY_STRING(MINIMAL);
364 CASE_HTP_PERSONALITY_STRING(GENERIC);
365 CASE_HTP_PERSONALITY_STRING(IDS);
366 CASE_HTP_PERSONALITY_STRING(IIS_4_0);
367 CASE_HTP_PERSONALITY_STRING(IIS_5_0);
368 CASE_HTP_PERSONALITY_STRING(IIS_5_1);
369 CASE_HTP_PERSONALITY_STRING(IIS_6_0);
370 CASE_HTP_PERSONALITY_STRING(IIS_7_0);
371 CASE_HTP_PERSONALITY_STRING(IIS_7_5);
372 CASE_HTP_PERSONALITY_STRING(APACHE_2);
386 static int HTPLookupPersonality(
const char *
str)
388 #define IF_HTP_PERSONALITY_NUM(p) \
389 if (strcasecmp(#p, str) == 0) \
390 return HTP_SERVER_PERSONALITY_##p
402 if (strcasecmp(
"TOMCAT_6_0",
str) == 0) {
404 "longer supported by libhtp.",
407 }
else if ((strcasecmp(
"APACHE",
str) == 0) ||
408 (strcasecmp(
"APACHE_2_2",
str) == 0))
411 "longer supported by libhtp, failing back to "
412 "Apache2 personality.",
414 return HTP_SERVER_PERSONALITY_APACHE_2;
421 const uint8_t dir,
const uint8_t e)
431 const uint64_t tx_id = (dir == STREAM_TOSERVER) ?
432 HtpGetActiveRequestTxID(s) : HtpGetActiveResponseTxID(s);
434 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
435 if (tx == NULL && tx_id > 0)
436 tx = HTPStateGetTx(s, tx_id - 1);
440 if (dir & STREAM_TOCLIENT)
442 if (dir & STREAM_TOSERVER)
453 static void *HTPStateAlloc(
void *orig_state,
AppProto proto_orig)
467 htp_state_memuse +=
sizeof(
HtpState);
468 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
475 static void HtpTxUserDataFree(
void *txud)
511 if (s->
connp != NULL) {
513 htp_connp_destroy_all(s->
connp);
521 htp_state_memuse -=
sizeof(
HtpState);
522 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
533 static void HTPStateTransactionFree(
void *state, uint64_t
id)
540 htp_tx_destroy(s->
connp,
id);
585 static void AppLayerHtpSetStreamDepthFlag(
void *tx,
const uint8_t
flags)
589 if (
flags & STREAM_TOCLIENT) {
598 SCLogDebug(
"cfg->body_limit %u stream_depth %u body->content_len_so_far %" PRIu64,
615 static uint32_t AppLayerHtpComputeChunkLength(uint64_t content_len_so_far, uint32_t body_limit,
616 uint32_t stream_depth, uint8_t
flags, uint32_t data_len)
618 uint32_t chunk_len = 0;
620 (content_len_so_far < (uint64_t)body_limit) &&
621 (content_len_so_far + (uint64_t)data_len) > body_limit)
623 chunk_len = (uint32_t)(body_limit - content_len_so_far);
625 (content_len_so_far < (uint64_t)stream_depth) &&
626 (content_len_so_far + (uint64_t)data_len) > stream_depth)
628 chunk_len = (uint32_t)(stream_depth - content_len_so_far);
631 return (chunk_len == 0 ? data_len : chunk_len);
642 static void HTPHandleError(
HtpState *s,
const uint8_t dir)
644 if (s == NULL || s->
conn == NULL) {
648 htp_log_t *log = htp_conn_next_log(s->
conn);
649 while (log != NULL) {
650 char *msg = htp_log_message(log);
653 log = htp_conn_next_log(s->
conn);
659 htp_log_code_t
id = htp_log_code(log);
660 if (
id != HTP_LOG_CODE_UNKNOWN &&
id != HTP_LOG_CODE_ERROR) {
661 HTPSetEvent(s, NULL, dir, (uint8_t)
id);
663 htp_free_cstring(msg);
670 log = htp_conn_next_log(s->
conn);
675 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s,
const htp_tx_t *tx)
678 BUG_ON(s == NULL || tx == NULL);
680 if (htp_tx_flags(tx) & (HTP_FLAGS_REQUEST_INVALID_T_E | HTP_FLAGS_REQUEST_INVALID_C_L |
681 HTP_FLAGS_HOST_MISSING | HTP_FLAGS_HOST_AMBIGUOUS |
682 HTP_FLAGS_HOSTU_INVALID | HTP_FLAGS_HOSTH_INVALID)) {
685 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_T_E)
686 HTPSetEvent(s, htud, STREAM_TOSERVER,
687 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST);
688 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_C_L)
690 s, htud, STREAM_TOSERVER, HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST);
691 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_MISSING)
692 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_MISSING_HOST_HEADER);
693 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_AMBIGUOUS)
694 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HOST_HEADER_AMBIGUOUS);
695 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTU_INVALID)
696 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_URI_HOST_INVALID);
697 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTH_INVALID)
698 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HEADER_HOST_INVALID);
700 if (htp_tx_request_auth_type(tx) == HTP_AUTH_TYPE_UNRECOGNIZED) {
702 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_AUTH_UNRECOGNIZED);
704 if (htp_tx_is_protocol_0_9(tx) && htp_tx_request_method_number(tx) == HTP_METHOD_UNKNOWN &&
705 (htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_INVALID ||
706 htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_UNKNOWN)) {
708 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_REQUEST_LINE_INVALID);
718 htp_cfg_t *htp = cfglist.
cfg;
719 void *user_data = NULL;
735 if (user_data != NULL) {
736 htp_cfg_rec = user_data;
737 htp = htp_cfg_rec->
cfg;
740 SCLogDebug(
"Using default HTP config: %p", htp);
744 #ifdef DEBUG_VALIDATION
751 hstate->
connp = htp_connp_create(htp);
752 if (hstate->
connp == NULL) {
756 hstate->
conn = (htp_conn_t *)htp_connp_connection(hstate->
connp);
758 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
759 hstate->
cfg = htp_cfg_rec;
764 htp_connp_open(hstate->
connp, NULL, f->
sp, NULL, f->
dp, &
tv);
796 if (NULL == hstate->
conn) {
797 if (Setup(f, hstate) != 0) {
802 hstate->
slice = &stream_slice;
804 const uint8_t *input = StreamSliceGetData(&stream_slice);
805 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
810 const int r = htp_connp_request_data(hstate->
connp, &
ts, input, input_len);
812 case HTP_STREAM_STATE_ERROR:
818 HTPHandleError(hstate, STREAM_TOSERVER);
824 htp_connp_request_close(hstate->
connp, &
ts);
826 SCLogDebug(
"stream eof encountered, closing htp handle for ts");
830 hstate->
slice = NULL;
858 const uint8_t *input = StreamSliceGetData(&stream_slice);
859 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
865 if (NULL == hstate->
conn) {
866 if (Setup(f, hstate) != 0) {
871 hstate->
slice = &stream_slice;
874 const htp_tx_t *tx = NULL;
875 uint32_t consumed = 0;
877 const int r = htp_connp_response_data(hstate->
connp, &
ts, input, input_len);
879 case HTP_STREAM_STATE_ERROR:
882 case HTP_STREAM_STATE_TUNNEL:
883 tx = htp_connp_get_response_tx(hstate->
connp);
884 if (tx != NULL && htp_tx_response_status_number(tx) == 101) {
885 const htp_header_t *h = htp_tx_response_header(tx,
"Upgrade");
890 if (htp_tx_request_port_number(tx) != -1) {
891 dp = (uint16_t)htp_tx_request_port_number(tx);
893 consumed = (uint32_t)htp_connp_response_data_consumed(hstate->
connp);
894 if (bstr_cmp_c(htp_header_value(h),
"h2c") == 0) {
899 hstate->
slice = NULL;
901 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
906 if (consumed > 0 && consumed < input_len) {
910 }
else if (bstr_cmp_c_nocase(htp_header_value(h),
"WebSocket")) {
915 hstate->
slice = NULL;
917 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
922 if (consumed > 0 && consumed < input_len) {
932 HTPHandleError(hstate, STREAM_TOCLIENT);
938 htp_connp_close(hstate->
connp, &
ts);
943 hstate->
slice = NULL;
954 static int HTTPParseContentDispositionHeader(
const uint8_t *
name,
size_t name_len,
955 const uint8_t *data,
size_t len, uint8_t
const **retptr,
size_t *retlen)
958 printf(
"DATA START: \n");
960 printf(
"DATA END: \n");
965 for (x = 0; x <
len; x++) {
966 if (!(isspace(data[x])))
973 const uint8_t *line = data + x;
974 size_t line_len =
len-x;
977 printf(
"LINE START: \n");
979 printf(
"LINE END: \n");
981 for (x = 0 ; x < line_len; x++) {
983 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
987 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
988 const uint8_t *token = line +
offset;
989 size_t token_len = x -
offset;
991 if ((x + 1) == line_len) {
1002 printf(
"TOKEN START: \n");
1004 printf(
"TOKEN END: \n");
1006 if (token_len > name_len) {
1007 if (
name == NULL || SCMemcmpLowercase(
name, token, name_len) == 0) {
1008 const uint8_t *value = token + name_len;
1009 size_t value_len = token_len - name_len;
1011 if (value[0] ==
'\"') {
1015 if (value[value_len-1] ==
'\"') {
1019 printf(
"VALUE START: \n");
1021 printf(
"VALUE END: \n");
1024 *retlen = value_len;
1048 static int HtpRequestBodySetupMultipart(
const htp_tx_t *tx,
HtpTxUserData *htud)
1050 const htp_header_t *h = htp_tx_request_header(tx,
"Content-Type");
1051 if (h != NULL && htp_header_value_len(h) > 0) {
1053 SCMimeStateInit(htp_header_value_ptr(h), (uint32_t)htp_header_value_len(h));
1070 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1073 chunks_buffer, chunks_buffer_len,
1077 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1081 if (dir == STREAM_TOSERVER) {
1082 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1084 }
else if (dir == STREAM_TOCLIENT) {
1085 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1092 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len,
bool eof)
1095 printf(
"CHUNK START: \n");
1097 printf(
"CHUNK END: \n");
1103 STREAM_TOSERVER) >= HTP_REQUEST_PROGRESS_COMPLETE);
1105 const uint8_t *cur_buf = chunks_buffer;
1106 uint32_t cur_buf_len = chunks_buffer_len;
1122 const uint8_t *filename = NULL;
1123 uint16_t filename_len = 0;
1126 while (cur_buf_len > 0) {
1127 MimeParserResult r =
1128 SCMimeParse(htud->
mime_state, cur_buf, cur_buf_len, &consumed, &warnings);
1132 if (warnings & MIME_EVENT_FLAG_INVALID_HEADER) {
1136 if (warnings & MIME_EVENT_FLAG_NO_FILEDATA) {
1147 SCMimeStateGetFilename(htud->
mime_state, &filename, &filename_len);
1148 if (filename_len > 0) {
1152 hstate, htud, filename, filename_len, NULL, 0, STREAM_TOSERVER);
1155 }
else if (result == -2) {
1158 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1166 }
else if (result == -2) {
1174 uint32_t lastsize = consumed;
1175 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\n') {
1177 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\r') {
1181 HTPFileClose(htud, cur_buf, lastsize, 0, STREAM_TOSERVER);
1186 cur_buf += consumed;
1187 cur_buf_len -= consumed;
1199 const uint8_t *data, uint32_t data_len)
1206 uint8_t *filename = NULL;
1207 size_t filename_len = 0;
1210 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1211 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1212 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1215 if (filename != NULL) {
1221 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1225 }
else if (result == -2) {
1228 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1242 }
else if (result == -2) {
1255 const uint8_t *data, uint32_t data_len)
1272 const uint8_t *filename = NULL;
1273 size_t filename_len = 0;
1276 const htp_header_t *h = htp_tx_response_header(tx,
"Content-Disposition");
1277 if (h != NULL && htp_header_value_len(h) > 0) {
1279 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1280 htp_header_value_ptr(h), htp_header_value_len(h), &filename, &filename_len);
1284 if (filename == NULL) {
1286 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1287 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1288 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1292 if (filename != NULL) {
1294 const htp_header_t *h_content_range = htp_tx_response_header(tx,
"content-range");
1300 if (h_content_range != NULL) {
1302 data_len, tx, htp_header_value(h_content_range), htud);
1304 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1310 }
else if (result == -2) {
1313 FlagDetectStateNewFile(htud, STREAM_TOCLIENT);
1326 }
else if (result == -2) {
1344 static int HTPCallbackRequestBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1348 const htp_tx_t *tx = htp_tx_data_tx(d);
1353 if (htp_tx_data_is_empty(d))
1357 printf(
"HTPBODY START: \n");
1358 PrintRawDataFp(stdout, (uint8_t *)htp_tx_data_data(d), htp_tx_data_len(d));
1359 printf(
"HTPBODY END: \n");
1362 HtpState *hstate = htp_connp_user_data(connp);
1363 if (hstate == NULL) {
1367 SCLogDebug(
"New request body data available at %p -> %p -> %p, bodylen "
1369 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1372 if (tx_ud == NULL) {
1381 if (htp_tx_request_method_number(tx) == HTP_METHOD_POST) {
1383 int r = HtpRequestBodySetupMultipart(tx, tx_ud);
1386 }
else if (r == 0) {
1390 }
else if (htp_tx_request_method_number(tx) == HTP_METHOD_PUT) {
1406 (uint32_t)htp_tx_data_len(d));
1411 const uint8_t *chunks_buffer = NULL;
1412 uint32_t chunks_buffer_len = 0;
1420 HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len);
1421 if (chunks_buffer == NULL) {
1425 printf(
"REASSCHUNK START: \n");
1427 printf(
"REASSCHUNK END: \n");
1430 HtpRequestBodyHandleMultipart(hstate, tx_ud, htp_tx_data_tx(d), chunks_buffer,
1431 chunks_buffer_len, (htp_tx_data_data(d) == NULL && htp_tx_data_len(d) == 0));
1435 HtpRequestBodyHandlePOSTorPUT(
1436 hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1441 SCLogDebug(
"closing file that was being stored");
1448 if (hstate->
conn != NULL) {
1449 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1450 ", last %" PRIu64
")",
1452 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1461 if ((uint64_t)htp_conn_request_data_counter(hstate->
conn) >
1463 (uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1465 (uint64_t)UINT_MAX) {
1466 uint32_t data_size =
1467 (uint32_t)((uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1488 static int HTPCallbackResponseBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1492 const htp_tx_t *tx = htp_tx_data_tx(d);
1497 if (htp_tx_data_is_empty(d))
1500 HtpState *hstate = htp_connp_user_data(connp);
1501 if (hstate == NULL) {
1505 SCLogDebug(
"New response body data available at %p -> %p -> %p, bodylen "
1507 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1527 (uint32_t)htp_tx_data_len(d));
1532 HtpResponseBodyHandle(hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1535 SCLogDebug(
"closing file that was being stored");
1541 if (hstate->
conn != NULL) {
1542 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1543 ", last %" PRIu64
")",
1545 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1553 if ((uint64_t)htp_conn_response_data_counter(hstate->
conn) >
1555 (uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1557 (uint64_t)UINT_MAX) {
1558 uint32_t data_size =
1559 (uint32_t)((uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1583 SCLogDebug(
"http_state_memcnt %"PRIu64
", http_state_memuse %"PRIu64
"",
1584 htp_state_memcnt, htp_state_memuse);
1601 htp_config_destroy(cfglist.
cfg);
1602 while (nextrec != NULL) {
1604 nextrec = nextrec->
next;
1606 htp_config_destroy(htprec->
cfg);
1614 static int HTPCallbackRequestHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1619 return HTP_STATUS_OK;
1622 static int HTPCallbackResponseHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1627 return HTP_STATUS_OK;
1630 static void *HTPCallbackTxCreate(
bool request)
1649 static int HTPCallbackRequestStart(
const htp_connp_t *connp, htp_tx_t *tx)
1651 HtpState *hstate = htp_connp_user_data(connp);
1652 if (hstate == NULL) {
1656 uint64_t consumed = hstate->
slice->
offset + htp_connp_request_data_consumed(hstate->
connp);
1657 SCLogDebug(
"HTTP request start: data offset %" PRIu64
", in_data_counter %" PRIu64, consumed,
1658 (uint64_t)htp_conn_request_data_counter(hstate->
conn));
1682 static int HTPCallbackResponseStart(
const htp_connp_t *connp, htp_tx_t *tx)
1684 HtpState *hstate = htp_connp_user_data(connp);
1685 if (hstate == NULL) {
1689 uint64_t consumed = hstate->
slice->
offset + htp_connp_response_data_consumed(hstate->
connp);
1690 SCLogDebug(
"HTTP response start: data offset %" PRIu64
", out_data_counter %" PRIu64, consumed,
1691 (uint64_t)htp_conn_response_data_counter(hstate->
conn));
1716 static int HTPCallbackRequestComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1724 HtpState *hstate = htp_connp_user_data(connp);
1725 if (hstate == NULL) {
1729 const uint64_t abs_right_edge =
1738 SCLogDebug(
"HTTP request complete: data offset %" PRIu64
", request_size %" PRIu64,
1740 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1742 frame->
len = (int64_t)request_size;
1748 SCLogDebug(
"transaction_cnt %"PRIu64
", list_size %"PRIu64,
1753 HTPErrorCheckTxRequestFlags(hstate, tx);
1758 SCLogDebug(
"closing file that was being stored");
1761 if (abs_right_edge < (uint64_t)UINT32_MAX) {
1763 hstate->
f->
protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
1780 static int HTPCallbackResponseComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1784 HtpState *hstate = htp_connp_user_data(connp);
1785 if (hstate == NULL) {
1792 const uint64_t abs_right_edge =
1800 SCLogDebug(
"HTTP response complete: data offset %" PRIu64
", response_size %" PRIu64,
1802 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1804 frame->
len = (int64_t)response_size;
1812 SCLogDebug(
"closing file that was being stored");
1822 if (htp_tx_request_method_number(tx) == HTP_METHOD_CONNECT) {
1825 if ((htp_tx_response_status_number(tx) >= 200) &&
1826 (htp_tx_response_status_number(tx) < 300) && (hstate->
transaction_cnt == 1)) {
1828 if (htp_tx_request_port_number(tx) != -1) {
1829 dp = (uint16_t)htp_tx_request_port_number(tx);
1843 static int HTPCallbackRequestLine(
const htp_connp_t *connp, htp_tx_t *tx)
1845 HtpState *hstate = htp_connp_user_data(connp);
1847 if (htp_tx_flags(tx)) {
1848 HTPErrorCheckTxRequestFlags(hstate, tx);
1850 return HTP_STATUS_OK;
1853 static int HTPCallbackRequestHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1856 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1857 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1858 return HTP_STATUS_OK;
1864 return HTP_STATUS_OK;
1870 htp_tx_data_len(tx_data));
1873 if (tx && htp_tx_flags(tx)) {
1874 HtpState *hstate = htp_connp_user_data(connp);
1875 HTPErrorCheckTxRequestFlags(hstate, tx);
1877 return HTP_STATUS_OK;
1880 static int HTPCallbackResponseHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1883 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1884 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1885 return HTP_STATUS_OK;
1892 return HTP_STATUS_OK;
1897 htp_tx_data_len(tx_data));
1900 return HTP_STATUS_OK;
1906 static void HTPConfigSetDefaultsPhase1(
HTPCfgRec *cfg_prec)
1908 htp_config_set_normalized_uri_include_all(cfg_prec->
cfg,
false);
1923 htp_config_register_request_header_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1924 htp_config_register_request_trailer_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1925 htp_config_register_response_header_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1926 htp_config_register_response_trailer_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1928 htp_config_register_request_trailer(cfg_prec->
cfg, HTPCallbackRequestHasTrailer);
1929 htp_config_register_response_trailer(cfg_prec->
cfg, HTPCallbackResponseHasTrailer);
1931 htp_config_register_request_body_data(cfg_prec->
cfg, HTPCallbackRequestBodyData);
1932 htp_config_register_response_body_data(cfg_prec->
cfg, HTPCallbackResponseBodyData);
1934 htp_config_register_tx_create(cfg_prec->
cfg, HTPCallbackTxCreate);
1935 htp_config_register_tx_destroy(cfg_prec->
cfg, HtpTxUserDataFree);
1937 htp_config_register_request_start(cfg_prec->
cfg, HTPCallbackRequestStart);
1938 htp_config_register_request_complete(cfg_prec->
cfg, HTPCallbackRequestComplete);
1940 htp_config_register_response_start(cfg_prec->
cfg, HTPCallbackResponseStart);
1941 htp_config_register_response_complete(cfg_prec->
cfg, HTPCallbackResponseComplete);
1943 htp_config_set_parse_request_cookies(cfg_prec->
cfg, 0);
1944 htp_config_set_allow_space_uri(cfg_prec->
cfg, 1);
1947 htp_config_set_plusspace_decode(cfg_prec->
cfg, 0);
1949 htp_config_set_request_decompression(cfg_prec->
cfg, 1);
1954 #define HTP_CONFIG_DEFAULT_MAX_TX_LIMIT 512
1956 #define HTP_CONFIG_DEFAULT_HEADERS_LIMIT 1024
1964 static int RandomGetWrap(
void)
1970 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
1972 return r % RAND_MAX;
1981 static void HTPConfigSetDefaultsPhase2(
const char *
name,
HTPCfgRec *cfg_prec)
1987 long int r = RandomGetWrap();
1989 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
1991 r = RandomGetWrap();
1993 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
1994 SCLogConfig(
"'%s' server has 'request-body-minimal-inspect-size' set to"
1995 " %u and 'request-body-inspect-window' set to %u after"
1999 r = RandomGetWrap();
2001 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2003 r = RandomGetWrap();
2005 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2007 SCLogConfig(
"'%s' server has 'response-body-minimal-inspect-size' set to"
2008 " %u and 'response-body-inspect-window' set to %u after"
2013 htp_config_register_request_line(cfg_prec->
cfg, HTPCallbackRequestLine);
2016 static void HTPConfigParseParameters(
HTPCfgRec *cfg_prec,
SCConfNode *s,
struct HTPConfigTree *tree)
2018 if (cfg_prec == NULL || s == NULL || tree == NULL)
2025 if (strcasecmp(
"address",
p->name) == 0) {
2031 if (strchr(pval->
val,
':') != NULL) {
2032 SCLogDebug(
"LIBHTP adding ipv6 server %s at %s: %p",
2036 SCLogWarning(
"LIBHTP failed to add ipv6 server %s, ignoring", pval->
val);
2039 SCLogDebug(
"LIBHTP adding ipv4 server %s at %s: %p",
2043 SCLogWarning(
"LIBHTP failed to add ipv4 server %s, ignoring", pval->
val);
2048 }
else if (strcasecmp(
"personality",
p->name) == 0) {
2050 int personality = HTPLookupPersonality(
p->val);
2051 SCLogDebug(
"LIBHTP default: %s = %s",
p->name,
p->val);
2052 SCLogDebug(
"LIBHTP default: %s = %s",
p->name,
p->val);
2054 if (personality >= 0) {
2055 SCLogDebug(
"LIBHTP default: %s=%s (%d)",
p->name,
p->val,
2057 if (htp_config_set_server_personality(cfg_prec->
cfg, personality) ==
2060 "personality \"%s\", ignoring",
2064 HTPLookupPersonalityString(personality));
2070 htp_config_set_convert_lowercase(cfg_prec->
cfg, 0);
2078 }
else if (strcasecmp(
"request-body-limit",
p->name) == 0 ||
2079 strcasecmp(
"request_body_limit",
p->name) == 0) {
2081 SCLogError(
"Error parsing request-body-limit "
2082 "from conf file - %s. Killing engine",
2087 }
else if (strcasecmp(
"response-body-limit",
p->name) == 0) {
2089 SCLogError(
"Error parsing response-body-limit "
2090 "from conf file - %s. Killing engine",
2095 }
else if (strcasecmp(
"request-body-minimal-inspect-size",
p->name) == 0) {
2097 SCLogError(
"Error parsing request-body-minimal-inspect-size "
2098 "from conf file - %s. Killing engine",
2103 }
else if (strcasecmp(
"request-body-inspect-window",
p->name) == 0) {
2105 SCLogError(
"Error parsing request-body-inspect-window "
2106 "from conf file - %s. Killing engine",
2111 }
else if (strcasecmp(
"double-decode-query",
p->name) == 0) {
2113 }
else if (strcasecmp(
"double-decode-path",
p->name) == 0) {
2115 }
else if (strcasecmp(
"response-body-minimal-inspect-size",
p->name) == 0) {
2117 SCLogError(
"Error parsing response-body-minimal-inspect-size "
2118 "from conf file - %s. Killing engine",
2123 }
else if (strcasecmp(
"response-body-inspect-window",
p->name) == 0) {
2125 SCLogError(
"Error parsing response-body-inspect-window "
2126 "from conf file - %s. Killing engine",
2131 }
else if (strcasecmp(
"response-body-decompress-layer-limit",
p->name) == 0) {
2134 SCLogError(
"Error parsing response-body-inspect-window "
2135 "from conf file - %s. Killing engine",
2139 htp_config_set_decompression_layer_limit(cfg_prec->
cfg, value);
2140 }
else if (strcasecmp(
"path-convert-backslash-separators",
p->name) == 0) {
2142 }
else if (strcasecmp(
"path-bestfit-replacement-char",
p->name) == 0) {
2143 if (strlen(
p->val) == 1) {
2144 htp_config_set_bestfit_replacement_byte(cfg_prec->
cfg,
p->val[0]);
2147 "for libhtp param path-bestfit-replacement-char");
2149 }
else if (strcasecmp(
"path-convert-lowercase",
p->name) == 0) {
2151 }
else if (strcasecmp(
"path-nul-encoded-terminates",
p->name) == 0) {
2153 }
else if (strcasecmp(
"path-nul-raw-terminates",
p->name) == 0) {
2155 }
else if (strcasecmp(
"path-separators-compress",
p->name) == 0) {
2157 }
else if (strcasecmp(
"path-separators-decode",
p->name) == 0) {
2159 }
else if (strcasecmp(
"path-u-encoding-decode",
p->name) == 0) {
2161 }
else if (strcasecmp(
"path-url-encoding-invalid-handling",
p->name) == 0) {
2162 enum htp_url_encoding_handling_t handling;
2163 if (strcasecmp(
p->val,
"preserve_percent") == 0) {
2164 handling = HTP_URL_ENCODING_HANDLING_PRESERVE_PERCENT;
2165 }
else if (strcasecmp(
p->val,
"remove_percent") == 0) {
2166 handling = HTP_URL_ENCODING_HANDLING_REMOVE_PERCENT;
2167 }
else if (strcasecmp(
p->val,
"decode_invalid") == 0) {
2168 handling = HTP_URL_ENCODING_HANDLING_PROCESS_INVALID;
2171 "for libhtp param path-url-encoding-invalid-handling");
2174 htp_config_set_url_encoding_invalid_handling(cfg_prec->
cfg, handling);
2175 }
else if (strcasecmp(
"path-utf8-convert-bestfit",
p->name) == 0) {
2177 }
else if (strcasecmp(
"uri-include-all",
p->name) == 0) {
2180 }
else if (strcasecmp(
"query-plusspace-decode",
p->name) == 0) {
2182 }
else if (strcasecmp(
"meta-field-limit",
p->name) == 0) {
2186 "from conf file - %s. Killing engine",
2192 "from conf file cannot be 0. Killing engine");
2195 htp_config_set_field_limit(cfg_prec->
cfg, (
size_t)limit);
2196 }
else if (strcasecmp(
"lzma-memlimit",
p->name) == 0) {
2199 FatalError(
"failed to parse 'lzma-memlimit' "
2200 "from conf file - %s.",
2205 "from conf file cannot be 0.");
2208 SCLogConfig(
"Setting HTTP LZMA memory limit to %"PRIu32
" bytes", limit);
2209 htp_config_set_lzma_memlimit(cfg_prec->
cfg, (
size_t)limit);
2210 }
else if (strcasecmp(
"lzma-enabled",
p->name) == 0) {
2212 htp_config_set_lzma_layers(cfg_prec->
cfg, 1);
2217 "from conf file - %s.",
2220 SCLogConfig(
"Setting HTTP LZMA decompression layers to %" PRIu32
"", (
int)limit);
2221 htp_config_set_lzma_layers(cfg_prec->
cfg, limit);
2223 }
else if (strcasecmp(
"compression-bomb-count",
p->name) == 0) {
2226 FatalError(
"failed to parse 'compression-bomb-count' "
2227 "from conf file - %s.",
2232 "from conf file cannot be 0.");
2235 SCLogConfig(
"Setting HTTP compression bomb count limit to %" PRIu8, limit);
2236 htp_config_set_max_nb_compression_bombs(cfg_prec->
cfg, (
size_t)limit);
2237 }
else if (strcasecmp(
"compression-bomb-limit",
p->name) == 0) {
2240 FatalError(
"failed to parse 'compression-bomb-limit' "
2241 "from conf file - %s.",
2246 "from conf file cannot be 0.");
2249 SCLogConfig(
"Setting HTTP compression bomb limit to %"PRIu32
" bytes", limit);
2250 htp_config_set_compression_bomb_limit(cfg_prec->
cfg, (
size_t)limit);
2251 }
else if (strcasecmp(
"decompression-time-limit",
p->name) == 0) {
2255 FatalError(
"failed to parse 'decompression-time-limit' "
2256 "from conf file - %s.",
2259 SCLogConfig(
"Setting HTTP decompression time limit to %" PRIu32
" usec", limit);
2260 htp_config_set_compression_time_limit(cfg_prec->
cfg, limit);
2261 }
else if (strcasecmp(
"max-tx",
p->name) == 0) {
2265 "from conf file - %s.",
2269 SCLogConfig(
"Setting HTTP max-tx limit to %" PRIu32
" bytes", limit);
2270 htp_config_set_max_tx(cfg_prec->
cfg, limit);
2271 }
else if (strcasecmp(
"headers-limit",
p->name) == 0) {
2274 FatalError(
"failed to parse 'headers-limit' "
2275 "from conf file - %s.",
2278 SCLogConfig(
"Setting HTTP headers limit to %" PRIu32, limit);
2279 htp_config_set_number_headers_limit(cfg_prec->
cfg, limit);
2280 }
else if (strcasecmp(
"randomize-inspection-sizes",
p->name) == 0) {
2284 }
else if (strcasecmp(
"randomize-inspection-range",
p->name) == 0) {
2287 (
const char *)
p->val, 0, 100) < 0) {
2289 "-inspection-range setting from conf file - \"%s\"."
2290 " It should be a valid integer less than or equal to 100."
2296 }
else if (strcasecmp(
"http-body-inline",
p->name) == 0) {
2302 if (strcmp(
"auto",
p->val) != 0) {
2311 }
else if (strcasecmp(
"swf-decompression",
p->name) == 0) {
2315 if (strcasecmp(
"enabled", pval->
name) == 0) {
2323 }
else if (strcasecmp(
"type", pval->
name) == 0) {
2324 if (strcasecmp(
"no", pval->
val) == 0) {
2326 }
else if (strcasecmp(
"deflate", pval->
val) == 0) {
2328 }
else if (strcasecmp(
"lzma", pval->
val) == 0) {
2330 }
else if (strcasecmp(
"both", pval->
val) == 0) {
2334 "swf-decompression.type: %s - "
2339 }
else if (strcasecmp(
"compress-depth", pval->
name) == 0) {
2342 SCLogError(
"Invalid swf-decompression.compress-depth value %s: the "
2343 "maximum is %u bytes. Killing engine",
2347 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2350 SCLogError(
"Invalid swf-decompression.decompress-depth value %s: the "
2351 "maximum is %u bytes. Killing engine",
2361 "default config: %s",
2371 cfglist.
next = NULL;
2378 cfglist.
cfg = htp_config_create();
2379 if (NULL == cfglist.
cfg) {
2380 FatalError(
"Failed to create HTP default config");
2383 HTPConfigSetDefaultsPhase1(&cfglist);
2384 if (
SCConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2385 HTPConfigParseParameters(&cfglist,
SCConfGetNode(
"libhtp.default-config"), &cfgtree);
2387 HTPConfigParseParameters(&cfglist,
2388 SCConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), &cfgtree);
2390 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2396 if (server_config == NULL) {
2398 if (server_config == NULL) {
2399 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2403 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2422 cfglist.
next = htprec;
2425 cfglist.
next->
cfg = htp_config_create();
2426 if (NULL == cfglist.
next->
cfg) {
2427 FatalError(
"Failed to create HTP server config");
2430 HTPConfigSetDefaultsPhase1(htprec);
2431 HTPConfigParseParameters(htprec, s, &cfgtree);
2432 HTPConfigSetDefaultsPhase2(s->
name, htprec);
2442 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
2456 htp_tx_t *tx = (htp_tx_t *)txv;
2458 if (direction & STREAM_TOCLIENT) {
2466 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
2468 if (direction & STREAM_TOSERVER)
2469 return htp_tx_request_progress((htp_tx_t *)tx);
2471 return htp_tx_response_progress((htp_tx_t *)tx);
2474 static uint64_t HTPStateGetTxCnt(
void *alstate)
2478 if (http_state != NULL && http_state->
connp != NULL) {
2479 const int64_t size = htp_connp_tx_size(http_state->
connp);
2483 return (uint64_t)size;
2489 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
2493 if (http_state != NULL && http_state->
connp != NULL)
2494 return (
void *)htp_connp_tx(http_state->
connp, tx_id);
2503 uint64_t size = HTPStateGetTxCnt(alstate);
2506 while (state->
un.
u64 < size) {
2507 htp_tx_t *tx = htp_connp_tx_index(http_state->
connp, state->
un.
u64);
2511 uint64_t tx_id = htp_tx_index(tx);
2512 if (tx_id < min_tx_id) {
2519 .has_next = (tx_id + 1) < size,
2531 if (http_state != NULL && http_state->
connp != NULL) {
2532 size_t txid = htp_connp_tx_size(http_state->
connp);
2534 return (
void *)htp_connp_tx(http_state->
connp, txid - 1);
2540 static int HTPStateGetEventInfo(
2550 static int HTPStateGetEventInfoById(
2554 if (*event_name == NULL) {
2556 "http's enum map table.",
2569 htp_tx_t *tx = (htp_tx_t *)vtx;
2580 static int HTPRegisterPatternsForProtocolDetection(
void)
2582 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
2583 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
2584 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
2585 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
2586 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
2587 const char *spacings[] = {
"|20|",
"|09|", NULL };
2588 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
2593 int register_result;
2594 char method_buffer[32] =
"";
2597 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
2598 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
2601 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
2608 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
2609 if (register_result < 0) {
2616 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
2618 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
2620 if (register_result < 0) {
2636 const char *proto_name =
"http";
2641 if (HTPRegisterPatternsForProtocolDetection() < 0)
2644 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
2659 ALPROTO_HTTP1, HTP_REQUEST_PROGRESS_COMPLETE, HTP_RESPONSE_PROGRESS_COMPLETE);
2671 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
2673 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
2677 IPPROTO_TCP,
ALPROTO_HTTP1, APP_LAYER_PARSER_OPT_ACCEPT_GAPS);
2679 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
2682 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
2685 IPPROTO_TCP,
ALPROTO_HTTP1, HtpStateGetStateIdByName, HtpStateGetStateNameById);
2689 SCLogInfo(
"Parser disabled for %s protocol. Protocol detection still on.", proto_name);
2705 cfglist_backup = cfglist;
2710 cfglist = cfglist_backup;
2715 static int HTPParserTest01(
void)
2717 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2719 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2722 memset(&ssn, 0,
sizeof(ssn));
2730 f->
proto = IPPROTO_TCP;
2736 for (u = 0; u < httplen1; u++) {
2740 flags = STREAM_TOSERVER|STREAM_START;
2741 else if (u == (httplen1 - 1))
2742 flags = STREAM_TOSERVER|STREAM_EOF;
2744 flags = STREAM_TOSERVER;
2753 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2756 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2759 FAIL_IF(bstr_cmp_c(htp_header_value(h),
"Victor/1.0"));
2760 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2761 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2770 static int HTPParserTest01b(
void)
2772 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2774 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2777 memset(&ssn, 0,
sizeof(ssn));
2785 f->
proto = IPPROTO_TCP;
2790 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
2797 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2800 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2803 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2804 FAIL_IF(strcmp(v,
"Victor/1.0"));
2806 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2807 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2816 static int HTPParserTest01c(
void)
2818 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2820 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2823 memset(&ssn, 0,
sizeof(ssn));
2831 f->
proto = IPPROTO_TCP;
2837 for (u = 0; u < httplen1; u++) {
2841 flags = STREAM_TOSERVER|STREAM_START;
2842 else if (u == (httplen1 - 1))
2843 flags = STREAM_TOSERVER|STREAM_EOF;
2845 flags = STREAM_TOSERVER;
2854 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2857 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2860 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2861 FAIL_IF(strcmp(v,
"Victor/1.0"));
2863 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2864 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2874 static int HTPParserTest01a(
void)
2877 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2879 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2884 memset(&ssn, 0,
sizeof(ssn));
2886 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2889 f->
proto = IPPROTO_TCP;
2895 for (u = 0; u < httplen1; u++) {
2899 flags = STREAM_TOSERVER|STREAM_START;
2900 else if (u == (httplen1 - 1))
2901 flags = STREAM_TOSERVER|STREAM_EOF;
2903 flags = STREAM_TOSERVER;
2912 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2915 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2918 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2919 FAIL_IF(strcmp(v,
"Victor/1.0"));
2921 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2922 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2931 static int HTPParserTest02(
void)
2934 uint8_t httpbuf1[] =
"POST";
2935 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2940 memset(&ssn, 0,
sizeof(ssn));
2942 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2945 f->
proto = IPPROTO_TCP;
2951 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
2957 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
2959 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2963 char *method = bstr_util_strdup_to_c(htp_tx_request_method(tx));
2966 FAIL_IF(strcmp(method,
"POST") != 0);
2977 static int HTPParserTest03(
void)
2980 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
2981 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2986 memset(&ssn, 0,
sizeof(ssn));
2988 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2991 f->
proto = IPPROTO_TCP;
2997 for (u = 0; u < httplen1; u++) {
3000 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3001 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3002 else flags = STREAM_TOSERVER;
3010 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3013 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3015 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3016 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
3026 static int HTPParserTest04(
void)
3030 uint8_t httpbuf1[] =
"World!\r\n";
3031 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3035 memset(&ssn, 0,
sizeof(ssn));
3037 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3040 f->
proto = IPPROTO_TCP;
3046 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3052 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3054 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3056 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3057 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V0_9);
3067 static int HTPParserTest05(
void)
3069 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3070 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3071 uint8_t httpbuf2[] =
"Post D";
3072 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3073 uint8_t httpbuf3[] =
"ata is c0oL!";
3074 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3076 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3077 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3078 uint8_t httpbuf5[] =
"post R";
3079 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3080 uint8_t httpbuf6[] =
"esults are tha bomb!";
3081 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3084 memset(&ssn, 0,
sizeof(ssn));
3092 f->
proto = IPPROTO_TCP;
3122 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3124 FAIL_IF_NOT(htp_tx_request_method_number(tx) == HTP_METHOD_POST);
3125 FAIL_IF_NOT(htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_V1_0);
3127 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3130 FAIL_IF_NOT(htp_tx_response_status_number(tx) == 200);
3140 static int HTPParserTest06(
void)
3142 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3143 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3144 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3145 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3146 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3148 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3149 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3150 "FrontPage/5.0.2.2510\r\n"
3151 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3153 "Content-Type: text/html\r\n\r\n"
3155 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3156 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3157 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3158 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3159 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3160 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3161 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3162 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3163 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3164 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3165 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3166 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3167 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3168 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3169 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3170 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3171 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3172 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3173 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3174 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3175 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3176 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3177 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3178 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3179 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3180 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3181 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3182 "aHA=\r\n0\r\n\r\n";
3183 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3189 memset(&ssn, 0,
sizeof(ssn));
3194 f->
proto = IPPROTO_TCP;
3209 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3212 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
3213 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3215 FAIL_IF(htp_tx_response_status_number(tx) != 200);
3216 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3218 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3229 static int HTPParserTest07(
void)
3232 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3233 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3238 memset(&ssn, 0,
sizeof(ssn));
3240 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3243 f->
proto = IPPROTO_TCP;
3249 for (u = 0; u < httplen1; u++) {
3253 flags = STREAM_TOSERVER|STREAM_START;
3254 else if (u == (httplen1 - 1))
3255 flags = STREAM_TOSERVER|STREAM_EOF;
3257 flags = STREAM_TOSERVER;
3266 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3267 size_t reflen =
sizeof(ref) - 1;
3269 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3271 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3273 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3275 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref, bstr_len(request_uri_normalized)) != 0);
3287 static int HTPParserTest08(
void)
3290 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3291 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3312 memset(&ssn, 0,
sizeof(ssn));
3314 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3317 f->
proto = IPPROTO_TCP;
3322 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3330 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3332 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3334 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3348 static int HTPParserTest09(
void)
3351 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3352 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3362 personality: Apache_2_2\n\
3374 memset(&ssn, 0,
sizeof(ssn));
3376 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3379 f->
proto = IPPROTO_TCP;
3384 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3392 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3394 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3396 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3410 static int HTPParserTest10(
void)
3414 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3415 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3420 memset(&ssn, 0,
sizeof(ssn));
3422 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3425 f->
proto = IPPROTO_TCP;
3431 for (u = 0; u < httplen1; u++) {
3435 flags = STREAM_TOSERVER|STREAM_START;
3436 else if (u == (httplen1 - 1))
3437 flags = STREAM_TOSERVER|STREAM_EOF;
3439 flags = STREAM_TOSERVER;
3448 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3449 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3452 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3456 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3458 FAIL_IF(strcmp(value,
"www.google.com") != 0);
3470 static int HTPParserTest11(
void)
3473 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3474 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3479 memset(&ssn, 0,
sizeof(ssn));
3481 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3484 f->
proto = IPPROTO_TCP;
3490 for (u = 0; u < httplen1; u++) {
3494 flags = STREAM_TOSERVER|STREAM_START;
3495 else if (u == (httplen1 - 1))
3496 flags = STREAM_TOSERVER|STREAM_EOF;
3498 flags = STREAM_TOSERVER;
3507 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3509 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3512 FAIL_IF(bstr_len(request_uri_normalized) != 4);
3513 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3514 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'%');
3515 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'0');
3516 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'0');
3526 static int HTPParserTest12(
void)
3529 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3530 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3535 memset(&ssn, 0,
sizeof(ssn));
3537 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3540 f->
proto = IPPROTO_TCP;
3546 for (u = 0; u < httplen1; u++) {
3550 flags = STREAM_TOSERVER|STREAM_START;
3551 else if (u == (httplen1 - 1))
3552 flags = STREAM_TOSERVER|STREAM_EOF;
3554 flags = STREAM_TOSERVER;
3563 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3565 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3568 FAIL_IF(bstr_len(request_uri_normalized) != 7);
3569 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3570 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'?');
3571 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'a');
3572 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'=');
3573 FAIL_IF(bstr_ptr(request_uri_normalized)[4] !=
'%');
3574 FAIL_IF(bstr_ptr(request_uri_normalized)[5] !=
'0');
3575 FAIL_IF(bstr_ptr(request_uri_normalized)[6] !=
'0');
3585 static int HTPParserTest13(
void)
3588 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3589 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3594 memset(&ssn, 0,
sizeof(ssn));
3596 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3599 f->
proto = IPPROTO_TCP;
3605 for (u = 0; u < httplen1; u++) {
3609 flags = STREAM_TOSERVER|STREAM_START;
3610 else if (u == (httplen1 - 1))
3611 flags = STREAM_TOSERVER|STREAM_EOF;
3613 flags = STREAM_TOSERVER;
3621 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3622 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3625 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3629 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3631 FAIL_IF(strcmp(value,
"www.google.com\rName: Value") != 0);
3643 static int HTPParserConfigTest01(
void)
3656 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3657 personality: Tomcat_6_0\n\
3662 - 192.168.10.0/24\n\
3663 personality: IIS_7_0\n\
3672 outputs =
SCConfGetNode(
"libhtp.default-config.personality");
3683 FAIL_IF(strcmp(node->
name,
"apache-tomcat") != 0);
3690 FAIL_IF(strcmp(node2->
val,
"Tomcat_6_0") != 0);
3700 FAIL_IF(strcmp(n->
val,
"192.168.1.0/24") != 0);
3740 FAIL_IF(strcmp(n->
val,
"192.168.0.0/24") != 0);
3744 FAIL_IF(strcmp(n->
val,
"192.168.10.0/24") != 0);
3759 static int HTPParserConfigTest02(
void)
3772 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3773 personality: Tomcat_6_0\n\
3778 - 192.168.10.0/24\n\
3779 personality: IIS_7_0\n\
3791 htp_cfg_t *htp = cfglist.
cfg;
3794 void *user_data = NULL;
3796 addr =
"192.168.10.42";
3797 FAIL_IF(inet_pton(AF_INET, addr, buf) != 1);
3801 htp = htp_cfg_rec->
cfg;
3807 FAIL_IF(inet_pton(AF_INET6, addr, buf) != 1);
3810 htp_cfg_rec = user_data;
3811 htp = htp_cfg_rec->
cfg;
3824 static int HTPParserConfigTest03(
void)
3827 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3829 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3845 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3846 personality: Tomcat_6_0\n\
3851 - 192.168.10.0/24\n\
3852 personality: IIS_7_0\n\
3863 const char *addr =
"192.168.10.42";
3865 memset(&ssn, 0,
sizeof(ssn));
3870 f->
proto = IPPROTO_TCP;
3873 htp_cfg_t *htp = cfglist.
cfg;
3876 void *user_data = NULL;
3881 htp = htp_cfg_rec->
cfg;
3888 for (u = 0; u < httplen1; u++) {
3891 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3892 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3893 else flags = STREAM_TOSERVER;
3902 FAIL_IF(HTPStateGetTxCnt(htp_state) != 2);
3904 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3906 tx = HTPStateGetTx(htp_state, 1);
3925 static int HTPParserDecodingTest01(
void)
3927 uint8_t httpbuf1[] =
3928 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3929 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3930 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
3931 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3942 personality: Apache_2\n\
3950 const char *addr =
"4.3.2.1";
3951 memset(&ssn, 0,
sizeof(ssn));
3956 f->
proto = IPPROTO_TCP;
3961 for (uint32_t u = 0; u < httplen1; u++) {
3963 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3964 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3965 else flags = STREAM_TOSERVER;
3974 uint8_t ref1[] =
"/abc%2fdef";
3975 size_t reflen =
sizeof(ref1) - 1;
3977 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3981 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3984 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3985 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
3987 uint8_t ref2[] =
"/abc/def?ghi/jkl";
3988 reflen =
sizeof(ref2) - 1;
3990 tx = HTPStateGetTx(htp_state, 1);
3994 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3997 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3998 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4000 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4001 reflen =
sizeof(ref3) - 1;
4002 tx = HTPStateGetTx(htp_state, 2);
4006 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4009 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4010 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4022 static int HTPParserDecodingTest01a(
void)
4024 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4025 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4026 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4027 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4038 personality: Apache_2\n\
4046 const char *addr =
"4.3.2.1";
4047 memset(&ssn, 0,
sizeof(ssn));
4052 f->
proto = IPPROTO_TCP;
4058 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4064 uint8_t ref1[] =
"/abc%2fdef";
4065 size_t reflen =
sizeof(ref1) - 1;
4067 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4071 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4074 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4075 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4077 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4078 reflen =
sizeof(ref2) - 1;
4080 tx = HTPStateGetTx(htp_state, 1);
4083 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4086 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4088 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4090 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4091 reflen =
sizeof(ref3) - 1;
4092 tx = HTPStateGetTx(htp_state, 2);
4095 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4098 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4100 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4118 static int HTPParserDecodingTest02(
void)
4121 uint8_t httpbuf1[] =
4122 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4123 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4124 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4125 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4137 double-decode-path: no\n\
4138 double-decode-query: no\n\
4146 const char *addr =
"4.3.2.1";
4147 memset(&ssn, 0,
sizeof(ssn));
4152 f->
proto = IPPROTO_TCP;
4158 for (u = 0; u < httplen1; u++) {
4161 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4162 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4163 else flags = STREAM_TOSERVER;
4172 uint8_t ref1[] =
"/abc/def";
4173 size_t reflen =
sizeof(ref1) - 1;
4175 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4177 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4179 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4180 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4182 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4183 reflen =
sizeof(ref2) - 1;
4185 tx = HTPStateGetTx(htp_state, 1);
4187 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4189 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4191 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4193 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4194 reflen =
sizeof(ref3) - 1;
4195 tx = HTPStateGetTx(htp_state, 2);
4197 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4199 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4201 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4218 static int HTPParserDecodingTest03(
void)
4221 uint8_t httpbuf1[] =
4222 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4223 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4224 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4236 double-decode-path: yes\n\
4237 double-decode-query: yes\n\
4245 const char *addr =
"4.3.2.1";
4246 memset(&ssn, 0,
sizeof(ssn));
4251 f->
proto = IPPROTO_TCP;
4257 for (u = 0; u < httplen1; u++) {
4260 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4261 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4262 else flags = STREAM_TOSERVER;
4271 uint8_t ref1[] =
"/abc/def";
4272 size_t reflen =
sizeof(ref1) - 1;
4274 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4276 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4278 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4280 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4282 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4283 reflen =
sizeof(ref2) - 1;
4285 tx = HTPStateGetTx(htp_state, 1);
4287 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4289 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4291 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4305 static int HTPParserDecodingTest04(
void)
4308 uint8_t httpbuf1[] =
4309 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4310 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4322 double-decode-path: yes\n\
4323 double-decode-query: yes\n\
4331 const char *addr =
"4.3.2.1";
4332 memset(&ssn, 0,
sizeof(ssn));
4337 f->
proto = IPPROTO_TCP;
4343 for (u = 0; u < httplen1; u++) {
4346 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4347 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4348 else flags = STREAM_TOSERVER;
4357 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
4358 size_t reflen =
sizeof(ref1) - 1;
4360 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4362 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4364 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4366 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4380 static int HTPParserDecodingTest05(
void)
4383 uint8_t httpbuf1[] =
4384 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4385 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4397 double-decode-path: yes\n\
4398 double-decode-query: yes\n\
4406 const char *addr =
"4.3.2.1";
4407 memset(&ssn, 0,
sizeof(ssn));
4412 f->
proto = IPPROTO_TCP;
4418 for (u = 0; u < httplen1; u++) {
4421 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4422 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4423 else flags = STREAM_TOSERVER;
4432 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
4433 size_t reflen =
sizeof(ref1) - 1;
4435 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4437 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4439 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4441 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4455 static int HTPParserDecodingTest06(
void)
4458 uint8_t httpbuf1[] =
4459 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4460 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4472 double-decode-path: yes\n\
4473 double-decode-query: yes\n\
4481 const char *addr =
"4.3.2.1";
4482 memset(&ssn, 0,
sizeof(ssn));
4487 f->
proto = IPPROTO_TCP;
4493 for (u = 0; u < httplen1; u++) {
4496 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4497 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4498 else flags = STREAM_TOSERVER;
4507 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
4508 size_t reflen =
sizeof(ref1) - 1;
4510 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4512 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4514 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4516 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4530 static int HTPParserDecodingTest07(
void)
4533 uint8_t httpbuf1[] =
4534 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4535 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4547 double-decode-path: yes\n\
4548 double-decode-query: yes\n\
4549 query-plusspace-decode: yes\n\
4557 const char *addr =
"4.3.2.1";
4558 memset(&ssn, 0,
sizeof(ssn));
4563 f->
proto = IPPROTO_TCP;
4569 for (u = 0; u < httplen1; u++) {
4572 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4573 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4574 else flags = STREAM_TOSERVER;
4583 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
4584 size_t reflen =
sizeof(ref1) - 1;
4586 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4588 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4590 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4592 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4606 static int HTPParserDecodingTest08(
void)
4609 uint8_t httpbuf1[] =
4610 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4611 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4630 const char *addr =
"4.3.2.1";
4631 memset(&ssn, 0,
sizeof(ssn));
4636 f->
proto = IPPROTO_TCP;
4642 for (u = 0; u < httplen1; u++) {
4645 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4646 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4647 else flags = STREAM_TOSERVER;
4656 uint8_t ref1[] =
"/blah/";
4657 size_t reflen =
sizeof(ref1) - 1;
4659 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4661 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4663 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4665 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4679 static int HTPParserDecodingTest09(
void)
4682 uint8_t httpbuf1[] =
4683 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4684 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4696 uri-include-all: true\n\
4704 const char *addr =
"4.3.2.1";
4705 memset(&ssn, 0,
sizeof(ssn));
4710 f->
proto = IPPROTO_TCP;
4716 for (u = 0; u < httplen1; u++) {
4719 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4720 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4721 else flags = STREAM_TOSERVER;
4730 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
4731 size_t reflen =
sizeof(ref1) - 1;
4733 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4735 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4737 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4739 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4752 static int HTPBodyReassemblyTest01(
void)
4757 memset(&hstate, 0x00,
sizeof(hstate));
4759 memset(&flow, 0x00,
sizeof(flow));
4761 htp_cfg_t *cfg = htp_config_create();
4763 htp_connp_t *connp = htp_connp_create(cfg);
4765 const htp_tx_t *tx = htp_connp_get_request_tx(connp);
4771 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
4772 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";
4779 const uint8_t *chunks_buffer = NULL;
4780 uint32_t chunks_buffer_len = 0;
4782 HtpRequestBodyReassemble(htud, &chunks_buffer, &chunks_buffer_len);
4785 printf(
"REASSCHUNK START: \n");
4787 printf(
"REASSCHUNK END: \n");
4790 htud->
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
4791 strlen(
"multipart/form-data; boundary=toto"));
4794 HtpRequestBodyHandleMultipart(&hstate, htud, &tx, chunks_buffer, chunks_buffer_len,
false);
4800 htp_connp_destroy_all(connp);
4801 HtpTxUserDataFree(htud);
4803 htp_config_destroy(cfg);
4808 static int HTPSegvTest01(
void)
4811 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";
4812 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4820 double-decode-path: no\n\
4821 double-decode-query: no\n\
4822 request-body-limit: 0\n\
4823 response-body-limit: 0\n\
4836 memset(&ssn, 0,
sizeof(ssn));
4838 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4841 f->
proto = IPPROTO_TCP;
4846 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
4850 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
4871 static int HTPParserTest14(
void)
4882 double-decode-path: no\n\
4883 double-decode-query: no\n\
4884 request-body-limit: 0\n\
4885 response-body-limit: 0\n\
4890 memset(&ssn, 0,
sizeof(ssn));
4900 memset(httpbuf, 0x00,
len);
4903 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4904 "Host: myhost.lan\r\n"
4905 "Connection: keep-alive\r\n"
4907 "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"
4908 "Referer: http://blah.lan/\r\n"
4909 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
4911 size_t o = strlen(httpbuf);
4912 for ( ; o <
len - 4; o++) {
4915 httpbuf[
len - 4] =
'\r';
4916 httpbuf[
len - 3] =
'\n';
4917 httpbuf[
len - 2] =
'\r';
4918 httpbuf[
len - 1] =
'\n';
4924 f->
proto = IPPROTO_TCP;
4929 for (u = 0; u <
len; u++) {
4932 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4933 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4934 else flags = STREAM_TOSERVER;
4942 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4944 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
4945 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
4952 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG);
4967 static int HTPParserTest15(
void)
4970 char *httpbuf = NULL;
4981 double-decode-path: no\n\
4982 double-decode-query: no\n\
4983 request-body-limit: 0\n\
4984 response-body-limit: 0\n\
4985 meta-field-limit: 20000\n\
4989 memset(&ssn, 0,
sizeof(ssn));
5000 memset(httpbuf, 0x00,
len);
5003 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5004 "Host: myhost.lan\r\n"
5005 "Connection: keep-alive\r\n"
5007 "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"
5008 "Referer: http://blah.lan/\r\n"
5009 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5011 size_t o = strlen(httpbuf);
5012 for ( ; o <
len - 4; o++) {
5015 httpbuf[
len - 4] =
'\r';
5016 httpbuf[
len - 3] =
'\n';
5017 httpbuf[
len - 2] =
'\r';
5018 httpbuf[
len - 1] =
'\n';
5020 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5023 f->
proto = IPPROTO_TCP;
5029 for (u = 0; u <
len; u++) {
5032 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5033 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5034 else flags = STREAM_TOSERVER;
5043 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5045 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5046 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5065 static int HTPParserTest16(
void)
5072 memset(&ssn, 0,
sizeof(ssn));
5074 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5075 "Host: myhost.lan\r\n"
5076 "Connection: keep-alive\r\n"
5078 "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"
5079 "Referer: http://blah.lan/\r\n"
5080 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5081 "Cookie: blah\r\n\r\n";
5082 size_t len =
sizeof(httpbuf) - 1;
5084 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5087 f->
proto = IPPROTO_TCP;
5092 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5100 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5102 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5103 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5105 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5112 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT);
5113 FAIL_IF(decoder_events->
events[1] != HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT);
5124 static int HTPParserTest20(
void)
5127 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5128 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5129 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5130 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5131 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
5132 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5133 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5134 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5140 memset(&ssn, 0,
sizeof(ssn));
5142 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5145 f->
proto = IPPROTO_TCP;
5164 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5166 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5169 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5170 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5172 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5173 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5183 static int HTPParserTest21(
void)
5186 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5187 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5188 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5189 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5190 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
5191 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5192 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5193 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5199 memset(&ssn, 0,
sizeof(ssn));
5201 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5204 f->
proto = IPPROTO_TCP;
5223 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5225 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5228 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5229 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5231 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5232 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5242 static int HTPParserTest22(
void)
5245 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5246 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5247 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5248 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5249 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
5250 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5251 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5257 memset(&ssn, 0,
sizeof(ssn));
5259 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5262 f->
proto = IPPROTO_TCP;
5277 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5279 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5282 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5283 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5285 FAIL_IF(htp_tx_response_status_number(tx) != -0);
5286 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5296 static int HTPParserTest23(
void)
5299 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5300 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5301 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5302 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5303 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
5304 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5305 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5311 memset(&ssn, 0,
sizeof(ssn));
5313 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5316 f->
proto = IPPROTO_TCP;
5331 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5333 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5336 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5337 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5339 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5340 FAIL_IF(htp_tx_response_protocol_number(tx) != -2);
5351 static int HTPParserTest24(
void)
5354 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5355 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5356 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5357 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5358 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
5359 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5360 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5366 memset(&ssn, 0,
sizeof(ssn));
5368 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5371 f->
proto = IPPROTO_TCP;
5386 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5388 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5391 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5392 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5394 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5395 FAIL_IF(htp_tx_response_protocol_number(tx) != HTP_PROTOCOL_V1_0);
5405 static int HTPParserTest25(
void)
5412 memset(&ssn, 0,
sizeof(ssn));
5417 f->
proto = IPPROTO_TCP;
5421 const char *
str =
"GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
5423 (uint8_t *)
str, strlen(
str));
5447 str =
"HTTP 1.1 200 OK\r\nServer: Suricata/1.0\r\nContent-Length: 8\r\n\r\nSuricata";
5449 (uint8_t *)
str, strlen(
str));
5483 (uint8_t *)
str, strlen(
str));
5494 (uint8_t *)
str, strlen(
str));
5515 static int HTPParserTest26(
void)
5524 request-body-limit: 1\n\
5525 response-body-limit: 1\n\
5539 uint8_t httpbuf1[] =
"GET /alice.txt HTTP/1.1\r\n\r\n";
5540 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5541 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\n"
5542 "Content-Type: text/plain\r\n"
5543 "Content-Length: 228\r\n\r\n"
5544 "Alice was beginning to get very tired of sitting by her sister on the bank."
5545 "Alice was beginning to get very tired of sitting by her sister on the bank.";
5546 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5547 uint8_t httpbuf3[] =
"Alice was beginning to get very tired of sitting by her sister on the bank.\r\n\r\n";
5548 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5556 memset(&f, 0,
sizeof(f));
5557 memset(&ssn, 0,
sizeof(ssn));
5564 f.
proto = IPPROTO_TCP;
5585 "(filestore; sid:1; rev:1;)");
5654 static int HTPParserTest27(
void)
5657 memset(&cfg, 0,
sizeof(cfg));
5661 uint32_t
len = 1000;
5686 static void HTPParserRegisterTests(
void)
5708 UtRegisterTest(
"HTPParserDecodingTest01", HTPParserDecodingTest01);
5709 UtRegisterTest(
"HTPParserDecodingTest01a", HTPParserDecodingTest01a);
5710 UtRegisterTest(
"HTPParserDecodingTest02", HTPParserDecodingTest02);
5711 UtRegisterTest(
"HTPParserDecodingTest03", HTPParserDecodingTest03);
5712 UtRegisterTest(
"HTPParserDecodingTest04", HTPParserDecodingTest04);
5713 UtRegisterTest(
"HTPParserDecodingTest05", HTPParserDecodingTest05);
5714 UtRegisterTest(
"HTPParserDecodingTest06", HTPParserDecodingTest06);
5715 UtRegisterTest(
"HTPParserDecodingTest07", HTPParserDecodingTest07);
5716 UtRegisterTest(
"HTPParserDecodingTest08", HTPParserDecodingTest08);
5717 UtRegisterTest(
"HTPParserDecodingTest09", HTPParserDecodingTest09);
5719 UtRegisterTest(
"HTPBodyReassemblyTest01", HTPBodyReassemblyTest01);