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);
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)
487 SCAppLayerTxDataCleanup(&htud->
tx_data);
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)
649 htp_log_t *log = htp_conn_next_log(s->
conn);
650 while (log != NULL) {
651 char *msg = htp_log_message(log);
654 log = htp_conn_next_log(s->
conn);
660 htp_log_code_t
id = htp_log_code(log);
661 if (
id != HTP_LOG_CODE_UNKNOWN &&
id != HTP_LOG_CODE_ERROR) {
662 HTPSetEvent(s, NULL, dir, (uint8_t)
id);
664 htp_free_cstring(msg);
674 log = htp_conn_next_log(s->
conn);
679 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s,
const htp_tx_t *tx)
682 BUG_ON(s == NULL || tx == NULL);
684 if (htp_tx_flags(tx) & (HTP_FLAGS_REQUEST_INVALID_T_E | HTP_FLAGS_REQUEST_INVALID_C_L |
685 HTP_FLAGS_HOST_MISSING | HTP_FLAGS_HOST_AMBIGUOUS |
686 HTP_FLAGS_HOSTU_INVALID | HTP_FLAGS_HOSTH_INVALID)) {
689 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_T_E)
690 HTPSetEvent(s, htud, STREAM_TOSERVER,
691 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST);
692 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_C_L)
694 s, htud, STREAM_TOSERVER, HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST);
695 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_MISSING)
696 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_MISSING_HOST_HEADER);
697 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_AMBIGUOUS)
698 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HOST_HEADER_AMBIGUOUS);
699 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTU_INVALID)
700 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_URI_HOST_INVALID);
701 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTH_INVALID)
702 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HEADER_HOST_INVALID);
704 if (htp_tx_request_auth_type(tx) == HTP_AUTH_TYPE_UNRECOGNIZED) {
706 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_AUTH_UNRECOGNIZED);
708 if (htp_tx_is_protocol_0_9(tx) && htp_tx_request_method_number(tx) == HTP_METHOD_UNKNOWN &&
709 (htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_INVALID ||
710 htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_UNKNOWN)) {
712 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_REQUEST_LINE_INVALID);
722 htp_cfg_t *htp = cfglist.
cfg;
723 void *user_data = NULL;
739 if (user_data != NULL) {
740 htp_cfg_rec = user_data;
741 htp = htp_cfg_rec->
cfg;
744 SCLogDebug(
"Using default HTP config: %p", htp);
748 #ifdef DEBUG_VALIDATION
755 hstate->
connp = htp_connp_create(htp);
756 if (hstate->
connp == NULL) {
760 hstate->
conn = (htp_conn_t *)htp_connp_connection(hstate->
connp);
762 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
763 hstate->
cfg = htp_cfg_rec;
768 htp_connp_open(hstate->
connp, NULL, f->
sp, NULL, f->
dp, &
tv);
800 if (NULL == hstate->
conn) {
801 if (Setup(f, hstate) != 0) {
806 hstate->
slice = &stream_slice;
808 const uint8_t *input = StreamSliceGetData(&stream_slice);
809 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
814 const int r = htp_connp_request_data(hstate->
connp, &
ts, input, input_len);
816 case HTP_STREAM_STATE_ERROR:
822 HTPHandleError(hstate, STREAM_TOSERVER);
828 htp_connp_request_close(hstate->
connp, &
ts);
830 SCLogDebug(
"stream eof encountered, closing htp handle for ts");
834 hstate->
slice = NULL;
862 const uint8_t *input = StreamSliceGetData(&stream_slice);
863 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
869 if (NULL == hstate->
conn) {
870 if (Setup(f, hstate) != 0) {
875 hstate->
slice = &stream_slice;
878 const htp_tx_t *tx = NULL;
879 uint32_t consumed = 0;
881 const int r = htp_connp_response_data(hstate->
connp, &
ts, input, input_len);
883 case HTP_STREAM_STATE_ERROR:
886 case HTP_STREAM_STATE_TUNNEL:
887 tx = htp_connp_get_response_tx(hstate->
connp);
888 if (tx != NULL && htp_tx_response_status_number(tx) == 101) {
889 const htp_header_t *h = htp_tx_response_header(tx,
"Upgrade");
894 if (htp_tx_request_port_number(tx) != -1) {
895 dp = (uint16_t)htp_tx_request_port_number(tx);
897 consumed = (uint32_t)htp_connp_response_data_consumed(hstate->
connp);
898 if (bstr_cmp_c(htp_header_value(h),
"h2c") == 0) {
903 hstate->
slice = NULL;
905 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
910 if (consumed > 0 && consumed < input_len) {
914 }
else if (bstr_cmp_c_nocase(htp_header_value(h),
"WebSocket")) {
919 hstate->
slice = NULL;
921 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
926 if (consumed > 0 && consumed < input_len) {
936 HTPHandleError(hstate, STREAM_TOCLIENT);
942 htp_connp_close(hstate->
connp, &
ts);
947 hstate->
slice = NULL;
958 static int HTTPParseContentDispositionHeader(
const uint8_t *
name,
size_t name_len,
959 const uint8_t *data,
size_t len, uint8_t
const **retptr,
size_t *retlen)
962 printf(
"DATA START: \n");
964 printf(
"DATA END: \n");
969 for (x = 0; x <
len; x++) {
970 if (!(isspace(data[x])))
977 const uint8_t *line = data + x;
978 size_t line_len =
len-x;
981 printf(
"LINE START: \n");
983 printf(
"LINE END: \n");
985 for (x = 0 ; x < line_len; x++) {
987 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
991 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
992 const uint8_t *token = line +
offset;
993 size_t token_len = x -
offset;
995 if ((x + 1) == line_len) {
1006 printf(
"TOKEN START: \n");
1008 printf(
"TOKEN END: \n");
1010 if (token_len > name_len) {
1011 if (
name == NULL || SCMemcmpLowercase(
name, token, name_len) == 0) {
1012 const uint8_t *value = token + name_len;
1013 size_t value_len = token_len - name_len;
1015 if (value[0] ==
'\"') {
1019 if (value[value_len-1] ==
'\"') {
1023 printf(
"VALUE START: \n");
1025 printf(
"VALUE END: \n");
1028 *retlen = value_len;
1052 static int HtpRequestBodySetupMultipart(
const htp_tx_t *tx,
HtpTxUserData *htud)
1054 const htp_header_t *h = htp_tx_request_header(tx,
"Content-Type");
1055 if (h != NULL && htp_header_value_len(h) > 0) {
1057 SCMimeStateInit(htp_header_value_ptr(h), (uint32_t)htp_header_value_len(h));
1074 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1077 chunks_buffer, chunks_buffer_len,
1081 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1084 if (tx && tx->
tx_data.de_state) {
1085 if (dir == STREAM_TOSERVER) {
1086 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1088 }
else if (dir == STREAM_TOCLIENT) {
1089 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1096 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len,
bool eof)
1099 printf(
"CHUNK START: \n");
1101 printf(
"CHUNK END: \n");
1107 STREAM_TOSERVER) >= HTP_REQUEST_PROGRESS_COMPLETE);
1109 const uint8_t *cur_buf = chunks_buffer;
1110 uint32_t cur_buf_len = chunks_buffer_len;
1126 const uint8_t *filename = NULL;
1127 uint16_t filename_len = 0;
1130 while (cur_buf_len > 0) {
1131 MimeParserResult r =
1132 SCMimeParse(htud->
mime_state, cur_buf, cur_buf_len, &consumed, &warnings);
1136 if (warnings & MIME_EVENT_FLAG_INVALID_HEADER) {
1140 if (warnings & MIME_EVENT_FLAG_NO_FILEDATA) {
1151 SCMimeStateGetFilename(htud->
mime_state, &filename, &filename_len);
1152 if (filename_len > 0) {
1156 hstate, htud, filename, filename_len, NULL, 0, STREAM_TOSERVER);
1159 }
else if (result == -2) {
1162 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1170 }
else if (result == -2) {
1178 uint32_t lastsize = consumed;
1179 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\n') {
1181 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\r') {
1185 HTPFileClose(htud, cur_buf, lastsize, 0, STREAM_TOSERVER);
1190 cur_buf += consumed;
1191 cur_buf_len -= consumed;
1203 const uint8_t *data, uint32_t data_len)
1210 uint8_t *filename = NULL;
1211 size_t filename_len = 0;
1214 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1215 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1216 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1219 if (filename != NULL) {
1225 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1229 }
else if (result == -2) {
1232 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1246 }
else if (result == -2) {
1259 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) {
1375 tx_ud->
tx_data.updated_ts =
true;
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));
1510 tx_ud->
tx_data.updated_tc =
true;
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)
1617 htud->
tx_data.updated_ts =
true;
1619 return HTP_STATUS_OK;
1622 static int HTPCallbackResponseHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1625 htud->
tx_data.updated_tc =
true;
1627 return HTP_STATUS_OK;
1630 static void *HTPCallbackTxCreate(
bool request)
1638 tx_ud->
tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT;
1640 tx_ud->
tx_data.file_tx = STREAM_TOCLIENT;
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));
1674 tx_ud->
tx_data.updated_ts =
true;
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));
1706 tx_ud->
tx_data.updated_tc =
true;
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 =
1730 hstate->
slice->offset + htp_connp_request_data_consumed(hstate->
connp);
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);
1756 htud->
tx_data.updated_ts =
true;
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 =
1793 hstate->
slice->offset + htp_connp_response_data_consumed(hstate->
connp);
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;
1810 htud->
tx_data.updated_tc =
true;
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;
1867 tx_ud->
tx_data.updated_ts =
true;
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;
1888 tx_ud->
tx_data.updated_tc =
true;
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);
2054 if (personality >= 0) {
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-limit", p->
name) == 0) {
2226 FatalError(
"failed to parse 'compression-bomb-limit' "
2227 "from conf file - %s.",
2232 "from conf file cannot be 0.");
2235 SCLogConfig(
"Setting HTTP compression bomb limit to %"PRIu32
" bytes", limit);
2236 htp_config_set_compression_bomb_limit(cfg_prec->
cfg, (
size_t)limit);
2237 }
else if (strcasecmp(
"decompression-time-limit", p->
name) == 0) {
2241 FatalError(
"failed to parse 'decompression-time-limit' "
2242 "from conf file - %s.",
2245 SCLogConfig(
"Setting HTTP decompression time limit to %" PRIu32
" usec", limit);
2246 htp_config_set_compression_time_limit(cfg_prec->
cfg, limit);
2247 }
else if (strcasecmp(
"max-tx", p->
name) == 0) {
2251 "from conf file - %s.",
2255 SCLogConfig(
"Setting HTTP max-tx limit to %" PRIu32
" bytes", limit);
2256 htp_config_set_max_tx(cfg_prec->
cfg, limit);
2257 }
else if (strcasecmp(
"headers-limit", p->
name) == 0) {
2260 FatalError(
"failed to parse 'headers-limit' "
2261 "from conf file - %s.",
2264 SCLogConfig(
"Setting HTTP headers limit to %" PRIu32, limit);
2265 htp_config_set_number_headers_limit(cfg_prec->
cfg, limit);
2266 }
else if (strcasecmp(
"randomize-inspection-sizes", p->
name) == 0) {
2270 }
else if (strcasecmp(
"randomize-inspection-range", p->
name) == 0) {
2273 (
const char *)p->
val, 0, 100) < 0) {
2275 "-inspection-range setting from conf file - \"%s\"."
2276 " It should be a valid integer less than or equal to 100."
2282 }
else if (strcasecmp(
"http-body-inline", p->
name) == 0) {
2288 if (strcmp(
"auto", p->
val) != 0) {
2297 }
else if (strcasecmp(
"swf-decompression", p->
name) == 0) {
2301 if (strcasecmp(
"enabled", pval->
name) == 0) {
2309 }
else if (strcasecmp(
"type", pval->
name) == 0) {
2310 if (strcasecmp(
"no", pval->
val) == 0) {
2312 }
else if (strcasecmp(
"deflate", pval->
val) == 0) {
2314 }
else if (strcasecmp(
"lzma", pval->
val) == 0) {
2316 }
else if (strcasecmp(
"both", pval->
val) == 0) {
2320 "swf-decompression.type: %s - "
2325 }
else if (strcasecmp(
"compress-depth", pval->
name) == 0) {
2327 SCLogError(
"Error parsing swf-decompression.compression-depth "
2328 "from conf file - %s. Killing engine",
2332 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2334 SCLogError(
"Error parsing swf-decompression.decompression-depth "
2335 "from conf file - %s. Killing engine",
2345 "default config: %s",
2355 cfglist.
next = NULL;
2362 cfglist.
cfg = htp_config_create();
2363 if (NULL == cfglist.
cfg) {
2364 FatalError(
"Failed to create HTP default config");
2367 HTPConfigSetDefaultsPhase1(&cfglist);
2368 if (
SCConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2369 HTPConfigParseParameters(&cfglist,
SCConfGetNode(
"libhtp.default-config"), &cfgtree);
2371 HTPConfigParseParameters(&cfglist,
2372 SCConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), &cfgtree);
2374 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2380 if (server_config == NULL) {
2382 if (server_config == NULL) {
2383 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2387 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2406 cfglist.
next = htprec;
2409 cfglist.
next->
cfg = htp_config_create();
2410 if (NULL == cfglist.
next->
cfg) {
2411 FatalError(
"Failed to create HTP server config");
2414 HTPConfigSetDefaultsPhase1(htprec);
2415 HTPConfigParseParameters(htprec, s, &cfgtree);
2416 HTPConfigSetDefaultsPhase2(s->
name, htprec);
2426 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
2440 htp_tx_t *tx = (htp_tx_t *)txv;
2442 if (direction & STREAM_TOCLIENT) {
2450 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
2452 if (direction & STREAM_TOSERVER)
2453 return htp_tx_request_progress((htp_tx_t *)tx);
2455 return htp_tx_response_progress((htp_tx_t *)tx);
2458 static uint64_t HTPStateGetTxCnt(
void *alstate)
2462 if (http_state != NULL && http_state->
connp != NULL) {
2463 const int64_t size = htp_connp_tx_size(http_state->
connp);
2467 return (uint64_t)size;
2473 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
2477 if (http_state != NULL && http_state->
connp != NULL)
2478 return (
void *)htp_connp_tx(http_state->
connp, tx_id);
2487 uint64_t size = HTPStateGetTxCnt(alstate);
2490 while (state->
un.
u64 < size) {
2491 htp_tx_t *tx = htp_connp_tx_index(http_state->
connp, state->
un.
u64);
2495 uint64_t tx_id = htp_tx_index(tx);
2496 if (tx_id < min_tx_id) {
2503 .has_next = state->
un.
u64 < size,
2515 if (http_state != NULL && http_state->
connp != NULL) {
2516 size_t txid = htp_connp_tx_size(http_state->
connp);
2518 return (
void *)htp_connp_tx(http_state->
connp, txid - 1);
2524 static int HTPStateGetEventInfo(
2528 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2534 static int HTPStateGetEventInfoById(
2538 if (*event_name == NULL) {
2540 "http's enum map table.",
2546 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2553 htp_tx_t *tx = (htp_tx_t *)vtx;
2564 static int HTPRegisterPatternsForProtocolDetection(
void)
2566 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
2567 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
2568 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
2569 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
2570 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
2571 const char *spacings[] = {
"|20|",
"|09|", NULL };
2572 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
2577 int register_result;
2578 char method_buffer[32] =
"";
2581 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
2582 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
2585 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
2592 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
2593 if (register_result < 0) {
2600 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
2602 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
2604 if (register_result < 0) {
2620 const char *proto_name =
"http";
2625 if (HTPRegisterPatternsForProtocolDetection() < 0)
2628 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
2643 ALPROTO_HTTP1, HTP_REQUEST_PROGRESS_COMPLETE, HTP_RESPONSE_PROGRESS_COMPLETE);
2655 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
2657 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
2663 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
2666 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
2669 IPPROTO_TCP,
ALPROTO_HTTP1, HtpStateGetStateIdByName, HtpStateGetStateNameById);
2673 SCLogInfo(
"Parser disabled for %s protocol. Protocol detection still on.", proto_name);
2689 cfglist_backup = cfglist;
2694 cfglist = cfglist_backup;
2699 static int HTPParserTest01(
void)
2701 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2703 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2706 memset(&ssn, 0,
sizeof(ssn));
2714 f->
proto = IPPROTO_TCP;
2720 for (u = 0; u < httplen1; u++) {
2724 flags = STREAM_TOSERVER|STREAM_START;
2725 else if (u == (httplen1 - 1))
2726 flags = STREAM_TOSERVER|STREAM_EOF;
2728 flags = STREAM_TOSERVER;
2737 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2740 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2743 FAIL_IF(bstr_cmp_c(htp_header_value(h),
"Victor/1.0"));
2744 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2745 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2754 static int HTPParserTest01b(
void)
2756 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2758 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2761 memset(&ssn, 0,
sizeof(ssn));
2769 f->
proto = IPPROTO_TCP;
2774 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
2781 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2784 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2787 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2788 FAIL_IF(strcmp(v,
"Victor/1.0"));
2790 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2791 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2800 static int HTPParserTest01c(
void)
2802 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2804 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2807 memset(&ssn, 0,
sizeof(ssn));
2815 f->
proto = IPPROTO_TCP;
2821 for (u = 0; u < httplen1; u++) {
2825 flags = STREAM_TOSERVER|STREAM_START;
2826 else if (u == (httplen1 - 1))
2827 flags = STREAM_TOSERVER|STREAM_EOF;
2829 flags = STREAM_TOSERVER;
2838 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2841 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2844 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2845 FAIL_IF(strcmp(v,
"Victor/1.0"));
2847 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2848 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2858 static int HTPParserTest01a(
void)
2861 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2863 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2868 memset(&ssn, 0,
sizeof(ssn));
2870 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2873 f->
proto = IPPROTO_TCP;
2879 for (u = 0; u < httplen1; u++) {
2883 flags = STREAM_TOSERVER|STREAM_START;
2884 else if (u == (httplen1 - 1))
2885 flags = STREAM_TOSERVER|STREAM_EOF;
2887 flags = STREAM_TOSERVER;
2896 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2899 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2902 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2903 FAIL_IF(strcmp(v,
"Victor/1.0"));
2905 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2906 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2915 static int HTPParserTest02(
void)
2918 uint8_t httpbuf1[] =
"POST";
2919 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2924 memset(&ssn, 0,
sizeof(ssn));
2926 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2929 f->
proto = IPPROTO_TCP;
2935 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
2941 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
2943 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2947 char *method = bstr_util_strdup_to_c(htp_tx_request_method(tx));
2950 FAIL_IF(strcmp(method,
"POST") != 0);
2961 static int HTPParserTest03(
void)
2964 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
2965 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2970 memset(&ssn, 0,
sizeof(ssn));
2972 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2975 f->
proto = IPPROTO_TCP;
2981 for (u = 0; u < httplen1; u++) {
2984 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
2985 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
2986 else flags = STREAM_TOSERVER;
2994 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2997 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2999 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3000 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
3010 static int HTPParserTest04(
void)
3014 uint8_t httpbuf1[] =
"World!\r\n";
3015 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3019 memset(&ssn, 0,
sizeof(ssn));
3021 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3024 f->
proto = IPPROTO_TCP;
3030 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3036 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3038 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3040 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3041 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V0_9);
3051 static int HTPParserTest05(
void)
3053 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3054 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3055 uint8_t httpbuf2[] =
"Post D";
3056 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3057 uint8_t httpbuf3[] =
"ata is c0oL!";
3058 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3060 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3061 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3062 uint8_t httpbuf5[] =
"post R";
3063 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3064 uint8_t httpbuf6[] =
"esults are tha bomb!";
3065 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3068 memset(&ssn, 0,
sizeof(ssn));
3076 f->
proto = IPPROTO_TCP;
3106 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3108 FAIL_IF_NOT(htp_tx_request_method_number(tx) == HTP_METHOD_POST);
3109 FAIL_IF_NOT(htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_V1_0);
3111 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3114 FAIL_IF_NOT(htp_tx_response_status_number(tx) == 200);
3124 static int HTPParserTest06(
void)
3126 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3127 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3128 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3129 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3130 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3132 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3133 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3134 "FrontPage/5.0.2.2510\r\n"
3135 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3137 "Content-Type: text/html\r\n\r\n"
3139 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3140 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3141 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3142 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3143 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3144 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3145 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3146 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3147 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3148 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3149 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3150 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3151 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3152 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3153 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3154 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3155 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3156 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3157 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3158 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3159 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3160 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3161 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3162 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3163 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3164 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3165 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3166 "aHA=\r\n0\r\n\r\n";
3167 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3173 memset(&ssn, 0,
sizeof(ssn));
3178 f->
proto = IPPROTO_TCP;
3193 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3196 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
3197 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3199 FAIL_IF(htp_tx_response_status_number(tx) != 200);
3200 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3202 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3213 static int HTPParserTest07(
void)
3216 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3217 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3222 memset(&ssn, 0,
sizeof(ssn));
3224 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3227 f->
proto = IPPROTO_TCP;
3233 for (u = 0; u < httplen1; u++) {
3237 flags = STREAM_TOSERVER|STREAM_START;
3238 else if (u == (httplen1 - 1))
3239 flags = STREAM_TOSERVER|STREAM_EOF;
3241 flags = STREAM_TOSERVER;
3250 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3251 size_t reflen =
sizeof(ref) - 1;
3253 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3255 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3257 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3259 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref, bstr_len(request_uri_normalized)) != 0);
3271 static int HTPParserTest08(
void)
3274 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3275 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3296 memset(&ssn, 0,
sizeof(ssn));
3298 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3301 f->
proto = IPPROTO_TCP;
3306 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3314 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3316 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3318 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3332 static int HTPParserTest09(
void)
3335 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3336 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3346 personality: Apache_2_2\n\
3358 memset(&ssn, 0,
sizeof(ssn));
3360 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3363 f->
proto = IPPROTO_TCP;
3368 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3376 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3378 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3380 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3394 static int HTPParserTest10(
void)
3398 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3399 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3404 memset(&ssn, 0,
sizeof(ssn));
3406 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3409 f->
proto = IPPROTO_TCP;
3415 for (u = 0; u < httplen1; u++) {
3419 flags = STREAM_TOSERVER|STREAM_START;
3420 else if (u == (httplen1 - 1))
3421 flags = STREAM_TOSERVER|STREAM_EOF;
3423 flags = STREAM_TOSERVER;
3432 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3433 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3436 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3440 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3442 FAIL_IF(strcmp(value,
"www.google.com") != 0);
3454 static int HTPParserTest11(
void)
3457 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3458 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3463 memset(&ssn, 0,
sizeof(ssn));
3465 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3468 f->
proto = IPPROTO_TCP;
3474 for (u = 0; u < httplen1; u++) {
3478 flags = STREAM_TOSERVER|STREAM_START;
3479 else if (u == (httplen1 - 1))
3480 flags = STREAM_TOSERVER|STREAM_EOF;
3482 flags = STREAM_TOSERVER;
3491 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3493 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3496 FAIL_IF(bstr_len(request_uri_normalized) != 4);
3497 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3498 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'%');
3499 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'0');
3500 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'0');
3510 static int HTPParserTest12(
void)
3513 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3514 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3519 memset(&ssn, 0,
sizeof(ssn));
3521 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3524 f->
proto = IPPROTO_TCP;
3530 for (u = 0; u < httplen1; u++) {
3534 flags = STREAM_TOSERVER|STREAM_START;
3535 else if (u == (httplen1 - 1))
3536 flags = STREAM_TOSERVER|STREAM_EOF;
3538 flags = STREAM_TOSERVER;
3547 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3549 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3552 FAIL_IF(bstr_len(request_uri_normalized) != 7);
3553 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3554 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'?');
3555 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'a');
3556 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'=');
3557 FAIL_IF(bstr_ptr(request_uri_normalized)[4] !=
'%');
3558 FAIL_IF(bstr_ptr(request_uri_normalized)[5] !=
'0');
3559 FAIL_IF(bstr_ptr(request_uri_normalized)[6] !=
'0');
3569 static int HTPParserTest13(
void)
3572 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3573 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3578 memset(&ssn, 0,
sizeof(ssn));
3580 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3583 f->
proto = IPPROTO_TCP;
3589 for (u = 0; u < httplen1; u++) {
3593 flags = STREAM_TOSERVER|STREAM_START;
3594 else if (u == (httplen1 - 1))
3595 flags = STREAM_TOSERVER|STREAM_EOF;
3597 flags = STREAM_TOSERVER;
3605 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3606 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3609 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3613 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3615 FAIL_IF(strcmp(value,
"www.google.com\rName: Value") != 0);
3627 static int HTPParserConfigTest01(
void)
3640 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3641 personality: Tomcat_6_0\n\
3646 - 192.168.10.0/24\n\
3647 personality: IIS_7_0\n\
3656 outputs =
SCConfGetNode(
"libhtp.default-config.personality");
3667 FAIL_IF(strcmp(node->
name,
"apache-tomcat") != 0);
3674 FAIL_IF(strcmp(node2->
val,
"Tomcat_6_0") != 0);
3684 FAIL_IF(strcmp(n->
val,
"192.168.1.0/24") != 0);
3724 FAIL_IF(strcmp(n->
val,
"192.168.0.0/24") != 0);
3728 FAIL_IF(strcmp(n->
val,
"192.168.10.0/24") != 0);
3743 static int HTPParserConfigTest02(
void)
3756 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3757 personality: Tomcat_6_0\n\
3762 - 192.168.10.0/24\n\
3763 personality: IIS_7_0\n\
3775 htp_cfg_t *htp = cfglist.
cfg;
3778 void *user_data = NULL;
3780 addr =
"192.168.10.42";
3781 FAIL_IF(inet_pton(AF_INET, addr, buf) != 1);
3785 htp = htp_cfg_rec->
cfg;
3791 FAIL_IF(inet_pton(AF_INET6, addr, buf) != 1);
3794 htp_cfg_rec = user_data;
3795 htp = htp_cfg_rec->
cfg;
3808 static int HTPParserConfigTest03(
void)
3811 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3813 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3829 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3830 personality: Tomcat_6_0\n\
3835 - 192.168.10.0/24\n\
3836 personality: IIS_7_0\n\
3847 const char *addr =
"192.168.10.42";
3849 memset(&ssn, 0,
sizeof(ssn));
3854 f->
proto = IPPROTO_TCP;
3857 htp_cfg_t *htp = cfglist.
cfg;
3860 void *user_data = NULL;
3865 htp = htp_cfg_rec->
cfg;
3872 for (u = 0; u < httplen1; u++) {
3875 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3876 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3877 else flags = STREAM_TOSERVER;
3886 FAIL_IF(HTPStateGetTxCnt(htp_state) != 2);
3888 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3890 tx = HTPStateGetTx(htp_state, 1);
3909 static int HTPParserDecodingTest01(
void)
3911 uint8_t httpbuf1[] =
3912 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3913 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3914 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
3915 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3926 personality: Apache_2\n\
3934 const char *addr =
"4.3.2.1";
3935 memset(&ssn, 0,
sizeof(ssn));
3940 f->
proto = IPPROTO_TCP;
3945 for (uint32_t u = 0; u < httplen1; u++) {
3947 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3948 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3949 else flags = STREAM_TOSERVER;
3958 uint8_t ref1[] =
"/abc%2fdef";
3959 size_t reflen =
sizeof(ref1) - 1;
3961 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3965 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3968 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3969 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
3971 uint8_t ref2[] =
"/abc/def?ghi/jkl";
3972 reflen =
sizeof(ref2) - 1;
3974 tx = HTPStateGetTx(htp_state, 1);
3978 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3981 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3982 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
3984 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
3985 reflen =
sizeof(ref3) - 1;
3986 tx = HTPStateGetTx(htp_state, 2);
3990 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3993 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3994 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4006 static int HTPParserDecodingTest01a(
void)
4008 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4009 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4010 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4011 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4022 personality: Apache_2\n\
4030 const char *addr =
"4.3.2.1";
4031 memset(&ssn, 0,
sizeof(ssn));
4036 f->
proto = IPPROTO_TCP;
4042 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4048 uint8_t ref1[] =
"/abc%2fdef";
4049 size_t reflen =
sizeof(ref1) - 1;
4051 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4055 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4058 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4059 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4061 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4062 reflen =
sizeof(ref2) - 1;
4064 tx = HTPStateGetTx(htp_state, 1);
4067 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4070 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4072 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4074 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4075 reflen =
sizeof(ref3) - 1;
4076 tx = HTPStateGetTx(htp_state, 2);
4079 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4082 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4084 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4102 static int HTPParserDecodingTest02(
void)
4105 uint8_t httpbuf1[] =
4106 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4107 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4108 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4109 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4121 double-decode-path: no\n\
4122 double-decode-query: no\n\
4130 const char *addr =
"4.3.2.1";
4131 memset(&ssn, 0,
sizeof(ssn));
4136 f->
proto = IPPROTO_TCP;
4142 for (u = 0; u < httplen1; u++) {
4145 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4146 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4147 else flags = STREAM_TOSERVER;
4156 uint8_t ref1[] =
"/abc/def";
4157 size_t reflen =
sizeof(ref1) - 1;
4159 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4161 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4163 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4164 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4166 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4167 reflen =
sizeof(ref2) - 1;
4169 tx = HTPStateGetTx(htp_state, 1);
4171 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4173 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4175 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4177 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4178 reflen =
sizeof(ref3) - 1;
4179 tx = HTPStateGetTx(htp_state, 2);
4181 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4183 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4185 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4202 static int HTPParserDecodingTest03(
void)
4205 uint8_t httpbuf1[] =
4206 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4207 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4208 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4220 double-decode-path: yes\n\
4221 double-decode-query: yes\n\
4229 const char *addr =
"4.3.2.1";
4230 memset(&ssn, 0,
sizeof(ssn));
4235 f->
proto = IPPROTO_TCP;
4241 for (u = 0; u < httplen1; u++) {
4244 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4245 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4246 else flags = STREAM_TOSERVER;
4255 uint8_t ref1[] =
"/abc/def";
4256 size_t reflen =
sizeof(ref1) - 1;
4258 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4260 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4262 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4264 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4266 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4267 reflen =
sizeof(ref2) - 1;
4269 tx = HTPStateGetTx(htp_state, 1);
4271 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4273 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4275 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4289 static int HTPParserDecodingTest04(
void)
4292 uint8_t httpbuf1[] =
4293 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4294 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4306 double-decode-path: yes\n\
4307 double-decode-query: yes\n\
4315 const char *addr =
"4.3.2.1";
4316 memset(&ssn, 0,
sizeof(ssn));
4321 f->
proto = IPPROTO_TCP;
4327 for (u = 0; u < httplen1; u++) {
4330 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4331 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4332 else flags = STREAM_TOSERVER;
4341 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
4342 size_t reflen =
sizeof(ref1) - 1;
4344 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4346 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4348 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4350 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4364 static int HTPParserDecodingTest05(
void)
4367 uint8_t httpbuf1[] =
4368 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4369 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4381 double-decode-path: yes\n\
4382 double-decode-query: yes\n\
4390 const char *addr =
"4.3.2.1";
4391 memset(&ssn, 0,
sizeof(ssn));
4396 f->
proto = IPPROTO_TCP;
4402 for (u = 0; u < httplen1; u++) {
4405 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4406 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4407 else flags = STREAM_TOSERVER;
4416 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
4417 size_t reflen =
sizeof(ref1) - 1;
4419 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4421 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4423 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4425 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4439 static int HTPParserDecodingTest06(
void)
4442 uint8_t httpbuf1[] =
4443 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4444 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4456 double-decode-path: yes\n\
4457 double-decode-query: yes\n\
4465 const char *addr =
"4.3.2.1";
4466 memset(&ssn, 0,
sizeof(ssn));
4471 f->
proto = IPPROTO_TCP;
4477 for (u = 0; u < httplen1; u++) {
4480 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4481 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4482 else flags = STREAM_TOSERVER;
4491 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
4492 size_t reflen =
sizeof(ref1) - 1;
4494 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4496 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4498 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4500 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4514 static int HTPParserDecodingTest07(
void)
4517 uint8_t httpbuf1[] =
4518 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4519 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4531 double-decode-path: yes\n\
4532 double-decode-query: yes\n\
4533 query-plusspace-decode: yes\n\
4541 const char *addr =
"4.3.2.1";
4542 memset(&ssn, 0,
sizeof(ssn));
4547 f->
proto = IPPROTO_TCP;
4553 for (u = 0; u < httplen1; u++) {
4556 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4557 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4558 else flags = STREAM_TOSERVER;
4567 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
4568 size_t reflen =
sizeof(ref1) - 1;
4570 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4572 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4574 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4576 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4590 static int HTPParserDecodingTest08(
void)
4593 uint8_t httpbuf1[] =
4594 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4595 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4614 const char *addr =
"4.3.2.1";
4615 memset(&ssn, 0,
sizeof(ssn));
4620 f->
proto = IPPROTO_TCP;
4626 for (u = 0; u < httplen1; u++) {
4629 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4630 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4631 else flags = STREAM_TOSERVER;
4640 uint8_t ref1[] =
"/blah/";
4641 size_t reflen =
sizeof(ref1) - 1;
4643 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4645 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4647 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4649 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4663 static int HTPParserDecodingTest09(
void)
4666 uint8_t httpbuf1[] =
4667 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4668 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4680 uri-include-all: true\n\
4688 const char *addr =
"4.3.2.1";
4689 memset(&ssn, 0,
sizeof(ssn));
4694 f->
proto = IPPROTO_TCP;
4700 for (u = 0; u < httplen1; u++) {
4703 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4704 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4705 else flags = STREAM_TOSERVER;
4714 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
4715 size_t reflen =
sizeof(ref1) - 1;
4717 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4719 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4721 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4723 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4736 static int HTPBodyReassemblyTest01(
void)
4741 memset(&hstate, 0x00,
sizeof(hstate));
4743 memset(&flow, 0x00,
sizeof(flow));
4745 htp_cfg_t *cfg = htp_config_create();
4747 htp_connp_t *connp = htp_connp_create(cfg);
4749 const htp_tx_t *tx = htp_connp_get_request_tx(connp);
4755 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
4756 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";
4763 const uint8_t *chunks_buffer = NULL;
4764 uint32_t chunks_buffer_len = 0;
4766 HtpRequestBodyReassemble(htud, &chunks_buffer, &chunks_buffer_len);
4769 printf(
"REASSCHUNK START: \n");
4771 printf(
"REASSCHUNK END: \n");
4774 htud->
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
4775 strlen(
"multipart/form-data; boundary=toto"));
4778 HtpRequestBodyHandleMultipart(&hstate, htud, &tx, chunks_buffer, chunks_buffer_len,
false);
4784 htp_connp_destroy_all(connp);
4785 HtpTxUserDataFree(htud);
4787 htp_config_destroy(cfg);
4792 static int HTPSegvTest01(
void)
4795 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";
4796 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4804 double-decode-path: no\n\
4805 double-decode-query: no\n\
4806 request-body-limit: 0\n\
4807 response-body-limit: 0\n\
4820 memset(&ssn, 0,
sizeof(ssn));
4822 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4825 f->
proto = IPPROTO_TCP;
4830 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
4834 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
4855 static int HTPParserTest14(
void)
4866 double-decode-path: no\n\
4867 double-decode-query: no\n\
4868 request-body-limit: 0\n\
4869 response-body-limit: 0\n\
4874 memset(&ssn, 0,
sizeof(ssn));
4884 memset(httpbuf, 0x00,
len);
4887 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4888 "Host: myhost.lan\r\n"
4889 "Connection: keep-alive\r\n"
4891 "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"
4892 "Referer: http://blah.lan/\r\n"
4893 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
4895 size_t o = strlen(httpbuf);
4896 for ( ; o <
len - 4; o++) {
4899 httpbuf[
len - 4] =
'\r';
4900 httpbuf[
len - 3] =
'\n';
4901 httpbuf[
len - 2] =
'\r';
4902 httpbuf[
len - 1] =
'\n';
4908 f->
proto = IPPROTO_TCP;
4913 for (u = 0; u <
len; u++) {
4916 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4917 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4918 else flags = STREAM_TOSERVER;
4926 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4928 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
4929 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
4936 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG);
4951 static int HTPParserTest15(
void)
4954 char *httpbuf = NULL;
4965 double-decode-path: no\n\
4966 double-decode-query: no\n\
4967 request-body-limit: 0\n\
4968 response-body-limit: 0\n\
4969 meta-field-limit: 20000\n\
4973 memset(&ssn, 0,
sizeof(ssn));
4984 memset(httpbuf, 0x00,
len);
4987 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4988 "Host: myhost.lan\r\n"
4989 "Connection: keep-alive\r\n"
4991 "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"
4992 "Referer: http://blah.lan/\r\n"
4993 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
4995 size_t o = strlen(httpbuf);
4996 for ( ; o <
len - 4; o++) {
4999 httpbuf[
len - 4] =
'\r';
5000 httpbuf[
len - 3] =
'\n';
5001 httpbuf[
len - 2] =
'\r';
5002 httpbuf[
len - 1] =
'\n';
5004 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5007 f->
proto = IPPROTO_TCP;
5013 for (u = 0; u <
len; u++) {
5016 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5017 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5018 else flags = STREAM_TOSERVER;
5027 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5029 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5030 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5049 static int HTPParserTest16(
void)
5056 memset(&ssn, 0,
sizeof(ssn));
5058 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5059 "Host: myhost.lan\r\n"
5060 "Connection: keep-alive\r\n"
5062 "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"
5063 "Referer: http://blah.lan/\r\n"
5064 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5065 "Cookie: blah\r\n\r\n";
5066 size_t len =
sizeof(httpbuf) - 1;
5068 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5071 f->
proto = IPPROTO_TCP;
5076 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5084 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5086 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5087 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5089 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5096 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT);
5097 FAIL_IF(decoder_events->
events[1] != HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT);
5108 static int HTPParserTest20(
void)
5111 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5112 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5113 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5114 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5115 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
5116 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5117 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5118 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5124 memset(&ssn, 0,
sizeof(ssn));
5126 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5129 f->
proto = IPPROTO_TCP;
5148 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5150 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5153 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5154 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5156 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5157 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5167 static int HTPParserTest21(
void)
5170 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5171 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5172 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5173 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5174 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
5175 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5176 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5177 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5183 memset(&ssn, 0,
sizeof(ssn));
5185 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5188 f->
proto = IPPROTO_TCP;
5207 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5209 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5212 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5213 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5215 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5216 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5226 static int HTPParserTest22(
void)
5229 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5230 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5231 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5232 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5233 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
5234 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5235 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5241 memset(&ssn, 0,
sizeof(ssn));
5243 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5246 f->
proto = IPPROTO_TCP;
5261 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5263 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5266 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5267 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5269 FAIL_IF(htp_tx_response_status_number(tx) != -0);
5270 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5280 static int HTPParserTest23(
void)
5283 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5284 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5285 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5286 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5287 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
5288 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5289 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5295 memset(&ssn, 0,
sizeof(ssn));
5297 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5300 f->
proto = IPPROTO_TCP;
5315 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5317 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5320 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5321 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5323 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5324 FAIL_IF(htp_tx_response_protocol_number(tx) != -2);
5335 static int HTPParserTest24(
void)
5338 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5339 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5340 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5341 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5342 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
5343 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5344 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5350 memset(&ssn, 0,
sizeof(ssn));
5352 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5355 f->
proto = IPPROTO_TCP;
5370 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5372 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5375 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5376 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5378 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5379 FAIL_IF(htp_tx_response_protocol_number(tx) != HTP_PROTOCOL_V1_0);
5389 static int HTPParserTest25(
void)
5396 memset(&ssn, 0,
sizeof(ssn));
5401 f->
proto = IPPROTO_TCP;
5405 const char *
str =
"GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
5407 (uint8_t *)
str, strlen(
str));
5431 str =
"HTTP 1.1 200 OK\r\nServer: Suricata/1.0\r\nContent-Length: 8\r\n\r\nSuricata";
5433 (uint8_t *)
str, strlen(
str));
5467 (uint8_t *)
str, strlen(
str));
5478 (uint8_t *)
str, strlen(
str));
5499 static int HTPParserTest26(
void)
5508 request-body-limit: 1\n\
5509 response-body-limit: 1\n\
5523 uint8_t httpbuf1[] =
"GET /alice.txt HTTP/1.1\r\n\r\n";
5524 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5525 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\n"
5526 "Content-Type: text/plain\r\n"
5527 "Content-Length: 228\r\n\r\n"
5528 "Alice was beginning to get very tired of sitting by her sister on the bank."
5529 "Alice was beginning to get very tired of sitting by her sister on the bank.";
5530 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5531 uint8_t httpbuf3[] =
"Alice was beginning to get very tired of sitting by her sister on the bank.\r\n\r\n";
5532 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5538 memset(&th_v, 0,
sizeof(th_v));
5539 memset(&f, 0,
sizeof(f));
5540 memset(&ssn, 0,
sizeof(ssn));
5547 f.
proto = IPPROTO_TCP;
5568 "(filestore; sid:1; rev:1;)");
5637 static int HTPParserTest27(
void)
5640 memset(&cfg, 0,
sizeof(cfg));
5644 uint32_t
len = 1000;
5669 static void HTPParserRegisterTests(
void)
5691 UtRegisterTest(
"HTPParserDecodingTest01", HTPParserDecodingTest01);
5692 UtRegisterTest(
"HTPParserDecodingTest01a", HTPParserDecodingTest01a);
5693 UtRegisterTest(
"HTPParserDecodingTest02", HTPParserDecodingTest02);
5694 UtRegisterTest(
"HTPParserDecodingTest03", HTPParserDecodingTest03);
5695 UtRegisterTest(
"HTPParserDecodingTest04", HTPParserDecodingTest04);
5696 UtRegisterTest(
"HTPParserDecodingTest05", HTPParserDecodingTest05);
5697 UtRegisterTest(
"HTPParserDecodingTest06", HTPParserDecodingTest06);
5698 UtRegisterTest(
"HTPParserDecodingTest07", HTPParserDecodingTest07);
5699 UtRegisterTest(
"HTPParserDecodingTest08", HTPParserDecodingTest08);
5700 UtRegisterTest(
"HTPParserDecodingTest09", HTPParserDecodingTest09);
5702 UtRegisterTest(
"HTPBodyReassemblyTest01", HTPBodyReassemblyTest01);