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));
1407 BUG_ON(
len > (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));
1528 BUG_ON(
len > (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 FAIL_IF(strcmp(bstr_util_strdup_to_c(htp_header_value(h)),
"Victor/1.0"));
2788 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2789 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2798 static int HTPParserTest01c(
void)
2800 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2802 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2805 memset(&ssn, 0,
sizeof(ssn));
2813 f->
proto = IPPROTO_TCP;
2819 for (u = 0; u < httplen1; u++) {
2823 flags = STREAM_TOSERVER|STREAM_START;
2824 else if (u == (httplen1 - 1))
2825 flags = STREAM_TOSERVER|STREAM_EOF;
2827 flags = STREAM_TOSERVER;
2836 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2839 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2842 FAIL_IF(strcmp(bstr_util_strdup_to_c(htp_header_value(h)),
"Victor/1.0"));
2843 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2844 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2854 static int HTPParserTest01a(
void)
2857 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2859 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2864 memset(&ssn, 0,
sizeof(ssn));
2866 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2869 f->
proto = IPPROTO_TCP;
2875 for (u = 0; u < httplen1; u++) {
2879 flags = STREAM_TOSERVER|STREAM_START;
2880 else if (u == (httplen1 - 1))
2881 flags = STREAM_TOSERVER|STREAM_EOF;
2883 flags = STREAM_TOSERVER;
2892 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2895 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2898 FAIL_IF(strcmp(bstr_util_strdup_to_c(htp_header_value(h)),
"Victor/1.0"));
2899 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2900 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2909 static int HTPParserTest02(
void)
2912 uint8_t httpbuf1[] =
"POST";
2913 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2918 memset(&ssn, 0,
sizeof(ssn));
2920 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2923 f->
proto = IPPROTO_TCP;
2929 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
2935 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
2937 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2941 char *method = bstr_util_strdup_to_c(htp_tx_request_method(tx));
2944 FAIL_IF(strcmp(method,
"POST") != 0);
2955 static int HTPParserTest03(
void)
2958 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
2959 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2964 memset(&ssn, 0,
sizeof(ssn));
2966 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2969 f->
proto = IPPROTO_TCP;
2975 for (u = 0; u < httplen1; u++) {
2978 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
2979 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
2980 else flags = STREAM_TOSERVER;
2988 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2991 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2993 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
2994 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
3004 static int HTPParserTest04(
void)
3008 uint8_t httpbuf1[] =
"World!\r\n";
3009 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3013 memset(&ssn, 0,
sizeof(ssn));
3015 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3018 f->
proto = IPPROTO_TCP;
3024 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3030 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3032 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3034 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3035 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V0_9);
3045 static int HTPParserTest05(
void)
3047 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3048 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3049 uint8_t httpbuf2[] =
"Post D";
3050 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3051 uint8_t httpbuf3[] =
"ata is c0oL!";
3052 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3054 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3055 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3056 uint8_t httpbuf5[] =
"post R";
3057 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3058 uint8_t httpbuf6[] =
"esults are tha bomb!";
3059 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3062 memset(&ssn, 0,
sizeof(ssn));
3070 f->
proto = IPPROTO_TCP;
3100 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3102 FAIL_IF_NOT(htp_tx_request_method_number(tx) == HTP_METHOD_POST);
3103 FAIL_IF_NOT(htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_V1_0);
3105 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3108 FAIL_IF_NOT(htp_tx_response_status_number(tx) == 200);
3118 static int HTPParserTest06(
void)
3120 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3121 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3122 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3123 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3124 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3126 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3127 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3128 "FrontPage/5.0.2.2510\r\n"
3129 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3131 "Content-Type: text/html\r\n\r\n"
3133 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3134 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3135 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3136 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3137 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3138 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3139 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3140 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3141 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3142 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3143 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3144 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3145 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3146 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3147 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3148 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3149 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3150 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3151 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3152 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3153 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3154 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3155 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3156 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3157 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3158 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3159 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3160 "aHA=\r\n0\r\n\r\n";
3161 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3167 memset(&ssn, 0,
sizeof(ssn));
3172 f->
proto = IPPROTO_TCP;
3187 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3190 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
3191 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3193 FAIL_IF(htp_tx_response_status_number(tx) != 200);
3194 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3196 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3207 static int HTPParserTest07(
void)
3210 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3211 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3216 memset(&ssn, 0,
sizeof(ssn));
3218 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3221 f->
proto = IPPROTO_TCP;
3227 for (u = 0; u < httplen1; u++) {
3231 flags = STREAM_TOSERVER|STREAM_START;
3232 else if (u == (httplen1 - 1))
3233 flags = STREAM_TOSERVER|STREAM_EOF;
3235 flags = STREAM_TOSERVER;
3244 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3245 size_t reflen =
sizeof(ref) - 1;
3247 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3249 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3251 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3253 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref, bstr_len(request_uri_normalized)) != 0);
3265 static int HTPParserTest08(
void)
3268 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3269 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3290 memset(&ssn, 0,
sizeof(ssn));
3292 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3295 f->
proto = IPPROTO_TCP;
3300 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3308 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3310 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3312 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3326 static int HTPParserTest09(
void)
3329 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3330 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3340 personality: Apache_2_2\n\
3352 memset(&ssn, 0,
sizeof(ssn));
3354 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3357 f->
proto = IPPROTO_TCP;
3362 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3370 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3372 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3374 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3388 static int HTPParserTest10(
void)
3392 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3393 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3398 memset(&ssn, 0,
sizeof(ssn));
3400 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3403 f->
proto = IPPROTO_TCP;
3409 for (u = 0; u < httplen1; u++) {
3413 flags = STREAM_TOSERVER|STREAM_START;
3414 else if (u == (httplen1 - 1))
3415 flags = STREAM_TOSERVER|STREAM_EOF;
3417 flags = STREAM_TOSERVER;
3426 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3427 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3430 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3434 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3436 FAIL_IF(strcmp(value,
"www.google.com") != 0);
3448 static int HTPParserTest11(
void)
3451 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3452 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3457 memset(&ssn, 0,
sizeof(ssn));
3459 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3462 f->
proto = IPPROTO_TCP;
3468 for (u = 0; u < httplen1; u++) {
3472 flags = STREAM_TOSERVER|STREAM_START;
3473 else if (u == (httplen1 - 1))
3474 flags = STREAM_TOSERVER|STREAM_EOF;
3476 flags = STREAM_TOSERVER;
3485 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3487 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3490 FAIL_IF(bstr_len(request_uri_normalized) != 4);
3491 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3492 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'%');
3493 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'0');
3494 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'0');
3504 static int HTPParserTest12(
void)
3507 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3508 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3513 memset(&ssn, 0,
sizeof(ssn));
3515 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3518 f->
proto = IPPROTO_TCP;
3524 for (u = 0; u < httplen1; u++) {
3528 flags = STREAM_TOSERVER|STREAM_START;
3529 else if (u == (httplen1 - 1))
3530 flags = STREAM_TOSERVER|STREAM_EOF;
3532 flags = STREAM_TOSERVER;
3541 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3543 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3546 FAIL_IF(bstr_len(request_uri_normalized) != 7);
3547 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3548 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'?');
3549 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'a');
3550 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'=');
3551 FAIL_IF(bstr_ptr(request_uri_normalized)[4] !=
'%');
3552 FAIL_IF(bstr_ptr(request_uri_normalized)[5] !=
'0');
3553 FAIL_IF(bstr_ptr(request_uri_normalized)[6] !=
'0');
3563 static int HTPParserTest13(
void)
3566 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3567 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3572 memset(&ssn, 0,
sizeof(ssn));
3574 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3577 f->
proto = IPPROTO_TCP;
3583 for (u = 0; u < httplen1; u++) {
3587 flags = STREAM_TOSERVER|STREAM_START;
3588 else if (u == (httplen1 - 1))
3589 flags = STREAM_TOSERVER|STREAM_EOF;
3591 flags = STREAM_TOSERVER;
3599 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3600 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3603 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3607 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3609 FAIL_IF(strcmp(value,
"www.google.com\rName: Value") != 0);
3621 static int HTPParserConfigTest01(
void)
3634 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3635 personality: Tomcat_6_0\n\
3640 - 192.168.10.0/24\n\
3641 personality: IIS_7_0\n\
3650 outputs =
SCConfGetNode(
"libhtp.default-config.personality");
3661 FAIL_IF(strcmp(node->
name,
"apache-tomcat") != 0);
3668 FAIL_IF(strcmp(node2->
val,
"Tomcat_6_0") != 0);
3678 FAIL_IF(strcmp(n->
val,
"192.168.1.0/24") != 0);
3718 FAIL_IF(strcmp(n->
val,
"192.168.0.0/24") != 0);
3722 FAIL_IF(strcmp(n->
val,
"192.168.10.0/24") != 0);
3737 static int HTPParserConfigTest02(
void)
3750 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3751 personality: Tomcat_6_0\n\
3756 - 192.168.10.0/24\n\
3757 personality: IIS_7_0\n\
3769 htp_cfg_t *htp = cfglist.
cfg;
3772 void *user_data = NULL;
3774 addr =
"192.168.10.42";
3775 FAIL_IF(inet_pton(AF_INET, addr, buf) != 1);
3779 htp = htp_cfg_rec->
cfg;
3785 FAIL_IF(inet_pton(AF_INET6, addr, buf) != 1);
3788 htp_cfg_rec = user_data;
3789 htp = htp_cfg_rec->
cfg;
3802 static int HTPParserConfigTest03(
void)
3805 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3807 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3823 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3824 personality: Tomcat_6_0\n\
3829 - 192.168.10.0/24\n\
3830 personality: IIS_7_0\n\
3841 const char *addr =
"192.168.10.42";
3843 memset(&ssn, 0,
sizeof(ssn));
3848 f->
proto = IPPROTO_TCP;
3851 htp_cfg_t *htp = cfglist.
cfg;
3854 void *user_data = NULL;
3859 htp = htp_cfg_rec->
cfg;
3866 for (u = 0; u < httplen1; u++) {
3869 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3870 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3871 else flags = STREAM_TOSERVER;
3880 FAIL_IF(HTPStateGetTxCnt(htp_state) != 2);
3882 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3884 tx = HTPStateGetTx(htp_state, 1);
3903 static int HTPParserDecodingTest01(
void)
3905 uint8_t httpbuf1[] =
3906 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3907 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3908 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
3909 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3920 personality: Apache_2\n\
3928 const char *addr =
"4.3.2.1";
3929 memset(&ssn, 0,
sizeof(ssn));
3934 f->
proto = IPPROTO_TCP;
3939 for (uint32_t u = 0; u < httplen1; u++) {
3941 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3942 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3943 else flags = STREAM_TOSERVER;
3952 uint8_t ref1[] =
"/abc%2fdef";
3953 size_t reflen =
sizeof(ref1) - 1;
3955 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3959 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3962 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3963 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
3965 uint8_t ref2[] =
"/abc/def?ghi/jkl";
3966 reflen =
sizeof(ref2) - 1;
3968 tx = HTPStateGetTx(htp_state, 1);
3972 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3975 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3976 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
3978 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
3979 reflen =
sizeof(ref3) - 1;
3980 tx = HTPStateGetTx(htp_state, 2);
3984 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3987 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3988 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4000 static int HTPParserDecodingTest01a(
void)
4002 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4003 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4004 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4005 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4016 personality: Apache_2\n\
4024 const char *addr =
"4.3.2.1";
4025 memset(&ssn, 0,
sizeof(ssn));
4030 f->
proto = IPPROTO_TCP;
4036 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4042 uint8_t ref1[] =
"/abc%2fdef";
4043 size_t reflen =
sizeof(ref1) - 1;
4045 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4049 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4052 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4053 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4055 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4056 reflen =
sizeof(ref2) - 1;
4058 tx = HTPStateGetTx(htp_state, 1);
4061 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4064 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4066 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4068 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4069 reflen =
sizeof(ref3) - 1;
4070 tx = HTPStateGetTx(htp_state, 2);
4073 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4076 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4078 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4096 static int HTPParserDecodingTest02(
void)
4099 uint8_t httpbuf1[] =
4100 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4101 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4102 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4103 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4115 double-decode-path: no\n\
4116 double-decode-query: no\n\
4124 const char *addr =
"4.3.2.1";
4125 memset(&ssn, 0,
sizeof(ssn));
4130 f->
proto = IPPROTO_TCP;
4136 for (u = 0; u < httplen1; u++) {
4139 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4140 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4141 else flags = STREAM_TOSERVER;
4150 uint8_t ref1[] =
"/abc/def";
4151 size_t reflen =
sizeof(ref1) - 1;
4153 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4155 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4157 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4158 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4160 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4161 reflen =
sizeof(ref2) - 1;
4163 tx = HTPStateGetTx(htp_state, 1);
4165 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4167 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4169 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4171 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4172 reflen =
sizeof(ref3) - 1;
4173 tx = HTPStateGetTx(htp_state, 2);
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), ref3, bstr_len(request_uri_normalized)) != 0);
4196 static int HTPParserDecodingTest03(
void)
4199 uint8_t httpbuf1[] =
4200 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4201 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4202 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4214 double-decode-path: yes\n\
4215 double-decode-query: yes\n\
4223 const char *addr =
"4.3.2.1";
4224 memset(&ssn, 0,
sizeof(ssn));
4229 f->
proto = IPPROTO_TCP;
4235 for (u = 0; u < httplen1; u++) {
4238 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4239 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4240 else flags = STREAM_TOSERVER;
4249 uint8_t ref1[] =
"/abc/def";
4250 size_t reflen =
sizeof(ref1) - 1;
4252 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4254 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4256 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4258 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4260 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4261 reflen =
sizeof(ref2) - 1;
4263 tx = HTPStateGetTx(htp_state, 1);
4265 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4267 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4269 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4283 static int HTPParserDecodingTest04(
void)
4286 uint8_t httpbuf1[] =
4287 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4288 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4300 double-decode-path: yes\n\
4301 double-decode-query: yes\n\
4309 const char *addr =
"4.3.2.1";
4310 memset(&ssn, 0,
sizeof(ssn));
4315 f->
proto = IPPROTO_TCP;
4321 for (u = 0; u < httplen1; u++) {
4324 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4325 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4326 else flags = STREAM_TOSERVER;
4335 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
4336 size_t reflen =
sizeof(ref1) - 1;
4338 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4340 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4342 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4344 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4358 static int HTPParserDecodingTest05(
void)
4361 uint8_t httpbuf1[] =
4362 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4363 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4375 double-decode-path: yes\n\
4376 double-decode-query: yes\n\
4384 const char *addr =
"4.3.2.1";
4385 memset(&ssn, 0,
sizeof(ssn));
4390 f->
proto = IPPROTO_TCP;
4396 for (u = 0; u < httplen1; u++) {
4399 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4400 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4401 else flags = STREAM_TOSERVER;
4410 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
4411 size_t reflen =
sizeof(ref1) - 1;
4413 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4415 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4417 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4419 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4433 static int HTPParserDecodingTest06(
void)
4436 uint8_t httpbuf1[] =
4437 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4438 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4450 double-decode-path: yes\n\
4451 double-decode-query: yes\n\
4459 const char *addr =
"4.3.2.1";
4460 memset(&ssn, 0,
sizeof(ssn));
4465 f->
proto = IPPROTO_TCP;
4471 for (u = 0; u < httplen1; u++) {
4474 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4475 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4476 else flags = STREAM_TOSERVER;
4485 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
4486 size_t reflen =
sizeof(ref1) - 1;
4488 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4490 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4492 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4494 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4508 static int HTPParserDecodingTest07(
void)
4511 uint8_t httpbuf1[] =
4512 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4513 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4525 double-decode-path: yes\n\
4526 double-decode-query: yes\n\
4527 query-plusspace-decode: yes\n\
4535 const char *addr =
"4.3.2.1";
4536 memset(&ssn, 0,
sizeof(ssn));
4541 f->
proto = IPPROTO_TCP;
4547 for (u = 0; u < httplen1; u++) {
4550 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4551 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4552 else flags = STREAM_TOSERVER;
4561 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
4562 size_t reflen =
sizeof(ref1) - 1;
4564 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4566 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4568 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4570 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4584 static int HTPParserDecodingTest08(
void)
4587 uint8_t httpbuf1[] =
4588 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4589 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4608 const char *addr =
"4.3.2.1";
4609 memset(&ssn, 0,
sizeof(ssn));
4614 f->
proto = IPPROTO_TCP;
4620 for (u = 0; u < httplen1; u++) {
4623 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4624 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4625 else flags = STREAM_TOSERVER;
4634 uint8_t ref1[] =
"/blah/";
4635 size_t reflen =
sizeof(ref1) - 1;
4637 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4639 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4641 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4643 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4657 static int HTPParserDecodingTest09(
void)
4660 uint8_t httpbuf1[] =
4661 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4662 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4674 uri-include-all: true\n\
4682 const char *addr =
"4.3.2.1";
4683 memset(&ssn, 0,
sizeof(ssn));
4688 f->
proto = IPPROTO_TCP;
4694 for (u = 0; u < httplen1; u++) {
4697 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4698 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4699 else flags = STREAM_TOSERVER;
4708 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
4709 size_t reflen =
sizeof(ref1) - 1;
4711 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4713 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4715 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4717 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4730 static int HTPBodyReassemblyTest01(
void)
4733 memset(&htud, 0x00,
sizeof(htud));
4735 memset(&hstate, 0x00,
sizeof(hstate));
4737 memset(&flow, 0x00,
sizeof(flow));
4739 htp_cfg_t *cfg = htp_config_create();
4741 htp_connp_t *connp = htp_connp_create(cfg);
4743 const htp_tx_t *tx = htp_connp_get_request_tx(connp);
4749 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
4750 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";
4757 const uint8_t *chunks_buffer = NULL;
4758 uint32_t chunks_buffer_len = 0;
4760 HtpRequestBodyReassemble(&htud, &chunks_buffer, &chunks_buffer_len);
4763 printf(
"REASSCHUNK START: \n");
4765 printf(
"REASSCHUNK END: \n");
4768 htud.
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
4769 strlen(
"multipart/form-data; boundary=toto"));
4772 HtpRequestBodyHandleMultipart(&hstate, &htud, &tx, chunks_buffer, chunks_buffer_len,
false);
4782 static int HTPSegvTest01(
void)
4785 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";
4786 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4794 double-decode-path: no\n\
4795 double-decode-query: no\n\
4796 request-body-limit: 0\n\
4797 response-body-limit: 0\n\
4810 memset(&ssn, 0,
sizeof(ssn));
4812 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4815 f->
proto = IPPROTO_TCP;
4820 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
4824 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
4845 static int HTPParserTest14(
void)
4856 double-decode-path: no\n\
4857 double-decode-query: no\n\
4858 request-body-limit: 0\n\
4859 response-body-limit: 0\n\
4864 memset(&ssn, 0,
sizeof(ssn));
4874 memset(httpbuf, 0x00,
len);
4877 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4878 "Host: myhost.lan\r\n"
4879 "Connection: keep-alive\r\n"
4881 "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"
4882 "Referer: http://blah.lan/\r\n"
4883 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
4885 size_t o = strlen(httpbuf);
4886 for ( ; o <
len - 4; o++) {
4889 httpbuf[
len - 4] =
'\r';
4890 httpbuf[
len - 3] =
'\n';
4891 httpbuf[
len - 2] =
'\r';
4892 httpbuf[
len - 1] =
'\n';
4898 f->
proto = IPPROTO_TCP;
4903 for (u = 0; u <
len; u++) {
4906 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4907 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4908 else flags = STREAM_TOSERVER;
4916 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4918 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
4919 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
4926 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG);
4941 static int HTPParserTest15(
void)
4944 char *httpbuf = NULL;
4955 double-decode-path: no\n\
4956 double-decode-query: no\n\
4957 request-body-limit: 0\n\
4958 response-body-limit: 0\n\
4959 meta-field-limit: 20000\n\
4963 memset(&ssn, 0,
sizeof(ssn));
4974 memset(httpbuf, 0x00,
len);
4977 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4978 "Host: myhost.lan\r\n"
4979 "Connection: keep-alive\r\n"
4981 "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"
4982 "Referer: http://blah.lan/\r\n"
4983 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
4985 size_t o = strlen(httpbuf);
4986 for ( ; o <
len - 4; o++) {
4989 httpbuf[
len - 4] =
'\r';
4990 httpbuf[
len - 3] =
'\n';
4991 httpbuf[
len - 2] =
'\r';
4992 httpbuf[
len - 1] =
'\n';
4994 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4997 f->
proto = IPPROTO_TCP;
5003 for (u = 0; u <
len; u++) {
5006 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5007 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5008 else flags = STREAM_TOSERVER;
5017 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5019 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5020 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5039 static int HTPParserTest16(
void)
5046 memset(&ssn, 0,
sizeof(ssn));
5048 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5049 "Host: myhost.lan\r\n"
5050 "Connection: keep-alive\r\n"
5052 "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"
5053 "Referer: http://blah.lan/\r\n"
5054 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5055 "Cookie: blah\r\n\r\n";
5056 size_t len =
sizeof(httpbuf) - 1;
5058 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5061 f->
proto = IPPROTO_TCP;
5066 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5074 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5076 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5077 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5079 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5086 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT);
5087 FAIL_IF(decoder_events->
events[1] != HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT);
5098 static int HTPParserTest20(
void)
5101 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5102 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5103 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5104 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5105 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
5106 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5107 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5108 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5114 memset(&ssn, 0,
sizeof(ssn));
5116 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5119 f->
proto = IPPROTO_TCP;
5138 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5140 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5143 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5144 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5146 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5147 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5157 static int HTPParserTest21(
void)
5160 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5161 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5162 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5163 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5164 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
5165 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5166 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5167 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5173 memset(&ssn, 0,
sizeof(ssn));
5175 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5178 f->
proto = IPPROTO_TCP;
5197 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5199 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5202 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5203 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5205 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5206 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5216 static int HTPParserTest22(
void)
5219 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5220 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5221 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5222 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5223 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
5224 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5225 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5231 memset(&ssn, 0,
sizeof(ssn));
5233 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5236 f->
proto = IPPROTO_TCP;
5251 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5253 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5256 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5257 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5259 FAIL_IF(htp_tx_response_status_number(tx) != -0);
5260 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5270 static int HTPParserTest23(
void)
5273 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5274 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5275 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5276 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5277 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
5278 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5279 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5285 memset(&ssn, 0,
sizeof(ssn));
5287 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5290 f->
proto = IPPROTO_TCP;
5305 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5307 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5310 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5311 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5313 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5314 FAIL_IF(htp_tx_response_protocol_number(tx) != -2);
5325 static int HTPParserTest24(
void)
5328 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5329 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5330 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5331 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5332 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
5333 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5334 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5340 memset(&ssn, 0,
sizeof(ssn));
5342 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5345 f->
proto = IPPROTO_TCP;
5360 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5362 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5365 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5366 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5368 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5369 FAIL_IF(htp_tx_response_protocol_number(tx) != HTP_PROTOCOL_V1_0);
5379 static int HTPParserTest25(
void)
5386 memset(&ssn, 0,
sizeof(ssn));
5391 f->
proto = IPPROTO_TCP;
5395 const char *
str =
"GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
5397 (uint8_t *)
str, strlen(
str));
5421 str =
"HTTP 1.1 200 OK\r\nServer: Suricata/1.0\r\nContent-Length: 8\r\n\r\nSuricata";
5423 (uint8_t *)
str, strlen(
str));
5457 (uint8_t *)
str, strlen(
str));
5468 (uint8_t *)
str, strlen(
str));
5489 static int HTPParserTest26(
void)
5498 request-body-limit: 1\n\
5499 response-body-limit: 1\n\
5513 uint8_t httpbuf1[] =
"GET /alice.txt HTTP/1.1\r\n\r\n";
5514 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5515 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\n"
5516 "Content-Type: text/plain\r\n"
5517 "Content-Length: 228\r\n\r\n"
5518 "Alice was beginning to get very tired of sitting by her sister on the bank."
5519 "Alice was beginning to get very tired of sitting by her sister on the bank.";
5520 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5521 uint8_t httpbuf3[] =
"Alice was beginning to get very tired of sitting by her sister on the bank.\r\n\r\n";
5522 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5528 memset(&th_v, 0,
sizeof(th_v));
5529 memset(&f, 0,
sizeof(f));
5530 memset(&ssn, 0,
sizeof(ssn));
5537 f.
proto = IPPROTO_TCP;
5558 "(filestore; sid:1; rev:1;)");
5626 static int HTPParserTest27(
void)
5629 memset(&cfg, 0,
sizeof(cfg));
5633 uint32_t
len = 1000;
5658 static void HTPParserRegisterTests(
void)
5680 UtRegisterTest(
"HTPParserDecodingTest01", HTPParserDecodingTest01);
5681 UtRegisterTest(
"HTPParserDecodingTest01a", HTPParserDecodingTest01a);
5682 UtRegisterTest(
"HTPParserDecodingTest02", HTPParserDecodingTest02);
5683 UtRegisterTest(
"HTPParserDecodingTest03", HTPParserDecodingTest03);
5684 UtRegisterTest(
"HTPParserDecodingTest04", HTPParserDecodingTest04);
5685 UtRegisterTest(
"HTPParserDecodingTest05", HTPParserDecodingTest05);
5686 UtRegisterTest(
"HTPParserDecodingTest06", HTPParserDecodingTest06);
5687 UtRegisterTest(
"HTPParserDecodingTest07", HTPParserDecodingTest07);
5688 UtRegisterTest(
"HTPParserDecodingTest08", HTPParserDecodingTest08);
5689 UtRegisterTest(
"HTPParserDecodingTest09", HTPParserDecodingTest09);
5691 UtRegisterTest(
"HTPBodyReassemblyTest01", HTPBodyReassemblyTest01);