79 static struct HTPConfigTree {
95 #define HTP_MAX_MESSAGES 512
101 static uint64_t htp_state_memuse = 0;
102 static uint64_t htp_state_memcnt = 0;
106 {
"UNKNOWN_ERROR", HTP_LOG_CODE_UNKNOWN },
107 {
"GZIP_DECOMPRESSION_FAILED", HTP_LOG_CODE_GZIP_DECOMPRESSION_FAILED },
108 {
"REQUEST_FIELD_MISSING_COLON", HTP_LOG_CODE_REQUEST_FIELD_MISSING_COLON },
109 {
"RESPONSE_FIELD_MISSING_COLON", HTP_LOG_CODE_RESPONSE_FIELD_MISSING_COLON },
110 {
"INVALID_REQUEST_CHUNK_LEN", HTP_LOG_CODE_INVALID_REQUEST_CHUNK_LEN },
111 {
"INVALID_RESPONSE_CHUNK_LEN", HTP_LOG_CODE_INVALID_RESPONSE_CHUNK_LEN },
112 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST",
113 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST },
114 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE",
115 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE },
116 {
"INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST",
117 HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST },
118 {
"INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE",
119 HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE },
120 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST",
121 HTP_LOG_CODE_DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST },
122 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE",
123 HTP_LOG_CODE_DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE },
124 {
"100_CONTINUE_ALREADY_SEEN", HTP_LOG_CODE_CONTINUE_ALREADY_SEEN },
125 {
"UNABLE_TO_MATCH_RESPONSE_TO_REQUEST", HTP_LOG_CODE_UNABLE_TO_MATCH_RESPONSE_TO_REQUEST },
126 {
"INVALID_SERVER_PORT_IN_REQUEST", HTP_LOG_CODE_INVALID_SERVER_PORT_IN_REQUEST },
127 {
"INVALID_AUTHORITY_PORT", HTP_LOG_CODE_INVALID_AUTHORITY_PORT },
128 {
"REQUEST_HEADER_INVALID", HTP_LOG_CODE_REQUEST_HEADER_INVALID },
129 {
"RESPONSE_HEADER_INVALID", HTP_LOG_CODE_RESPONSE_HEADER_INVALID },
130 {
"MISSING_HOST_HEADER", HTP_LOG_CODE_MISSING_HOST_HEADER },
131 {
"HOST_HEADER_AMBIGUOUS", HTP_LOG_CODE_HOST_HEADER_AMBIGUOUS },
132 {
"INVALID_REQUEST_FIELD_FOLDING", HTP_LOG_CODE_INVALID_REQUEST_FIELD_FOLDING },
133 {
"INVALID_RESPONSE_FIELD_FOLDING", HTP_LOG_CODE_INVALID_RESPONSE_FIELD_FOLDING },
134 {
"REQUEST_FIELD_TOO_LONG", HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG },
135 {
"RESPONSE_FIELD_TOO_LONG", HTP_LOG_CODE_RESPONSE_FIELD_TOO_LONG },
136 {
"REQUEST_LINE_INVALID", HTP_LOG_CODE_REQUEST_LINE_INVALID },
137 {
"REQUEST_BODY_UNEXPECTED", HTP_LOG_CODE_REQUEST_BODY_UNEXPECTED },
138 {
"RESPONSE_BODY_UNEXPECTED", HTP_LOG_CODE_RESPONSE_BODY_UNEXPECTED },
139 {
"REQUEST_SERVER_PORT_TCP_PORT_MISMATCH", HTP_LOG_CODE_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH },
140 {
"REQUEST_URI_HOST_INVALID", HTP_LOG_CODE_URI_HOST_INVALID },
141 {
"REQUEST_HEADER_HOST_INVALID", HTP_LOG_CODE_HEADER_HOST_INVALID },
142 {
"REQUEST_AUTH_UNRECOGNIZED", HTP_LOG_CODE_AUTH_UNRECOGNIZED },
143 {
"REQUEST_HEADER_REPETITION", HTP_LOG_CODE_REQUEST_HEADER_REPETITION },
144 {
"RESPONSE_HEADER_REPETITION", HTP_LOG_CODE_RESPONSE_HEADER_REPETITION },
145 {
"DOUBLE_ENCODED_URI", HTP_LOG_CODE_DOUBLE_ENCODED_URI },
146 {
"URI_DELIM_NON_COMPLIANT", HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT },
147 {
"METHOD_DELIM_NON_COMPLIANT", HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT },
148 {
"REQUEST_LINE_LEADING_WHITESPACE", HTP_LOG_CODE_REQUEST_LINE_LEADING_WHITESPACE },
149 {
"TOO_MANY_ENCODING_LAYERS", HTP_LOG_CODE_TOO_MANY_ENCODING_LAYERS },
150 {
"REQUEST_TOO_MANY_LZMA_LAYERS", HTP_LOG_CODE_REQUEST_TOO_MANY_LZMA_LAYERS },
151 {
"RESPONSE_TOO_MANY_LZMA_LAYERS", HTP_LOG_CODE_RESPONSE_TOO_MANY_LZMA_LAYERS },
152 {
"ABNORMAL_CE_HEADER", HTP_LOG_CODE_ABNORMAL_CE_HEADER },
153 {
"RESPONSE_MULTIPART_BYTERANGES", HTP_LOG_CODE_RESPONSE_MULTIPART_BYTERANGES },
154 {
"RESPONSE_ABNORMAL_TRANSFER_ENCODING", HTP_LOG_CODE_RESPONSE_ABNORMAL_TRANSFER_ENCODING },
155 {
"RESPONSE_CHUNKED_OLD_PROTO", HTP_LOG_CODE_RESPONSE_CHUNKED_OLD_PROTO },
156 {
"RESPONSE_INVALID_PROTOCOL", HTP_LOG_CODE_RESPONSE_INVALID_PROTOCOL },
157 {
"RESPONSE_INVALID_STATUS", HTP_LOG_CODE_RESPONSE_INVALID_STATUS },
158 {
"REQUEST_LINE_INCOMPLETE", HTP_LOG_CODE_REQUEST_LINE_INCOMPLETE },
159 {
"PROTOCOL_CONTAINS_EXTRA_DATA", HTP_LOG_CODE_PROTOCOL_CONTAINS_EXTRA_DATA },
161 "CONTENT_LENGTH_EXTRA_DATA_START",
162 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_START,
165 "CONTENT_LENGTH_EXTRA_DATA_END",
166 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_END,
169 "CONTENT_LENGTH_EXTRA_DATA_END",
170 HTP_LOG_CODE_CONTENT_LENGTH_EXTRA_DATA_END,
172 {
"SWITCHING_PROTO_WITH_CONTENT_LENGTH", HTP_LOG_CODE_SWITCHING_PROTO_WITH_CONTENT_LENGTH },
173 {
"DEFORMED_EOL", HTP_LOG_CODE_DEFORMED_EOL },
174 {
"PARSER_STATE_ERROR", HTP_LOG_CODE_PARSER_STATE_ERROR },
175 {
"MISSING_OUTBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_OUTBOUND_TRANSACTION_DATA },
176 {
"MISSING_INBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_INBOUND_TRANSACTION_DATA },
177 {
"MISSING_INBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_INBOUND_TRANSACTION_DATA },
178 {
"ZERO_LENGTH_DATA_CHUNKS", HTP_LOG_CODE_ZERO_LENGTH_DATA_CHUNKS },
179 {
"REQUEST_LINE_UNKNOWN_METHOD", HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD },
180 {
"REQUEST_LINE_UNKNOWN_METHOD", HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD },
181 {
"REQUEST_LINE_UNKNOWN_METHOD_NO_PROTOCOL",
182 HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD_NO_PROTOCOL },
183 {
"REQUEST_LINE_UNKNOWN_METHOD_INVALID_PROTOCOL",
184 HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD_INVALID_PROTOCOL },
185 {
"REQUEST_LINE_MISSING_PROTOCOL", HTP_LOG_CODE_REQUEST_LINE_NO_PROTOCOL },
186 {
"RESPONSE_LINE_INVALID_PROTOCOL", HTP_LOG_CODE_RESPONSE_LINE_INVALID_PROTOCOL },
187 {
"RESPONSE_LINE_INVALID_RESPONSE_STATUS", HTP_LOG_CODE_RESPONSE_LINE_INVALID_RESPONSE_STATUS },
188 {
"RESPONSE_BODY_INTERNAL_ERROR", HTP_LOG_CODE_RESPONSE_BODY_INTERNAL_ERROR },
189 {
"REQUEST_BODY_DATA_CALLBACK_ERROR", HTP_LOG_CODE_REQUEST_BODY_DATA_CALLBACK_ERROR },
190 {
"RESPONSE_INVALID_EMPTY_NAME", HTP_LOG_CODE_RESPONSE_INVALID_EMPTY_NAME },
191 {
"REQUEST_INVALID_EMPTY_NAME", HTP_LOG_CODE_REQUEST_INVALID_EMPTY_NAME },
192 {
"RESPONSE_INVALID_LWS_AFTER_NAME", HTP_LOG_CODE_RESPONSE_INVALID_LWS_AFTER_NAME },
193 {
"RESPONSE_HEADER_NAME_NOT_TOKEN", HTP_LOG_CODE_RESPONSE_HEADER_NAME_NOT_TOKEN },
194 {
"REQUEST_INVALID_LWS_AFTER_NAME", HTP_LOG_CODE_REQUEST_INVALID_LWS_AFTER_NAME },
195 {
"LZMA_DECOMPRESSION_DISABLED", HTP_LOG_CODE_LZMA_DECOMPRESSION_DISABLED },
196 {
"CONNECTION_ALREADY_OPEN", HTP_LOG_CODE_CONNECTION_ALREADY_OPEN },
197 {
"COMPRESSION_BOMB_DOUBLE_LZMA", HTP_LOG_CODE_COMPRESSION_BOMB_DOUBLE_LZMA },
198 {
"INVALID_CONTENT_ENCODING", HTP_LOG_CODE_INVALID_CONTENT_ENCODING },
199 {
"INVALID_GAP", HTP_LOG_CODE_INVALID_GAP },
200 {
"REQUEST_CHUNK_EXTENSION", HTP_LOG_CODE_REQUEST_CHUNK_EXTENSION },
201 {
"RESPONSE_CHUNK_EXTENSION", HTP_LOG_CODE_RESPONSE_CHUNK_EXTENSION },
203 {
"LZMA_MEMLIMIT_REACHED", HTP_LOG_CODE_LZMA_MEMLIMIT_REACHED },
204 {
"COMPRESSION_BOMB", HTP_LOG_CODE_COMPRESSION_BOMB },
206 {
"REQUEST_TOO_MANY_HEADERS", HTP_LOG_CODE_REQUEST_TOO_MANY_HEADERS },
207 {
"RESPONSE_TOO_MANY_HEADERS", HTP_LOG_CODE_RESPONSE_TOO_MANY_HEADERS },
240 static int HTTPGetFrameIdByName(
const char *frame_name)
249 static const char *HTTPGetFrameNameById(
const uint8_t frame_id)
259 HTP_REQUEST_PROGRESS_NOT_STARTED,
263 HTP_REQUEST_PROGRESS_LINE,
267 HTP_REQUEST_PROGRESS_HEADERS,
271 HTP_REQUEST_PROGRESS_BODY,
275 HTP_REQUEST_PROGRESS_TRAILER,
279 HTP_REQUEST_PROGRESS_COMPLETE,
288 HTP_RESPONSE_PROGRESS_NOT_STARTED,
292 HTP_RESPONSE_PROGRESS_LINE,
296 HTP_RESPONSE_PROGRESS_HEADERS,
300 HTP_RESPONSE_PROGRESS_BODY,
304 HTP_RESPONSE_PROGRESS_TRAILER,
308 HTP_RESPONSE_PROGRESS_COMPLETE,
313 static int HtpStateGetStateIdByName(
const char *
name,
const uint8_t direction)
316 direction == STREAM_TOSERVER ? http_state_client_table : http_state_server_table;
325 static const char *HtpStateGetStateNameById(
const int id,
const uint8_t direction)
328 direction == STREAM_TOSERVER ? http_state_client_table : http_state_server_table;
333 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id);
334 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction);
335 static uint64_t HTPStateGetTxCnt(
void *alstate);
337 static void HTPParserRegisterTests(
void);
340 static inline uint64_t HtpGetActiveRequestTxID(
HtpState *s)
342 uint64_t
id = HTPStateGetTxCnt(s);
347 static inline uint64_t HtpGetActiveResponseTxID(
HtpState *s)
360 static const char *HTPLookupPersonalityString(
int p)
362 #define CASE_HTP_PERSONALITY_STRING(p) \
363 case HTP_SERVER_PERSONALITY_##p: \
367 CASE_HTP_PERSONALITY_STRING(MINIMAL);
368 CASE_HTP_PERSONALITY_STRING(GENERIC);
369 CASE_HTP_PERSONALITY_STRING(IDS);
370 CASE_HTP_PERSONALITY_STRING(IIS_4_0);
371 CASE_HTP_PERSONALITY_STRING(IIS_5_0);
372 CASE_HTP_PERSONALITY_STRING(IIS_5_1);
373 CASE_HTP_PERSONALITY_STRING(IIS_6_0);
374 CASE_HTP_PERSONALITY_STRING(IIS_7_0);
375 CASE_HTP_PERSONALITY_STRING(IIS_7_5);
376 CASE_HTP_PERSONALITY_STRING(APACHE_2);
390 static int HTPLookupPersonality(
const char *
str)
392 #define IF_HTP_PERSONALITY_NUM(p) \
393 if (strcasecmp(#p, str) == 0) \
394 return HTP_SERVER_PERSONALITY_##p
406 if (strcasecmp(
"TOMCAT_6_0",
str) == 0) {
408 "longer supported by libhtp.",
411 }
else if ((strcasecmp(
"APACHE",
str) == 0) ||
412 (strcasecmp(
"APACHE_2_2",
str) == 0))
415 "longer supported by libhtp, failing back to "
416 "Apache2 personality.",
418 return HTP_SERVER_PERSONALITY_APACHE_2;
425 const uint8_t dir,
const uint8_t e)
435 const uint64_t tx_id = (dir == STREAM_TOSERVER) ?
436 HtpGetActiveRequestTxID(s) : HtpGetActiveResponseTxID(s);
438 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
439 if (tx == NULL && tx_id > 0)
440 tx = HTPStateGetTx(s, tx_id - 1);
444 if (dir & STREAM_TOCLIENT)
445 htud->
tx_data.updated_tc =
true;
446 if (dir & STREAM_TOSERVER)
447 htud->
tx_data.updated_ts =
true;
457 static void *HTPStateAlloc(
void *orig_state,
AppProto proto_orig)
471 htp_state_memuse +=
sizeof(
HtpState);
472 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
479 static void HtpTxUserDataFree(
void *txud)
491 SCAppLayerTxDataCleanup(&htud->
tx_data);
515 if (s->
connp != NULL) {
517 htp_connp_destroy_all(s->
connp);
525 htp_state_memuse -=
sizeof(
HtpState);
526 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
537 static void HTPStateTransactionFree(
void *state, uint64_t
id)
544 htp_tx_destroy(s->
connp,
id);
589 static void AppLayerHtpSetStreamDepthFlag(
void *tx,
const uint8_t
flags)
593 if (
flags & STREAM_TOCLIENT) {
602 SCLogDebug(
"cfg->body_limit %u stream_depth %u body->content_len_so_far %" PRIu64,
619 static uint32_t AppLayerHtpComputeChunkLength(uint64_t content_len_so_far, uint32_t body_limit,
620 uint32_t stream_depth, uint8_t
flags, uint32_t data_len)
622 uint32_t chunk_len = 0;
624 (content_len_so_far < (uint64_t)body_limit) &&
625 (content_len_so_far + (uint64_t)data_len) > body_limit)
627 chunk_len = (uint32_t)(body_limit - content_len_so_far);
629 (content_len_so_far < (uint64_t)stream_depth) &&
630 (content_len_so_far + (uint64_t)data_len) > stream_depth)
632 chunk_len = (uint32_t)(stream_depth - content_len_so_far);
635 return (chunk_len == 0 ? data_len : chunk_len);
646 static void HTPHandleError(
HtpState *s,
const uint8_t dir)
653 htp_log_t *log = htp_conn_next_log(s->
conn);
654 while (log != NULL) {
655 char *msg = htp_log_message(log);
658 log = htp_conn_next_log(s->
conn);
664 htp_log_code_t
id = htp_log_code(log);
665 if (
id != HTP_LOG_CODE_UNKNOWN &&
id != HTP_LOG_CODE_ERROR) {
666 HTPSetEvent(s, NULL, dir, (uint8_t)
id);
668 htp_free_cstring(msg);
678 log = htp_conn_next_log(s->
conn);
683 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s,
const htp_tx_t *tx)
686 BUG_ON(s == NULL || tx == NULL);
688 if (htp_tx_flags(tx) & (HTP_FLAGS_REQUEST_INVALID_T_E | HTP_FLAGS_REQUEST_INVALID_C_L |
689 HTP_FLAGS_HOST_MISSING | HTP_FLAGS_HOST_AMBIGUOUS |
690 HTP_FLAGS_HOSTU_INVALID | HTP_FLAGS_HOSTH_INVALID)) {
693 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_T_E)
694 HTPSetEvent(s, htud, STREAM_TOSERVER,
695 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST);
696 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_C_L)
698 s, htud, STREAM_TOSERVER, HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST);
699 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_MISSING)
700 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_MISSING_HOST_HEADER);
701 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_AMBIGUOUS)
702 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HOST_HEADER_AMBIGUOUS);
703 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTU_INVALID)
704 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_URI_HOST_INVALID);
705 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTH_INVALID)
706 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HEADER_HOST_INVALID);
708 if (htp_tx_request_auth_type(tx) == HTP_AUTH_TYPE_UNRECOGNIZED) {
710 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_AUTH_UNRECOGNIZED);
712 if (htp_tx_is_protocol_0_9(tx) && htp_tx_request_method_number(tx) == HTP_METHOD_UNKNOWN &&
713 (htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_INVALID ||
714 htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_UNKNOWN)) {
716 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_REQUEST_LINE_INVALID);
726 htp_cfg_t *htp = cfglist.
cfg;
727 void *user_data = NULL;
743 if (user_data != NULL) {
744 htp_cfg_rec = user_data;
745 htp = htp_cfg_rec->
cfg;
748 SCLogDebug(
"Using default HTP config: %p", htp);
752 #ifdef DEBUG_VALIDATION
759 hstate->
connp = htp_connp_create(htp);
760 if (hstate->
connp == NULL) {
764 hstate->
conn = (htp_conn_t *)htp_connp_connection(hstate->
connp);
766 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
767 hstate->
cfg = htp_cfg_rec;
772 htp_connp_open(hstate->
connp, NULL, f->
sp, NULL, f->
dp, &
tv);
804 if (NULL == hstate->
conn) {
805 if (Setup(f, hstate) != 0) {
810 hstate->
slice = &stream_slice;
812 const uint8_t *input = StreamSliceGetData(&stream_slice);
813 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
818 const int r = htp_connp_request_data(hstate->
connp, &
ts, input, input_len);
820 case HTP_STREAM_STATE_ERROR:
826 HTPHandleError(hstate, STREAM_TOSERVER);
832 htp_connp_request_close(hstate->
connp, &
ts);
834 SCLogDebug(
"stream eof encountered, closing htp handle for ts");
838 hstate->
slice = NULL;
866 const uint8_t *input = StreamSliceGetData(&stream_slice);
867 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
873 if (NULL == hstate->
conn) {
874 if (Setup(f, hstate) != 0) {
879 hstate->
slice = &stream_slice;
882 const htp_tx_t *tx = NULL;
883 uint32_t consumed = 0;
885 const int r = htp_connp_response_data(hstate->
connp, &
ts, input, input_len);
887 case HTP_STREAM_STATE_ERROR:
890 case HTP_STREAM_STATE_TUNNEL:
891 tx = htp_connp_get_response_tx(hstate->
connp);
892 if (tx != NULL && htp_tx_response_status_number(tx) == 101) {
893 const htp_header_t *h = htp_tx_response_header(tx,
"Upgrade");
898 if (htp_tx_request_port_number(tx) != -1) {
899 dp = (uint16_t)htp_tx_request_port_number(tx);
901 consumed = (uint32_t)htp_connp_response_data_consumed(hstate->
connp);
902 if (bstr_cmp_c(htp_header_value(h),
"h2c") == 0) {
907 hstate->
slice = NULL;
909 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
914 if (consumed > 0 && consumed < input_len) {
918 }
else if (bstr_cmp_c_nocase(htp_header_value(h),
"WebSocket")) {
923 hstate->
slice = NULL;
925 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
930 if (consumed > 0 && consumed < input_len) {
940 HTPHandleError(hstate, STREAM_TOCLIENT);
946 htp_connp_close(hstate->
connp, &
ts);
951 hstate->
slice = NULL;
962 static int HTTPParseContentDispositionHeader(
const uint8_t *
name,
size_t name_len,
963 const uint8_t *data,
size_t len, uint8_t
const **retptr,
size_t *retlen)
966 printf(
"DATA START: \n");
968 printf(
"DATA END: \n");
973 for (x = 0; x <
len; x++) {
974 if (!(isspace(data[x])))
981 const uint8_t *line = data + x;
982 size_t line_len =
len-x;
985 printf(
"LINE START: \n");
987 printf(
"LINE END: \n");
989 for (x = 0 ; x < line_len; x++) {
991 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
995 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
996 const uint8_t *token = line +
offset;
997 size_t token_len = x -
offset;
999 if ((x + 1) == line_len) {
1010 printf(
"TOKEN START: \n");
1012 printf(
"TOKEN END: \n");
1014 if (token_len > name_len) {
1015 if (
name == NULL || SCMemcmpLowercase(
name, token, name_len) == 0) {
1016 const uint8_t *value = token + name_len;
1017 size_t value_len = token_len - name_len;
1019 if (value[0] ==
'\"') {
1023 if (value[value_len-1] ==
'\"') {
1027 printf(
"VALUE START: \n");
1029 printf(
"VALUE END: \n");
1032 *retlen = value_len;
1056 static int HtpRequestBodySetupMultipart(
const htp_tx_t *tx,
HtpTxUserData *htud)
1058 const htp_header_t *h = htp_tx_request_header(tx,
"Content-Type");
1059 if (h != NULL && htp_header_value_len(h) > 0) {
1061 SCMimeStateInit(htp_header_value_ptr(h), (uint32_t)htp_header_value_len(h));
1078 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1081 chunks_buffer, chunks_buffer_len,
1085 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1088 if (tx && tx->
tx_data.de_state) {
1089 if (dir == STREAM_TOSERVER) {
1090 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1092 }
else if (dir == STREAM_TOCLIENT) {
1093 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1100 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len,
bool eof)
1103 printf(
"CHUNK START: \n");
1105 printf(
"CHUNK END: \n");
1111 STREAM_TOSERVER) >= HTP_REQUEST_PROGRESS_COMPLETE);
1113 const uint8_t *cur_buf = chunks_buffer;
1114 uint32_t cur_buf_len = chunks_buffer_len;
1130 const uint8_t *filename = NULL;
1131 uint16_t filename_len = 0;
1134 while (cur_buf_len > 0) {
1135 MimeParserResult r =
1136 SCMimeParse(htud->
mime_state, cur_buf, cur_buf_len, &consumed, &warnings);
1140 if (warnings & MIME_EVENT_FLAG_INVALID_HEADER) {
1144 if (warnings & MIME_EVENT_FLAG_NO_FILEDATA) {
1155 SCMimeStateGetFilename(htud->
mime_state, &filename, &filename_len);
1156 if (filename_len > 0) {
1160 hstate, htud, filename, filename_len, NULL, 0, STREAM_TOSERVER);
1163 }
else if (result == -2) {
1166 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1174 }
else if (result == -2) {
1182 uint32_t lastsize = consumed;
1183 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\n') {
1185 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\r') {
1189 HTPFileClose(htud, cur_buf, lastsize, 0, STREAM_TOSERVER);
1194 cur_buf += consumed;
1195 cur_buf_len -= consumed;
1207 const uint8_t *data, uint32_t data_len)
1214 uint8_t *filename = NULL;
1215 size_t filename_len = 0;
1218 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1219 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1220 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1223 if (filename != NULL) {
1229 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1233 }
else if (result == -2) {
1236 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1250 }
else if (result == -2) {
1263 const uint8_t *data, uint32_t data_len)
1276 const uint8_t *filename = NULL;
1277 size_t filename_len = 0;
1280 const htp_header_t *h = htp_tx_response_header(tx,
"Content-Disposition");
1281 if (h != NULL && htp_header_value_len(h) > 0) {
1283 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1284 htp_header_value_ptr(h), htp_header_value_len(h), &filename, &filename_len);
1288 if (filename == NULL) {
1290 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1291 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1292 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1296 if (filename != NULL) {
1298 const htp_header_t *h_content_range = htp_tx_response_header(tx,
"content-range");
1304 if (h_content_range != NULL) {
1306 data_len, tx, htp_header_value(h_content_range), htud);
1308 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1314 }
else if (result == -2) {
1317 FlagDetectStateNewFile(htud, STREAM_TOCLIENT);
1330 }
else if (result == -2) {
1348 static int HTPCallbackRequestBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1352 const htp_tx_t *tx = htp_tx_data_tx(d);
1357 if (htp_tx_data_is_empty(d))
1361 printf(
"HTPBODY START: \n");
1362 PrintRawDataFp(stdout, (uint8_t *)htp_tx_data_data(d), htp_tx_data_len(d));
1363 printf(
"HTPBODY END: \n");
1366 HtpState *hstate = htp_connp_user_data(connp);
1367 if (hstate == NULL) {
1371 SCLogDebug(
"New request body data available at %p -> %p -> %p, bodylen "
1373 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1376 if (tx_ud == NULL) {
1379 tx_ud->
tx_data.updated_ts =
true;
1385 if (htp_tx_request_method_number(tx) == HTP_METHOD_POST) {
1387 int r = HtpRequestBodySetupMultipart(tx, tx_ud);
1390 }
else if (r == 0) {
1394 }
else if (htp_tx_request_method_number(tx) == HTP_METHOD_PUT) {
1410 (uint32_t)htp_tx_data_len(d));
1415 const uint8_t *chunks_buffer = NULL;
1416 uint32_t chunks_buffer_len = 0;
1424 HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len);
1425 if (chunks_buffer == NULL) {
1429 printf(
"REASSCHUNK START: \n");
1431 printf(
"REASSCHUNK END: \n");
1434 HtpRequestBodyHandleMultipart(hstate, tx_ud, htp_tx_data_tx(d), chunks_buffer,
1435 chunks_buffer_len, (htp_tx_data_data(d) == NULL && htp_tx_data_len(d) == 0));
1439 HtpRequestBodyHandlePOSTorPUT(
1440 hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1445 SCLogDebug(
"closing file that was being stored");
1452 if (hstate->
conn != NULL) {
1453 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1454 ", last %" PRIu64
")",
1456 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1465 if ((uint64_t)htp_conn_request_data_counter(hstate->
conn) >
1467 (uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1469 (uint64_t)UINT_MAX) {
1470 uint32_t data_size =
1471 (uint32_t)((uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1492 static int HTPCallbackResponseBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1496 const htp_tx_t *tx = htp_tx_data_tx(d);
1501 if (htp_tx_data_is_empty(d))
1504 HtpState *hstate = htp_connp_user_data(connp);
1505 if (hstate == NULL) {
1509 SCLogDebug(
"New response body data available at %p -> %p -> %p, bodylen "
1511 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1514 tx_ud->
tx_data.updated_tc =
true;
1531 (uint32_t)htp_tx_data_len(d));
1536 HtpResponseBodyHandle(hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1539 SCLogDebug(
"closing file that was being stored");
1545 if (hstate->
conn != NULL) {
1546 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1547 ", last %" PRIu64
")",
1549 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1557 if ((uint64_t)htp_conn_response_data_counter(hstate->
conn) >
1559 (uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1561 (uint64_t)UINT_MAX) {
1562 uint32_t data_size =
1563 (uint32_t)((uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1587 SCLogDebug(
"http_state_memcnt %"PRIu64
", http_state_memuse %"PRIu64
"",
1588 htp_state_memcnt, htp_state_memuse);
1605 htp_config_destroy(cfglist.
cfg);
1606 while (nextrec != NULL) {
1608 nextrec = nextrec->
next;
1610 htp_config_destroy(htprec->
cfg);
1618 static int HTPCallbackRequestHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1621 htud->
tx_data.updated_ts =
true;
1623 return HTP_STATUS_OK;
1626 static int HTPCallbackResponseHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1629 htud->
tx_data.updated_tc =
true;
1631 return HTP_STATUS_OK;
1634 static void *HTPCallbackTxCreate(
bool request)
1642 tx_ud->
tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT;
1644 tx_ud->
tx_data.file_tx = STREAM_TOCLIENT;
1653 static int HTPCallbackRequestStart(
const htp_connp_t *connp, htp_tx_t *tx)
1655 HtpState *hstate = htp_connp_user_data(connp);
1656 if (hstate == NULL) {
1660 uint64_t consumed = hstate->
slice->offset + htp_connp_request_data_consumed(hstate->
connp);
1661 SCLogDebug(
"HTTP request start: data offset %" PRIu64
", in_data_counter %" PRIu64, consumed,
1662 (uint64_t)htp_conn_request_data_counter(hstate->
conn));
1678 tx_ud->
tx_data.updated_ts =
true;
1686 static int HTPCallbackResponseStart(
const htp_connp_t *connp, htp_tx_t *tx)
1688 HtpState *hstate = htp_connp_user_data(connp);
1689 if (hstate == NULL) {
1693 uint64_t consumed = hstate->
slice->offset + htp_connp_response_data_consumed(hstate->
connp);
1694 SCLogDebug(
"HTTP response start: data offset %" PRIu64
", out_data_counter %" PRIu64, consumed,
1695 (uint64_t)htp_conn_response_data_counter(hstate->
conn));
1710 tx_ud->
tx_data.updated_tc =
true;
1720 static int HTPCallbackRequestComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1728 HtpState *hstate = htp_connp_user_data(connp);
1729 if (hstate == NULL) {
1733 const uint64_t abs_right_edge =
1734 hstate->
slice->offset + htp_connp_request_data_consumed(hstate->
connp);
1742 SCLogDebug(
"HTTP request complete: data offset %" PRIu64
", request_size %" PRIu64,
1744 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1746 frame->
len = (int64_t)request_size;
1752 SCLogDebug(
"transaction_cnt %"PRIu64
", list_size %"PRIu64,
1757 HTPErrorCheckTxRequestFlags(hstate, tx);
1760 htud->
tx_data.updated_ts =
true;
1762 SCLogDebug(
"closing file that was being stored");
1765 if (abs_right_edge < (uint64_t)UINT32_MAX) {
1767 hstate->
f->
protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
1784 static int HTPCallbackResponseComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1788 HtpState *hstate = htp_connp_user_data(connp);
1789 if (hstate == NULL) {
1796 const uint64_t abs_right_edge =
1797 hstate->
slice->offset + htp_connp_response_data_consumed(hstate->
connp);
1804 SCLogDebug(
"HTTP response complete: data offset %" PRIu64
", response_size %" PRIu64,
1806 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1808 frame->
len = (int64_t)response_size;
1814 htud->
tx_data.updated_tc =
true;
1816 SCLogDebug(
"closing file that was being stored");
1826 if (htp_tx_request_method_number(tx) == HTP_METHOD_CONNECT) {
1829 if ((htp_tx_response_status_number(tx) >= 200) &&
1830 (htp_tx_response_status_number(tx) < 300) && (hstate->
transaction_cnt == 1)) {
1832 if (htp_tx_request_port_number(tx) != -1) {
1833 dp = (uint16_t)htp_tx_request_port_number(tx);
1847 static int HTPCallbackRequestLine(
const htp_connp_t *connp, htp_tx_t *tx)
1849 HtpState *hstate = htp_connp_user_data(connp);
1851 if (htp_tx_flags(tx)) {
1852 HTPErrorCheckTxRequestFlags(hstate, tx);
1854 return HTP_STATUS_OK;
1857 static int HTPCallbackRequestHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1860 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1861 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1862 return HTP_STATUS_OK;
1868 return HTP_STATUS_OK;
1871 tx_ud->
tx_data.updated_ts =
true;
1874 htp_tx_data_len(tx_data));
1877 if (tx && htp_tx_flags(tx)) {
1878 HtpState *hstate = htp_connp_user_data(connp);
1879 HTPErrorCheckTxRequestFlags(hstate, tx);
1881 return HTP_STATUS_OK;
1884 static int HTPCallbackResponseHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1887 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1888 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1889 return HTP_STATUS_OK;
1892 tx_ud->
tx_data.updated_tc =
true;
1896 return HTP_STATUS_OK;
1901 htp_tx_data_len(tx_data));
1904 return HTP_STATUS_OK;
1910 static void HTPConfigSetDefaultsPhase1(
HTPCfgRec *cfg_prec)
1912 htp_config_set_normalized_uri_include_all(cfg_prec->
cfg,
false);
1927 htp_config_register_request_header_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1928 htp_config_register_request_trailer_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1929 htp_config_register_response_header_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1930 htp_config_register_response_trailer_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1932 htp_config_register_request_trailer(cfg_prec->
cfg, HTPCallbackRequestHasTrailer);
1933 htp_config_register_response_trailer(cfg_prec->
cfg, HTPCallbackResponseHasTrailer);
1935 htp_config_register_request_body_data(cfg_prec->
cfg, HTPCallbackRequestBodyData);
1936 htp_config_register_response_body_data(cfg_prec->
cfg, HTPCallbackResponseBodyData);
1938 htp_config_register_tx_create(cfg_prec->
cfg, HTPCallbackTxCreate);
1939 htp_config_register_tx_destroy(cfg_prec->
cfg, HtpTxUserDataFree);
1941 htp_config_register_request_start(cfg_prec->
cfg, HTPCallbackRequestStart);
1942 htp_config_register_request_complete(cfg_prec->
cfg, HTPCallbackRequestComplete);
1944 htp_config_register_response_start(cfg_prec->
cfg, HTPCallbackResponseStart);
1945 htp_config_register_response_complete(cfg_prec->
cfg, HTPCallbackResponseComplete);
1947 htp_config_set_parse_request_cookies(cfg_prec->
cfg, 0);
1948 htp_config_set_allow_space_uri(cfg_prec->
cfg, 1);
1951 htp_config_set_plusspace_decode(cfg_prec->
cfg, 0);
1953 htp_config_set_request_decompression(cfg_prec->
cfg, 1);
1958 #define HTP_CONFIG_DEFAULT_MAX_TX_LIMIT 512
1960 #define HTP_CONFIG_DEFAULT_HEADERS_LIMIT 1024
1968 static int RandomGetWrap(
void)
1974 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
1976 return r % RAND_MAX;
1985 static void HTPConfigSetDefaultsPhase2(
const char *
name,
HTPCfgRec *cfg_prec)
1991 long int r = RandomGetWrap();
1993 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
1995 r = RandomGetWrap();
1997 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
1998 SCLogConfig(
"'%s' server has 'request-body-minimal-inspect-size' set to"
1999 " %u and 'request-body-inspect-window' set to %u after"
2003 r = RandomGetWrap();
2005 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2007 r = RandomGetWrap();
2009 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2011 SCLogConfig(
"'%s' server has 'response-body-minimal-inspect-size' set to"
2012 " %u and 'response-body-inspect-window' set to %u after"
2017 htp_config_register_request_line(cfg_prec->
cfg, HTPCallbackRequestLine);
2020 static void HTPConfigParseParameters(
HTPCfgRec *cfg_prec,
SCConfNode *s,
struct HTPConfigTree *tree)
2022 if (cfg_prec == NULL || s == NULL || tree == NULL)
2029 if (strcasecmp(
"address", p->
name) == 0) {
2035 if (strchr(pval->
val,
':') != NULL) {
2036 SCLogDebug(
"LIBHTP adding ipv6 server %s at %s: %p",
2040 SCLogWarning(
"LIBHTP failed to add ipv6 server %s, ignoring", pval->
val);
2043 SCLogDebug(
"LIBHTP adding ipv4 server %s at %s: %p",
2047 SCLogWarning(
"LIBHTP failed to add ipv4 server %s, ignoring", pval->
val);
2052 }
else if (strcasecmp(
"personality", p->
name) == 0) {
2054 int personality = HTPLookupPersonality(p->
val);
2058 if (personality >= 0) {
2061 if (htp_config_set_server_personality(cfg_prec->
cfg, personality) ==
2064 "personality \"%s\", ignoring",
2068 HTPLookupPersonalityString(personality));
2074 htp_config_set_convert_lowercase(cfg_prec->
cfg, 0);
2082 }
else if (strcasecmp(
"request-body-limit", p->
name) == 0 ||
2083 strcasecmp(
"request_body_limit", p->
name) == 0) {
2085 SCLogError(
"Error parsing request-body-limit "
2086 "from conf file - %s. Killing engine",
2091 }
else if (strcasecmp(
"response-body-limit", p->
name) == 0) {
2093 SCLogError(
"Error parsing response-body-limit "
2094 "from conf file - %s. Killing engine",
2099 }
else if (strcasecmp(
"request-body-minimal-inspect-size", p->
name) == 0) {
2101 SCLogError(
"Error parsing request-body-minimal-inspect-size "
2102 "from conf file - %s. Killing engine",
2107 }
else if (strcasecmp(
"request-body-inspect-window", p->
name) == 0) {
2109 SCLogError(
"Error parsing request-body-inspect-window "
2110 "from conf file - %s. Killing engine",
2115 }
else if (strcasecmp(
"double-decode-query", p->
name) == 0) {
2117 }
else if (strcasecmp(
"double-decode-path", p->
name) == 0) {
2119 }
else if (strcasecmp(
"response-body-minimal-inspect-size", p->
name) == 0) {
2121 SCLogError(
"Error parsing response-body-minimal-inspect-size "
2122 "from conf file - %s. Killing engine",
2127 }
else if (strcasecmp(
"response-body-inspect-window", p->
name) == 0) {
2129 SCLogError(
"Error parsing response-body-inspect-window "
2130 "from conf file - %s. Killing engine",
2135 }
else if (strcasecmp(
"response-body-decompress-layer-limit", p->
name) == 0) {
2138 SCLogError(
"Error parsing response-body-inspect-window "
2139 "from conf file - %s. Killing engine",
2143 htp_config_set_decompression_layer_limit(cfg_prec->
cfg, value);
2144 }
else if (strcasecmp(
"path-convert-backslash-separators", p->
name) == 0) {
2146 }
else if (strcasecmp(
"path-bestfit-replacement-char", p->
name) == 0) {
2147 if (strlen(p->
val) == 1) {
2148 htp_config_set_bestfit_replacement_byte(cfg_prec->
cfg, p->
val[0]);
2151 "for libhtp param path-bestfit-replacement-char");
2153 }
else if (strcasecmp(
"path-convert-lowercase", p->
name) == 0) {
2155 }
else if (strcasecmp(
"path-nul-encoded-terminates", p->
name) == 0) {
2157 }
else if (strcasecmp(
"path-nul-raw-terminates", p->
name) == 0) {
2159 }
else if (strcasecmp(
"path-separators-compress", p->
name) == 0) {
2161 }
else if (strcasecmp(
"path-separators-decode", p->
name) == 0) {
2163 }
else if (strcasecmp(
"path-u-encoding-decode", p->
name) == 0) {
2165 }
else if (strcasecmp(
"path-url-encoding-invalid-handling", p->
name) == 0) {
2166 enum htp_url_encoding_handling_t handling;
2167 if (strcasecmp(p->
val,
"preserve_percent") == 0) {
2168 handling = HTP_URL_ENCODING_HANDLING_PRESERVE_PERCENT;
2169 }
else if (strcasecmp(p->
val,
"remove_percent") == 0) {
2170 handling = HTP_URL_ENCODING_HANDLING_REMOVE_PERCENT;
2171 }
else if (strcasecmp(p->
val,
"decode_invalid") == 0) {
2172 handling = HTP_URL_ENCODING_HANDLING_PROCESS_INVALID;
2175 "for libhtp param path-url-encoding-invalid-handling");
2178 htp_config_set_url_encoding_invalid_handling(cfg_prec->
cfg, handling);
2179 }
else if (strcasecmp(
"path-utf8-convert-bestfit", p->
name) == 0) {
2181 }
else if (strcasecmp(
"uri-include-all", p->
name) == 0) {
2184 }
else if (strcasecmp(
"query-plusspace-decode", p->
name) == 0) {
2186 }
else if (strcasecmp(
"meta-field-limit", p->
name) == 0) {
2190 "from conf file - %s. Killing engine",
2196 "from conf file cannot be 0. Killing engine");
2199 htp_config_set_field_limit(cfg_prec->
cfg, (
size_t)limit);
2200 }
else if (strcasecmp(
"lzma-memlimit", p->
name) == 0) {
2203 FatalError(
"failed to parse 'lzma-memlimit' "
2204 "from conf file - %s.",
2209 "from conf file cannot be 0.");
2212 SCLogConfig(
"Setting HTTP LZMA memory limit to %"PRIu32
" bytes", limit);
2213 htp_config_set_lzma_memlimit(cfg_prec->
cfg, (
size_t)limit);
2214 }
else if (strcasecmp(
"lzma-enabled", p->
name) == 0) {
2216 htp_config_set_lzma_layers(cfg_prec->
cfg, 1);
2221 "from conf file - %s.",
2224 SCLogConfig(
"Setting HTTP LZMA decompression layers to %" PRIu32
"", (
int)limit);
2225 htp_config_set_lzma_layers(cfg_prec->
cfg, limit);
2227 }
else if (strcasecmp(
"compression-bomb-limit", p->
name) == 0) {
2230 FatalError(
"failed to parse 'compression-bomb-limit' "
2231 "from conf file - %s.",
2236 "from conf file cannot be 0.");
2239 SCLogConfig(
"Setting HTTP compression bomb limit to %"PRIu32
" bytes", limit);
2240 htp_config_set_compression_bomb_limit(cfg_prec->
cfg, (
size_t)limit);
2241 }
else if (strcasecmp(
"decompression-time-limit", p->
name) == 0) {
2245 FatalError(
"failed to parse 'decompression-time-limit' "
2246 "from conf file - %s.",
2249 SCLogConfig(
"Setting HTTP decompression time limit to %" PRIu32
" usec", limit);
2250 htp_config_set_compression_time_limit(cfg_prec->
cfg, limit);
2251 }
else if (strcasecmp(
"max-tx", p->
name) == 0) {
2255 "from conf file - %s.",
2259 SCLogConfig(
"Setting HTTP max-tx limit to %" PRIu32
" bytes", limit);
2260 htp_config_set_max_tx(cfg_prec->
cfg, limit);
2261 }
else if (strcasecmp(
"headers-limit", p->
name) == 0) {
2264 FatalError(
"failed to parse 'headers-limit' "
2265 "from conf file - %s.",
2268 SCLogConfig(
"Setting HTTP headers limit to %" PRIu32, limit);
2269 htp_config_set_number_headers_limit(cfg_prec->
cfg, limit);
2270 }
else if (strcasecmp(
"randomize-inspection-sizes", p->
name) == 0) {
2274 }
else if (strcasecmp(
"randomize-inspection-range", p->
name) == 0) {
2277 (
const char *)p->
val, 0, 100) < 0) {
2279 "-inspection-range setting from conf file - \"%s\"."
2280 " It should be a valid integer less than or equal to 100."
2286 }
else if (strcasecmp(
"http-body-inline", p->
name) == 0) {
2292 if (strcmp(
"auto", p->
val) != 0) {
2301 }
else if (strcasecmp(
"swf-decompression", p->
name) == 0) {
2305 if (strcasecmp(
"enabled", pval->
name) == 0) {
2313 }
else if (strcasecmp(
"type", pval->
name) == 0) {
2314 if (strcasecmp(
"no", pval->
val) == 0) {
2316 }
else if (strcasecmp(
"deflate", pval->
val) == 0) {
2318 }
else if (strcasecmp(
"lzma", pval->
val) == 0) {
2320 }
else if (strcasecmp(
"both", pval->
val) == 0) {
2324 "swf-decompression.type: %s - "
2329 }
else if (strcasecmp(
"compress-depth", pval->
name) == 0) {
2331 SCLogError(
"Error parsing swf-decompression.compression-depth "
2332 "from conf file - %s. Killing engine",
2336 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2338 SCLogError(
"Error parsing swf-decompression.decompression-depth "
2339 "from conf file - %s. Killing engine",
2349 "default config: %s",
2359 cfglist.
next = NULL;
2366 cfglist.
cfg = htp_config_create();
2367 if (NULL == cfglist.
cfg) {
2368 FatalError(
"Failed to create HTP default config");
2371 HTPConfigSetDefaultsPhase1(&cfglist);
2372 if (
SCConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2373 HTPConfigParseParameters(&cfglist,
SCConfGetNode(
"libhtp.default-config"), &cfgtree);
2375 HTPConfigParseParameters(&cfglist,
2376 SCConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), &cfgtree);
2378 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2384 if (server_config == NULL) {
2386 if (server_config == NULL) {
2387 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2391 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2410 cfglist.
next = htprec;
2413 cfglist.
next->
cfg = htp_config_create();
2414 if (NULL == cfglist.
next->
cfg) {
2415 FatalError(
"Failed to create HTP server config");
2418 HTPConfigSetDefaultsPhase1(htprec);
2419 HTPConfigParseParameters(htprec, s, &cfgtree);
2420 HTPConfigSetDefaultsPhase2(s->
name, htprec);
2430 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
2444 htp_tx_t *tx = (htp_tx_t *)txv;
2446 if (direction & STREAM_TOCLIENT) {
2454 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
2456 if (direction & STREAM_TOSERVER)
2457 return htp_tx_request_progress((htp_tx_t *)tx);
2459 return htp_tx_response_progress((htp_tx_t *)tx);
2462 static uint64_t HTPStateGetTxCnt(
void *alstate)
2466 if (http_state != NULL && http_state->
connp != NULL) {
2467 const int64_t size = htp_connp_tx_size(http_state->
connp);
2471 return (uint64_t)size;
2477 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
2481 if (http_state != NULL && http_state->
connp != NULL)
2482 return (
void *)htp_connp_tx(http_state->
connp, tx_id);
2491 uint64_t size = HTPStateGetTxCnt(alstate);
2494 while (state->
un.
u64 < size) {
2495 htp_tx_t *tx = htp_connp_tx_index(http_state->
connp, state->
un.
u64);
2499 uint64_t tx_id = htp_tx_index(tx);
2500 if (tx_id < min_tx_id) {
2507 .has_next = state->
un.
u64 < size,
2519 if (http_state != NULL && http_state->
connp != NULL) {
2520 size_t txid = htp_connp_tx_size(http_state->
connp);
2522 return (
void *)htp_connp_tx(http_state->
connp, txid - 1);
2528 static int HTPStateGetEventInfo(
2538 static int HTPStateGetEventInfoById(
2542 if (*event_name == NULL) {
2544 "http's enum map table.",
2557 htp_tx_t *tx = (htp_tx_t *)vtx;
2568 static int HTPRegisterPatternsForProtocolDetection(
void)
2570 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
2571 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
2572 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
2573 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
2574 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
2575 const char *spacings[] = {
"|20|",
"|09|", NULL };
2576 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
2581 int register_result;
2582 char method_buffer[32] =
"";
2585 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
2586 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
2589 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
2596 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
2597 if (register_result < 0) {
2604 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
2606 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
2608 if (register_result < 0) {
2624 const char *proto_name =
"http";
2629 if (HTPRegisterPatternsForProtocolDetection() < 0)
2632 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
2647 ALPROTO_HTTP1, HTP_REQUEST_PROGRESS_COMPLETE, HTP_RESPONSE_PROGRESS_COMPLETE);
2659 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
2661 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
2667 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
2670 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
2673 IPPROTO_TCP,
ALPROTO_HTTP1, HtpStateGetStateIdByName, HtpStateGetStateNameById);
2677 SCLogInfo(
"Parser disabled for %s protocol. Protocol detection still on.", proto_name);
2693 cfglist_backup = cfglist;
2698 cfglist = cfglist_backup;
2703 static int HTPParserTest01(
void)
2705 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2707 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2710 memset(&ssn, 0,
sizeof(ssn));
2718 f->
proto = IPPROTO_TCP;
2724 for (u = 0; u < httplen1; u++) {
2728 flags = STREAM_TOSERVER|STREAM_START;
2729 else if (u == (httplen1 - 1))
2730 flags = STREAM_TOSERVER|STREAM_EOF;
2732 flags = STREAM_TOSERVER;
2741 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2744 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2747 FAIL_IF(bstr_cmp_c(htp_header_value(h),
"Victor/1.0"));
2748 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2749 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2758 static int HTPParserTest01b(
void)
2760 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2762 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2765 memset(&ssn, 0,
sizeof(ssn));
2773 f->
proto = IPPROTO_TCP;
2778 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
2785 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2788 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2791 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2792 FAIL_IF(strcmp(v,
"Victor/1.0"));
2794 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2795 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2804 static int HTPParserTest01c(
void)
2806 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2808 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2811 memset(&ssn, 0,
sizeof(ssn));
2819 f->
proto = IPPROTO_TCP;
2825 for (u = 0; u < httplen1; u++) {
2829 flags = STREAM_TOSERVER|STREAM_START;
2830 else if (u == (httplen1 - 1))
2831 flags = STREAM_TOSERVER|STREAM_EOF;
2833 flags = STREAM_TOSERVER;
2842 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2845 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2848 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2849 FAIL_IF(strcmp(v,
"Victor/1.0"));
2851 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2852 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2862 static int HTPParserTest01a(
void)
2865 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2867 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2872 memset(&ssn, 0,
sizeof(ssn));
2874 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2877 f->
proto = IPPROTO_TCP;
2883 for (u = 0; u < httplen1; u++) {
2887 flags = STREAM_TOSERVER|STREAM_START;
2888 else if (u == (httplen1 - 1))
2889 flags = STREAM_TOSERVER|STREAM_EOF;
2891 flags = STREAM_TOSERVER;
2900 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2903 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2906 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2907 FAIL_IF(strcmp(v,
"Victor/1.0"));
2909 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2910 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2919 static int HTPParserTest02(
void)
2922 uint8_t httpbuf1[] =
"POST";
2923 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2928 memset(&ssn, 0,
sizeof(ssn));
2930 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2933 f->
proto = IPPROTO_TCP;
2939 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
2945 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
2947 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2951 char *method = bstr_util_strdup_to_c(htp_tx_request_method(tx));
2954 FAIL_IF(strcmp(method,
"POST") != 0);
2965 static int HTPParserTest03(
void)
2968 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
2969 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2974 memset(&ssn, 0,
sizeof(ssn));
2976 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2979 f->
proto = IPPROTO_TCP;
2985 for (u = 0; u < httplen1; u++) {
2988 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
2989 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
2990 else flags = STREAM_TOSERVER;
2998 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3001 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3003 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3004 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
3014 static int HTPParserTest04(
void)
3018 uint8_t httpbuf1[] =
"World!\r\n";
3019 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3023 memset(&ssn, 0,
sizeof(ssn));
3025 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3028 f->
proto = IPPROTO_TCP;
3034 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3040 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3042 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3044 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3045 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V0_9);
3055 static int HTPParserTest05(
void)
3057 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3058 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3059 uint8_t httpbuf2[] =
"Post D";
3060 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3061 uint8_t httpbuf3[] =
"ata is c0oL!";
3062 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3064 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3065 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3066 uint8_t httpbuf5[] =
"post R";
3067 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3068 uint8_t httpbuf6[] =
"esults are tha bomb!";
3069 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3072 memset(&ssn, 0,
sizeof(ssn));
3080 f->
proto = IPPROTO_TCP;
3110 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3112 FAIL_IF_NOT(htp_tx_request_method_number(tx) == HTP_METHOD_POST);
3113 FAIL_IF_NOT(htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_V1_0);
3115 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3118 FAIL_IF_NOT(htp_tx_response_status_number(tx) == 200);
3128 static int HTPParserTest06(
void)
3130 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3131 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3132 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3133 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3134 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3136 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3137 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3138 "FrontPage/5.0.2.2510\r\n"
3139 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3141 "Content-Type: text/html\r\n\r\n"
3143 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3144 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3145 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3146 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3147 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3148 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3149 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3150 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3151 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3152 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3153 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3154 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3155 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3156 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3157 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3158 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3159 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3160 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3161 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3162 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3163 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3164 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3165 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3166 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3167 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3168 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3169 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3170 "aHA=\r\n0\r\n\r\n";
3171 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3177 memset(&ssn, 0,
sizeof(ssn));
3182 f->
proto = IPPROTO_TCP;
3197 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3200 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
3201 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3203 FAIL_IF(htp_tx_response_status_number(tx) != 200);
3204 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3206 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3217 static int HTPParserTest07(
void)
3220 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3221 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3226 memset(&ssn, 0,
sizeof(ssn));
3228 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3231 f->
proto = IPPROTO_TCP;
3237 for (u = 0; u < httplen1; u++) {
3241 flags = STREAM_TOSERVER|STREAM_START;
3242 else if (u == (httplen1 - 1))
3243 flags = STREAM_TOSERVER|STREAM_EOF;
3245 flags = STREAM_TOSERVER;
3254 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3255 size_t reflen =
sizeof(ref) - 1;
3257 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3259 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3261 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3263 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref, bstr_len(request_uri_normalized)) != 0);
3275 static int HTPParserTest08(
void)
3278 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3279 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3300 memset(&ssn, 0,
sizeof(ssn));
3302 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3305 f->
proto = IPPROTO_TCP;
3310 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3318 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3320 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3322 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3336 static int HTPParserTest09(
void)
3339 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3340 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3350 personality: Apache_2_2\n\
3362 memset(&ssn, 0,
sizeof(ssn));
3364 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3367 f->
proto = IPPROTO_TCP;
3372 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3380 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3382 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3384 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3398 static int HTPParserTest10(
void)
3402 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3403 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3408 memset(&ssn, 0,
sizeof(ssn));
3410 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3413 f->
proto = IPPROTO_TCP;
3419 for (u = 0; u < httplen1; u++) {
3423 flags = STREAM_TOSERVER|STREAM_START;
3424 else if (u == (httplen1 - 1))
3425 flags = STREAM_TOSERVER|STREAM_EOF;
3427 flags = STREAM_TOSERVER;
3436 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3437 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3440 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3444 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3446 FAIL_IF(strcmp(value,
"www.google.com") != 0);
3458 static int HTPParserTest11(
void)
3461 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3462 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3467 memset(&ssn, 0,
sizeof(ssn));
3469 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3472 f->
proto = IPPROTO_TCP;
3478 for (u = 0; u < httplen1; u++) {
3482 flags = STREAM_TOSERVER|STREAM_START;
3483 else if (u == (httplen1 - 1))
3484 flags = STREAM_TOSERVER|STREAM_EOF;
3486 flags = STREAM_TOSERVER;
3495 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3497 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3500 FAIL_IF(bstr_len(request_uri_normalized) != 4);
3501 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3502 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'%');
3503 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'0');
3504 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'0');
3514 static int HTPParserTest12(
void)
3517 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3518 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3523 memset(&ssn, 0,
sizeof(ssn));
3525 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3528 f->
proto = IPPROTO_TCP;
3534 for (u = 0; u < httplen1; u++) {
3538 flags = STREAM_TOSERVER|STREAM_START;
3539 else if (u == (httplen1 - 1))
3540 flags = STREAM_TOSERVER|STREAM_EOF;
3542 flags = STREAM_TOSERVER;
3551 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3553 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3556 FAIL_IF(bstr_len(request_uri_normalized) != 7);
3557 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3558 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'?');
3559 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'a');
3560 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'=');
3561 FAIL_IF(bstr_ptr(request_uri_normalized)[4] !=
'%');
3562 FAIL_IF(bstr_ptr(request_uri_normalized)[5] !=
'0');
3563 FAIL_IF(bstr_ptr(request_uri_normalized)[6] !=
'0');
3573 static int HTPParserTest13(
void)
3576 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3577 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3582 memset(&ssn, 0,
sizeof(ssn));
3584 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3587 f->
proto = IPPROTO_TCP;
3593 for (u = 0; u < httplen1; u++) {
3597 flags = STREAM_TOSERVER|STREAM_START;
3598 else if (u == (httplen1 - 1))
3599 flags = STREAM_TOSERVER|STREAM_EOF;
3601 flags = STREAM_TOSERVER;
3609 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3610 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3613 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3617 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3619 FAIL_IF(strcmp(value,
"www.google.com\rName: Value") != 0);
3631 static int HTPParserConfigTest01(
void)
3644 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3645 personality: Tomcat_6_0\n\
3650 - 192.168.10.0/24\n\
3651 personality: IIS_7_0\n\
3660 outputs =
SCConfGetNode(
"libhtp.default-config.personality");
3671 FAIL_IF(strcmp(node->
name,
"apache-tomcat") != 0);
3678 FAIL_IF(strcmp(node2->
val,
"Tomcat_6_0") != 0);
3688 FAIL_IF(strcmp(n->
val,
"192.168.1.0/24") != 0);
3728 FAIL_IF(strcmp(n->
val,
"192.168.0.0/24") != 0);
3732 FAIL_IF(strcmp(n->
val,
"192.168.10.0/24") != 0);
3747 static int HTPParserConfigTest02(
void)
3760 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3761 personality: Tomcat_6_0\n\
3766 - 192.168.10.0/24\n\
3767 personality: IIS_7_0\n\
3779 htp_cfg_t *htp = cfglist.
cfg;
3782 void *user_data = NULL;
3784 addr =
"192.168.10.42";
3785 FAIL_IF(inet_pton(AF_INET, addr, buf) != 1);
3789 htp = htp_cfg_rec->
cfg;
3795 FAIL_IF(inet_pton(AF_INET6, addr, buf) != 1);
3798 htp_cfg_rec = user_data;
3799 htp = htp_cfg_rec->
cfg;
3812 static int HTPParserConfigTest03(
void)
3815 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3817 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3833 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3834 personality: Tomcat_6_0\n\
3839 - 192.168.10.0/24\n\
3840 personality: IIS_7_0\n\
3851 const char *addr =
"192.168.10.42";
3853 memset(&ssn, 0,
sizeof(ssn));
3858 f->
proto = IPPROTO_TCP;
3861 htp_cfg_t *htp = cfglist.
cfg;
3864 void *user_data = NULL;
3869 htp = htp_cfg_rec->
cfg;
3876 for (u = 0; u < httplen1; u++) {
3879 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3880 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3881 else flags = STREAM_TOSERVER;
3890 FAIL_IF(HTPStateGetTxCnt(htp_state) != 2);
3892 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3894 tx = HTPStateGetTx(htp_state, 1);
3913 static int HTPParserDecodingTest01(
void)
3915 uint8_t httpbuf1[] =
3916 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3917 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3918 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
3919 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3930 personality: Apache_2\n\
3938 const char *addr =
"4.3.2.1";
3939 memset(&ssn, 0,
sizeof(ssn));
3944 f->
proto = IPPROTO_TCP;
3949 for (uint32_t u = 0; u < httplen1; u++) {
3951 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3952 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3953 else flags = STREAM_TOSERVER;
3962 uint8_t ref1[] =
"/abc%2fdef";
3963 size_t reflen =
sizeof(ref1) - 1;
3965 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3969 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3972 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3973 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
3975 uint8_t ref2[] =
"/abc/def?ghi/jkl";
3976 reflen =
sizeof(ref2) - 1;
3978 tx = HTPStateGetTx(htp_state, 1);
3982 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3985 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3986 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
3988 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
3989 reflen =
sizeof(ref3) - 1;
3990 tx = HTPStateGetTx(htp_state, 2);
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), ref3, bstr_len(request_uri_normalized)) != 0);
4010 static int HTPParserDecodingTest01a(
void)
4012 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4013 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4014 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4015 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4026 personality: Apache_2\n\
4034 const char *addr =
"4.3.2.1";
4035 memset(&ssn, 0,
sizeof(ssn));
4040 f->
proto = IPPROTO_TCP;
4046 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4052 uint8_t ref1[] =
"/abc%2fdef";
4053 size_t reflen =
sizeof(ref1) - 1;
4055 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4059 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4062 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4063 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4065 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4066 reflen =
sizeof(ref2) - 1;
4068 tx = HTPStateGetTx(htp_state, 1);
4071 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4074 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4076 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4078 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4079 reflen =
sizeof(ref3) - 1;
4080 tx = HTPStateGetTx(htp_state, 2);
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), ref3, bstr_len(request_uri_normalized)) != 0);
4106 static int HTPParserDecodingTest02(
void)
4109 uint8_t httpbuf1[] =
4110 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4111 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4112 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4113 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4125 double-decode-path: no\n\
4126 double-decode-query: no\n\
4134 const char *addr =
"4.3.2.1";
4135 memset(&ssn, 0,
sizeof(ssn));
4140 f->
proto = IPPROTO_TCP;
4146 for (u = 0; u < httplen1; u++) {
4149 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4150 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4151 else flags = STREAM_TOSERVER;
4160 uint8_t ref1[] =
"/abc/def";
4161 size_t reflen =
sizeof(ref1) - 1;
4163 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4165 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4167 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4168 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4170 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4171 reflen =
sizeof(ref2) - 1;
4173 tx = HTPStateGetTx(htp_state, 1);
4175 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4177 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4179 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4181 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4182 reflen =
sizeof(ref3) - 1;
4183 tx = HTPStateGetTx(htp_state, 2);
4185 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4187 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4189 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4206 static int HTPParserDecodingTest03(
void)
4209 uint8_t httpbuf1[] =
4210 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4211 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4212 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4224 double-decode-path: yes\n\
4225 double-decode-query: yes\n\
4233 const char *addr =
"4.3.2.1";
4234 memset(&ssn, 0,
sizeof(ssn));
4239 f->
proto = IPPROTO_TCP;
4245 for (u = 0; u < httplen1; u++) {
4248 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4249 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4250 else flags = STREAM_TOSERVER;
4259 uint8_t ref1[] =
"/abc/def";
4260 size_t reflen =
sizeof(ref1) - 1;
4262 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4264 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4266 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4268 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4270 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4271 reflen =
sizeof(ref2) - 1;
4273 tx = HTPStateGetTx(htp_state, 1);
4275 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4277 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4279 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4293 static int HTPParserDecodingTest04(
void)
4296 uint8_t httpbuf1[] =
4297 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4298 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4310 double-decode-path: yes\n\
4311 double-decode-query: yes\n\
4319 const char *addr =
"4.3.2.1";
4320 memset(&ssn, 0,
sizeof(ssn));
4325 f->
proto = IPPROTO_TCP;
4331 for (u = 0; u < httplen1; u++) {
4334 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4335 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4336 else flags = STREAM_TOSERVER;
4345 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
4346 size_t reflen =
sizeof(ref1) - 1;
4348 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4350 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4352 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4354 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4368 static int HTPParserDecodingTest05(
void)
4371 uint8_t httpbuf1[] =
4372 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4373 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4385 double-decode-path: yes\n\
4386 double-decode-query: yes\n\
4394 const char *addr =
"4.3.2.1";
4395 memset(&ssn, 0,
sizeof(ssn));
4400 f->
proto = IPPROTO_TCP;
4406 for (u = 0; u < httplen1; u++) {
4409 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4410 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4411 else flags = STREAM_TOSERVER;
4420 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
4421 size_t reflen =
sizeof(ref1) - 1;
4423 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4425 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4427 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4429 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4443 static int HTPParserDecodingTest06(
void)
4446 uint8_t httpbuf1[] =
4447 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4448 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4460 double-decode-path: yes\n\
4461 double-decode-query: yes\n\
4469 const char *addr =
"4.3.2.1";
4470 memset(&ssn, 0,
sizeof(ssn));
4475 f->
proto = IPPROTO_TCP;
4481 for (u = 0; u < httplen1; u++) {
4484 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4485 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4486 else flags = STREAM_TOSERVER;
4495 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
4496 size_t reflen =
sizeof(ref1) - 1;
4498 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4500 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4502 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4504 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4518 static int HTPParserDecodingTest07(
void)
4521 uint8_t httpbuf1[] =
4522 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4523 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4535 double-decode-path: yes\n\
4536 double-decode-query: yes\n\
4537 query-plusspace-decode: yes\n\
4545 const char *addr =
"4.3.2.1";
4546 memset(&ssn, 0,
sizeof(ssn));
4551 f->
proto = IPPROTO_TCP;
4557 for (u = 0; u < httplen1; u++) {
4560 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4561 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4562 else flags = STREAM_TOSERVER;
4571 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
4572 size_t reflen =
sizeof(ref1) - 1;
4574 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4576 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4578 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4580 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4594 static int HTPParserDecodingTest08(
void)
4597 uint8_t httpbuf1[] =
4598 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4599 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4618 const char *addr =
"4.3.2.1";
4619 memset(&ssn, 0,
sizeof(ssn));
4624 f->
proto = IPPROTO_TCP;
4630 for (u = 0; u < httplen1; u++) {
4633 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4634 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4635 else flags = STREAM_TOSERVER;
4644 uint8_t ref1[] =
"/blah/";
4645 size_t reflen =
sizeof(ref1) - 1;
4647 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4649 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4651 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4653 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4667 static int HTPParserDecodingTest09(
void)
4670 uint8_t httpbuf1[] =
4671 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4672 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4684 uri-include-all: true\n\
4692 const char *addr =
"4.3.2.1";
4693 memset(&ssn, 0,
sizeof(ssn));
4698 f->
proto = IPPROTO_TCP;
4704 for (u = 0; u < httplen1; u++) {
4707 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4708 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4709 else flags = STREAM_TOSERVER;
4718 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
4719 size_t reflen =
sizeof(ref1) - 1;
4721 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4723 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4725 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4727 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4740 static int HTPBodyReassemblyTest01(
void)
4745 memset(&hstate, 0x00,
sizeof(hstate));
4747 memset(&flow, 0x00,
sizeof(flow));
4749 htp_cfg_t *cfg = htp_config_create();
4751 htp_connp_t *connp = htp_connp_create(cfg);
4753 const htp_tx_t *tx = htp_connp_get_request_tx(connp);
4759 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
4760 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";
4767 const uint8_t *chunks_buffer = NULL;
4768 uint32_t chunks_buffer_len = 0;
4770 HtpRequestBodyReassemble(htud, &chunks_buffer, &chunks_buffer_len);
4773 printf(
"REASSCHUNK START: \n");
4775 printf(
"REASSCHUNK END: \n");
4778 htud->
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
4779 strlen(
"multipart/form-data; boundary=toto"));
4782 HtpRequestBodyHandleMultipart(&hstate, htud, &tx, chunks_buffer, chunks_buffer_len,
false);
4788 htp_connp_destroy_all(connp);
4789 HtpTxUserDataFree(htud);
4791 htp_config_destroy(cfg);
4796 static int HTPSegvTest01(
void)
4799 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";
4800 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4808 double-decode-path: no\n\
4809 double-decode-query: no\n\
4810 request-body-limit: 0\n\
4811 response-body-limit: 0\n\
4824 memset(&ssn, 0,
sizeof(ssn));
4826 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4829 f->
proto = IPPROTO_TCP;
4834 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
4838 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
4859 static int HTPParserTest14(
void)
4870 double-decode-path: no\n\
4871 double-decode-query: no\n\
4872 request-body-limit: 0\n\
4873 response-body-limit: 0\n\
4878 memset(&ssn, 0,
sizeof(ssn));
4888 memset(httpbuf, 0x00,
len);
4891 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4892 "Host: myhost.lan\r\n"
4893 "Connection: keep-alive\r\n"
4895 "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"
4896 "Referer: http://blah.lan/\r\n"
4897 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
4899 size_t o = strlen(httpbuf);
4900 for ( ; o <
len - 4; o++) {
4903 httpbuf[
len - 4] =
'\r';
4904 httpbuf[
len - 3] =
'\n';
4905 httpbuf[
len - 2] =
'\r';
4906 httpbuf[
len - 1] =
'\n';
4912 f->
proto = IPPROTO_TCP;
4917 for (u = 0; u <
len; u++) {
4920 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4921 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4922 else flags = STREAM_TOSERVER;
4930 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4932 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
4933 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
4940 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG);
4955 static int HTPParserTest15(
void)
4958 char *httpbuf = NULL;
4969 double-decode-path: no\n\
4970 double-decode-query: no\n\
4971 request-body-limit: 0\n\
4972 response-body-limit: 0\n\
4973 meta-field-limit: 20000\n\
4977 memset(&ssn, 0,
sizeof(ssn));
4988 memset(httpbuf, 0x00,
len);
4991 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4992 "Host: myhost.lan\r\n"
4993 "Connection: keep-alive\r\n"
4995 "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"
4996 "Referer: http://blah.lan/\r\n"
4997 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
4999 size_t o = strlen(httpbuf);
5000 for ( ; o <
len - 4; o++) {
5003 httpbuf[
len - 4] =
'\r';
5004 httpbuf[
len - 3] =
'\n';
5005 httpbuf[
len - 2] =
'\r';
5006 httpbuf[
len - 1] =
'\n';
5008 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5011 f->
proto = IPPROTO_TCP;
5017 for (u = 0; u <
len; u++) {
5020 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5021 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5022 else flags = STREAM_TOSERVER;
5031 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5033 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5034 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5053 static int HTPParserTest16(
void)
5060 memset(&ssn, 0,
sizeof(ssn));
5062 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5063 "Host: myhost.lan\r\n"
5064 "Connection: keep-alive\r\n"
5066 "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"
5067 "Referer: http://blah.lan/\r\n"
5068 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5069 "Cookie: blah\r\n\r\n";
5070 size_t len =
sizeof(httpbuf) - 1;
5072 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5075 f->
proto = IPPROTO_TCP;
5080 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5088 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5090 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5091 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5093 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5100 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT);
5101 FAIL_IF(decoder_events->
events[1] != HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT);
5112 static int HTPParserTest20(
void)
5115 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5116 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5117 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5118 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5119 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
5120 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5121 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5122 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5128 memset(&ssn, 0,
sizeof(ssn));
5130 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5133 f->
proto = IPPROTO_TCP;
5152 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5154 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5157 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5158 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5160 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5161 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5171 static int HTPParserTest21(
void)
5174 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5175 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5176 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5177 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5178 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
5179 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5180 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5181 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5187 memset(&ssn, 0,
sizeof(ssn));
5189 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5192 f->
proto = IPPROTO_TCP;
5211 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5213 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5216 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5217 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5219 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5220 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5230 static int HTPParserTest22(
void)
5233 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5234 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5235 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5236 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5237 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
5238 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5239 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5245 memset(&ssn, 0,
sizeof(ssn));
5247 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5250 f->
proto = IPPROTO_TCP;
5265 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5267 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5270 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5271 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5273 FAIL_IF(htp_tx_response_status_number(tx) != -0);
5274 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5284 static int HTPParserTest23(
void)
5287 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5288 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5289 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5290 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5291 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
5292 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5293 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5299 memset(&ssn, 0,
sizeof(ssn));
5301 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5304 f->
proto = IPPROTO_TCP;
5319 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5321 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5324 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5325 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5327 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5328 FAIL_IF(htp_tx_response_protocol_number(tx) != -2);
5339 static int HTPParserTest24(
void)
5342 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5343 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5344 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5345 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5346 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
5347 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5348 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5354 memset(&ssn, 0,
sizeof(ssn));
5356 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5359 f->
proto = IPPROTO_TCP;
5374 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5376 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5379 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5380 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5382 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5383 FAIL_IF(htp_tx_response_protocol_number(tx) != HTP_PROTOCOL_V1_0);
5393 static int HTPParserTest25(
void)
5400 memset(&ssn, 0,
sizeof(ssn));
5405 f->
proto = IPPROTO_TCP;
5409 const char *
str =
"GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
5411 (uint8_t *)
str, strlen(
str));
5435 str =
"HTTP 1.1 200 OK\r\nServer: Suricata/1.0\r\nContent-Length: 8\r\n\r\nSuricata";
5437 (uint8_t *)
str, strlen(
str));
5471 (uint8_t *)
str, strlen(
str));
5482 (uint8_t *)
str, strlen(
str));
5503 static int HTPParserTest26(
void)
5512 request-body-limit: 1\n\
5513 response-body-limit: 1\n\
5527 uint8_t httpbuf1[] =
"GET /alice.txt HTTP/1.1\r\n\r\n";
5528 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5529 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\n"
5530 "Content-Type: text/plain\r\n"
5531 "Content-Length: 228\r\n\r\n"
5532 "Alice was beginning to get very tired of sitting by her sister on the bank."
5533 "Alice was beginning to get very tired of sitting by her sister on the bank.";
5534 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5535 uint8_t httpbuf3[] =
"Alice was beginning to get very tired of sitting by her sister on the bank.\r\n\r\n";
5536 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5542 memset(&th_v, 0,
sizeof(th_v));
5544 memset(&f, 0,
sizeof(f));
5545 memset(&ssn, 0,
sizeof(ssn));
5552 f.
proto = IPPROTO_TCP;
5573 "(filestore; sid:1; rev:1;)");
5642 static int HTPParserTest27(
void)
5645 memset(&cfg, 0,
sizeof(cfg));
5649 uint32_t
len = 1000;
5674 static void HTPParserRegisterTests(
void)
5696 UtRegisterTest(
"HTPParserDecodingTest01", HTPParserDecodingTest01);
5697 UtRegisterTest(
"HTPParserDecodingTest01a", HTPParserDecodingTest01a);
5698 UtRegisterTest(
"HTPParserDecodingTest02", HTPParserDecodingTest02);
5699 UtRegisterTest(
"HTPParserDecodingTest03", HTPParserDecodingTest03);
5700 UtRegisterTest(
"HTPParserDecodingTest04", HTPParserDecodingTest04);
5701 UtRegisterTest(
"HTPParserDecodingTest05", HTPParserDecodingTest05);
5702 UtRegisterTest(
"HTPParserDecodingTest06", HTPParserDecodingTest06);
5703 UtRegisterTest(
"HTPParserDecodingTest07", HTPParserDecodingTest07);
5704 UtRegisterTest(
"HTPParserDecodingTest08", HTPParserDecodingTest08);
5705 UtRegisterTest(
"HTPParserDecodingTest09", HTPParserDecodingTest09);
5707 UtRegisterTest(
"HTPBodyReassemblyTest01", HTPBodyReassemblyTest01);