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,
168 {
"SWITCHING_PROTO_WITH_CONTENT_LENGTH", HTP_LOG_CODE_SWITCHING_PROTO_WITH_CONTENT_LENGTH },
169 {
"DEFORMED_EOL", HTP_LOG_CODE_DEFORMED_EOL },
170 {
"PARSER_STATE_ERROR", HTP_LOG_CODE_PARSER_STATE_ERROR },
171 {
"MISSING_OUTBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_OUTBOUND_TRANSACTION_DATA },
172 {
"MISSING_INBOUND_TRANSACTION_DATA", HTP_LOG_CODE_MISSING_INBOUND_TRANSACTION_DATA },
173 {
"ZERO_LENGTH_DATA_CHUNKS", HTP_LOG_CODE_ZERO_LENGTH_DATA_CHUNKS },
174 {
"REQUEST_LINE_UNKNOWN_METHOD", HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD },
175 {
"REQUEST_LINE_UNKNOWN_METHOD_NO_PROTOCOL",
176 HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD_NO_PROTOCOL },
177 {
"REQUEST_LINE_UNKNOWN_METHOD_INVALID_PROTOCOL",
178 HTP_LOG_CODE_REQUEST_LINE_UNKNOWN_METHOD_INVALID_PROTOCOL },
179 {
"REQUEST_LINE_MISSING_PROTOCOL", HTP_LOG_CODE_REQUEST_LINE_NO_PROTOCOL },
180 {
"RESPONSE_LINE_INVALID_PROTOCOL", HTP_LOG_CODE_RESPONSE_LINE_INVALID_PROTOCOL },
181 {
"RESPONSE_LINE_INVALID_RESPONSE_STATUS", HTP_LOG_CODE_RESPONSE_LINE_INVALID_RESPONSE_STATUS },
182 {
"RESPONSE_BODY_INTERNAL_ERROR", HTP_LOG_CODE_RESPONSE_BODY_INTERNAL_ERROR },
183 {
"REQUEST_BODY_DATA_CALLBACK_ERROR", HTP_LOG_CODE_REQUEST_BODY_DATA_CALLBACK_ERROR },
184 {
"RESPONSE_INVALID_EMPTY_NAME", HTP_LOG_CODE_RESPONSE_INVALID_EMPTY_NAME },
185 {
"REQUEST_INVALID_EMPTY_NAME", HTP_LOG_CODE_REQUEST_INVALID_EMPTY_NAME },
186 {
"RESPONSE_INVALID_LWS_AFTER_NAME", HTP_LOG_CODE_RESPONSE_INVALID_LWS_AFTER_NAME },
187 {
"RESPONSE_HEADER_NAME_NOT_TOKEN", HTP_LOG_CODE_RESPONSE_HEADER_NAME_NOT_TOKEN },
188 {
"REQUEST_INVALID_LWS_AFTER_NAME", HTP_LOG_CODE_REQUEST_INVALID_LWS_AFTER_NAME },
189 {
"LZMA_DECOMPRESSION_DISABLED", HTP_LOG_CODE_LZMA_DECOMPRESSION_DISABLED },
190 {
"CONNECTION_ALREADY_OPEN", HTP_LOG_CODE_CONNECTION_ALREADY_OPEN },
191 {
"COMPRESSION_BOMB_DOUBLE_LZMA", HTP_LOG_CODE_COMPRESSION_BOMB_DOUBLE_LZMA },
192 {
"INVALID_CONTENT_ENCODING", HTP_LOG_CODE_INVALID_CONTENT_ENCODING },
193 {
"INVALID_GAP", HTP_LOG_CODE_INVALID_GAP },
194 {
"REQUEST_CHUNK_EXTENSION", HTP_LOG_CODE_REQUEST_CHUNK_EXTENSION },
195 {
"RESPONSE_CHUNK_EXTENSION", HTP_LOG_CODE_RESPONSE_CHUNK_EXTENSION },
197 {
"LZMA_MEMLIMIT_REACHED", HTP_LOG_CODE_LZMA_MEMLIMIT_REACHED },
198 {
"COMPRESSION_BOMB", HTP_LOG_CODE_COMPRESSION_BOMB },
199 {
"COMPRESSION_BOMB_LIMIT_REACHED", HTP_LOG_CODE_COMPRESSION_BOMB_LIMIT_REACHED },
201 {
"REQUEST_TOO_MANY_HEADERS", HTP_LOG_CODE_REQUEST_TOO_MANY_HEADERS },
202 {
"RESPONSE_TOO_MANY_HEADERS", HTP_LOG_CODE_RESPONSE_TOO_MANY_HEADERS },
235 static int HTTPGetFrameIdByName(
const char *frame_name)
244 static const char *HTTPGetFrameNameById(
const uint8_t frame_id)
254 HTP_REQUEST_PROGRESS_NOT_STARTED,
258 HTP_REQUEST_PROGRESS_LINE,
262 HTP_REQUEST_PROGRESS_HEADERS,
266 HTP_REQUEST_PROGRESS_BODY,
270 HTP_REQUEST_PROGRESS_TRAILER,
274 HTP_REQUEST_PROGRESS_COMPLETE,
283 HTP_RESPONSE_PROGRESS_NOT_STARTED,
287 HTP_RESPONSE_PROGRESS_LINE,
291 HTP_RESPONSE_PROGRESS_HEADERS,
295 HTP_RESPONSE_PROGRESS_BODY,
299 HTP_RESPONSE_PROGRESS_TRAILER,
303 HTP_RESPONSE_PROGRESS_COMPLETE,
308 static int HtpStateGetStateIdByName(
const char *
name,
const uint8_t direction)
311 direction == STREAM_TOSERVER ? http_state_client_table : http_state_server_table;
320 static const char *HtpStateGetStateNameById(
const int id,
const uint8_t direction)
323 direction == STREAM_TOSERVER ? http_state_client_table : http_state_server_table;
328 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id);
329 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction);
330 static uint64_t HTPStateGetTxCnt(
void *alstate);
332 static void HTPParserRegisterTests(
void);
335 static inline uint64_t HtpGetActiveRequestTxID(
HtpState *s)
337 uint64_t
id = HTPStateGetTxCnt(s);
342 static inline uint64_t HtpGetActiveResponseTxID(
HtpState *s)
355 static const char *HTPLookupPersonalityString(
int p)
357 #define CASE_HTP_PERSONALITY_STRING(p) \
358 case HTP_SERVER_PERSONALITY_##p: \
362 CASE_HTP_PERSONALITY_STRING(MINIMAL);
363 CASE_HTP_PERSONALITY_STRING(GENERIC);
364 CASE_HTP_PERSONALITY_STRING(IDS);
365 CASE_HTP_PERSONALITY_STRING(IIS_4_0);
366 CASE_HTP_PERSONALITY_STRING(IIS_5_0);
367 CASE_HTP_PERSONALITY_STRING(IIS_5_1);
368 CASE_HTP_PERSONALITY_STRING(IIS_6_0);
369 CASE_HTP_PERSONALITY_STRING(IIS_7_0);
370 CASE_HTP_PERSONALITY_STRING(IIS_7_5);
371 CASE_HTP_PERSONALITY_STRING(APACHE_2);
385 static int HTPLookupPersonality(
const char *
str)
387 #define IF_HTP_PERSONALITY_NUM(p) \
388 if (strcasecmp(#p, str) == 0) \
389 return HTP_SERVER_PERSONALITY_##p
401 if (strcasecmp(
"TOMCAT_6_0",
str) == 0) {
403 "longer supported by libhtp.",
406 }
else if ((strcasecmp(
"APACHE",
str) == 0) ||
407 (strcasecmp(
"APACHE_2_2",
str) == 0))
410 "longer supported by libhtp, failing back to "
411 "Apache2 personality.",
413 return HTP_SERVER_PERSONALITY_APACHE_2;
420 const uint8_t dir,
const uint8_t e)
430 const uint64_t tx_id = (dir == STREAM_TOSERVER) ?
431 HtpGetActiveRequestTxID(s) : HtpGetActiveResponseTxID(s);
433 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
434 if (tx == NULL && tx_id > 0)
435 tx = HTPStateGetTx(s, tx_id - 1);
439 if (dir & STREAM_TOCLIENT)
441 if (dir & STREAM_TOSERVER)
452 static void *HTPStateAlloc(
void *orig_state,
AppProto proto_orig)
466 htp_state_memuse +=
sizeof(
HtpState);
467 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
474 static void HtpTxUserDataFree(
void *txud)
510 if (s->
connp != NULL) {
512 htp_connp_destroy_all(s->
connp);
520 htp_state_memuse -=
sizeof(
HtpState);
521 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
532 static void HTPStateTransactionFree(
void *state, uint64_t
id)
539 htp_tx_destroy(s->
connp,
id);
584 static void AppLayerHtpSetStreamDepthFlag(
void *tx,
const uint8_t
flags)
588 if (
flags & STREAM_TOCLIENT) {
597 SCLogDebug(
"cfg->body_limit %u stream_depth %u body->content_len_so_far %" PRIu64,
614 static uint32_t AppLayerHtpComputeChunkLength(uint64_t content_len_so_far, uint32_t body_limit,
615 uint32_t stream_depth, uint8_t
flags, uint32_t data_len)
617 uint32_t chunk_len = 0;
619 (content_len_so_far < (uint64_t)body_limit) &&
620 (content_len_so_far + (uint64_t)data_len) > body_limit)
622 chunk_len = (uint32_t)(body_limit - content_len_so_far);
624 (content_len_so_far < (uint64_t)stream_depth) &&
625 (content_len_so_far + (uint64_t)data_len) > stream_depth)
627 chunk_len = (uint32_t)(stream_depth - content_len_so_far);
630 return (chunk_len == 0 ? data_len : chunk_len);
641 static void HTPHandleError(
HtpState *s,
const uint8_t dir)
648 htp_log_t *log = htp_conn_next_log(s->
conn);
649 while (log != NULL) {
650 char *msg = htp_log_message(log);
653 log = htp_conn_next_log(s->
conn);
659 htp_log_code_t
id = htp_log_code(log);
660 if (
id != HTP_LOG_CODE_UNKNOWN &&
id != HTP_LOG_CODE_ERROR) {
661 HTPSetEvent(s, NULL, dir, (uint8_t)
id);
663 htp_free_cstring(msg);
673 log = htp_conn_next_log(s->
conn);
678 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s,
const htp_tx_t *tx)
681 BUG_ON(s == NULL || tx == NULL);
683 if (htp_tx_flags(tx) & (HTP_FLAGS_REQUEST_INVALID_T_E | HTP_FLAGS_REQUEST_INVALID_C_L |
684 HTP_FLAGS_HOST_MISSING | HTP_FLAGS_HOST_AMBIGUOUS |
685 HTP_FLAGS_HOSTU_INVALID | HTP_FLAGS_HOSTH_INVALID)) {
688 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_T_E)
689 HTPSetEvent(s, htud, STREAM_TOSERVER,
690 HTP_LOG_CODE_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST);
691 if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_C_L)
693 s, htud, STREAM_TOSERVER, HTP_LOG_CODE_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST);
694 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_MISSING)
695 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_MISSING_HOST_HEADER);
696 if (htp_tx_flags(tx) & HTP_FLAGS_HOST_AMBIGUOUS)
697 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HOST_HEADER_AMBIGUOUS);
698 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTU_INVALID)
699 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_URI_HOST_INVALID);
700 if (htp_tx_flags(tx) & HTP_FLAGS_HOSTH_INVALID)
701 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_HEADER_HOST_INVALID);
703 if (htp_tx_request_auth_type(tx) == HTP_AUTH_TYPE_UNRECOGNIZED) {
705 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_AUTH_UNRECOGNIZED);
707 if (htp_tx_is_protocol_0_9(tx) && htp_tx_request_method_number(tx) == HTP_METHOD_UNKNOWN &&
708 (htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_INVALID ||
709 htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_UNKNOWN)) {
711 HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_REQUEST_LINE_INVALID);
721 htp_cfg_t *htp = cfglist.
cfg;
722 void *user_data = NULL;
738 if (user_data != NULL) {
739 htp_cfg_rec = user_data;
740 htp = htp_cfg_rec->
cfg;
743 SCLogDebug(
"Using default HTP config: %p", htp);
747 #ifdef DEBUG_VALIDATION
754 hstate->
connp = htp_connp_create(htp);
755 if (hstate->
connp == NULL) {
759 hstate->
conn = (htp_conn_t *)htp_connp_connection(hstate->
connp);
761 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
762 hstate->
cfg = htp_cfg_rec;
767 htp_connp_open(hstate->
connp, NULL, f->
sp, NULL, f->
dp, &
tv);
799 if (NULL == hstate->
conn) {
800 if (Setup(f, hstate) != 0) {
805 hstate->
slice = &stream_slice;
807 const uint8_t *input = StreamSliceGetData(&stream_slice);
808 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
813 const int r = htp_connp_request_data(hstate->
connp, &
ts, input, input_len);
815 case HTP_STREAM_STATE_ERROR:
821 HTPHandleError(hstate, STREAM_TOSERVER);
827 htp_connp_request_close(hstate->
connp, &
ts);
829 SCLogDebug(
"stream eof encountered, closing htp handle for ts");
833 hstate->
slice = NULL;
861 const uint8_t *input = StreamSliceGetData(&stream_slice);
862 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
868 if (NULL == hstate->
conn) {
869 if (Setup(f, hstate) != 0) {
874 hstate->
slice = &stream_slice;
877 const htp_tx_t *tx = NULL;
878 uint32_t consumed = 0;
880 const int r = htp_connp_response_data(hstate->
connp, &
ts, input, input_len);
882 case HTP_STREAM_STATE_ERROR:
885 case HTP_STREAM_STATE_TUNNEL:
886 tx = htp_connp_get_response_tx(hstate->
connp);
887 if (tx != NULL && htp_tx_response_status_number(tx) == 101) {
888 const htp_header_t *h = htp_tx_response_header(tx,
"Upgrade");
893 if (htp_tx_request_port_number(tx) != -1) {
894 dp = (uint16_t)htp_tx_request_port_number(tx);
896 consumed = (uint32_t)htp_connp_response_data_consumed(hstate->
connp);
897 if (bstr_cmp_c(htp_header_value(h),
"h2c") == 0) {
902 hstate->
slice = NULL;
904 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
909 if (consumed > 0 && consumed < input_len) {
913 }
else if (bstr_cmp_c_nocase(htp_header_value(h),
"WebSocket")) {
918 hstate->
slice = NULL;
920 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
925 if (consumed > 0 && consumed < input_len) {
935 HTPHandleError(hstate, STREAM_TOCLIENT);
941 htp_connp_close(hstate->
connp, &
ts);
946 hstate->
slice = NULL;
957 static int HTTPParseContentDispositionHeader(
const uint8_t *
name,
size_t name_len,
958 const uint8_t *data,
size_t len, uint8_t
const **retptr,
size_t *retlen)
961 printf(
"DATA START: \n");
963 printf(
"DATA END: \n");
968 for (x = 0; x <
len; x++) {
969 if (!(isspace(data[x])))
976 const uint8_t *line = data + x;
977 size_t line_len =
len-x;
980 printf(
"LINE START: \n");
982 printf(
"LINE END: \n");
984 for (x = 0 ; x < line_len; x++) {
986 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
990 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
991 const uint8_t *token = line +
offset;
992 size_t token_len = x -
offset;
994 if ((x + 1) == line_len) {
1005 printf(
"TOKEN START: \n");
1007 printf(
"TOKEN END: \n");
1009 if (token_len > name_len) {
1010 if (
name == NULL || SCMemcmpLowercase(
name, token, name_len) == 0) {
1011 const uint8_t *value = token + name_len;
1012 size_t value_len = token_len - name_len;
1014 if (value[0] ==
'\"') {
1018 if (value[value_len-1] ==
'\"') {
1022 printf(
"VALUE START: \n");
1024 printf(
"VALUE END: \n");
1027 *retlen = value_len;
1051 static int HtpRequestBodySetupMultipart(
const htp_tx_t *tx,
HtpTxUserData *htud)
1053 const htp_header_t *h = htp_tx_request_header(tx,
"Content-Type");
1054 if (h != NULL && htp_header_value_len(h) > 0) {
1056 SCMimeStateInit(htp_header_value_ptr(h), (uint32_t)htp_header_value_len(h));
1073 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1076 chunks_buffer, chunks_buffer_len,
1080 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1084 if (dir == STREAM_TOSERVER) {
1085 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1087 }
else if (dir == STREAM_TOCLIENT) {
1088 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1095 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len,
bool eof)
1098 printf(
"CHUNK START: \n");
1100 printf(
"CHUNK END: \n");
1106 STREAM_TOSERVER) >= HTP_REQUEST_PROGRESS_COMPLETE);
1108 const uint8_t *cur_buf = chunks_buffer;
1109 uint32_t cur_buf_len = chunks_buffer_len;
1125 const uint8_t *filename = NULL;
1126 uint16_t filename_len = 0;
1129 while (cur_buf_len > 0) {
1130 MimeParserResult r =
1131 SCMimeParse(htud->
mime_state, cur_buf, cur_buf_len, &consumed, &warnings);
1135 if (warnings & MIME_EVENT_FLAG_INVALID_HEADER) {
1139 if (warnings & MIME_EVENT_FLAG_NO_FILEDATA) {
1150 SCMimeStateGetFilename(htud->
mime_state, &filename, &filename_len);
1151 if (filename_len > 0) {
1155 hstate, htud, filename, filename_len, NULL, 0, STREAM_TOSERVER);
1158 }
else if (result == -2) {
1161 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1169 }
else if (result == -2) {
1177 uint32_t lastsize = consumed;
1178 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\n') {
1180 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\r') {
1184 HTPFileClose(htud, cur_buf, lastsize, 0, STREAM_TOSERVER);
1189 cur_buf += consumed;
1190 cur_buf_len -= consumed;
1202 const uint8_t *data, uint32_t data_len)
1209 uint8_t *filename = NULL;
1210 size_t filename_len = 0;
1213 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1214 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1215 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1218 if (filename != NULL) {
1224 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1228 }
else if (result == -2) {
1231 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1245 }
else if (result == -2) {
1258 const uint8_t *data, uint32_t data_len)
1275 const uint8_t *filename = NULL;
1276 size_t filename_len = 0;
1279 const htp_header_t *h = htp_tx_response_header(tx,
"Content-Disposition");
1280 if (h != NULL && htp_header_value_len(h) > 0) {
1282 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1283 htp_header_value_ptr(h), htp_header_value_len(h), &filename, &filename_len);
1287 if (filename == NULL) {
1289 if (htp_uri_path(htp_tx_parsed_uri(tx)) != NULL) {
1290 filename = (uint8_t *)bstr_ptr(htp_uri_path(htp_tx_parsed_uri(tx)));
1291 filename_len = bstr_len(htp_uri_path(htp_tx_parsed_uri(tx)));
1295 if (filename != NULL) {
1297 const htp_header_t *h_content_range = htp_tx_response_header(tx,
"content-range");
1303 if (h_content_range != NULL) {
1305 data_len, tx, htp_header_value(h_content_range), htud);
1307 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1313 }
else if (result == -2) {
1316 FlagDetectStateNewFile(htud, STREAM_TOCLIENT);
1329 }
else if (result == -2) {
1347 static int HTPCallbackRequestBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1351 const htp_tx_t *tx = htp_tx_data_tx(d);
1356 if (htp_tx_data_is_empty(d))
1360 printf(
"HTPBODY START: \n");
1361 PrintRawDataFp(stdout, (uint8_t *)htp_tx_data_data(d), htp_tx_data_len(d));
1362 printf(
"HTPBODY END: \n");
1365 HtpState *hstate = htp_connp_user_data(connp);
1366 if (hstate == NULL) {
1370 SCLogDebug(
"New request body data available at %p -> %p -> %p, bodylen "
1372 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1375 if (tx_ud == NULL) {
1384 if (htp_tx_request_method_number(tx) == HTP_METHOD_POST) {
1386 int r = HtpRequestBodySetupMultipart(tx, tx_ud);
1389 }
else if (r == 0) {
1393 }
else if (htp_tx_request_method_number(tx) == HTP_METHOD_PUT) {
1409 (uint32_t)htp_tx_data_len(d));
1414 const uint8_t *chunks_buffer = NULL;
1415 uint32_t chunks_buffer_len = 0;
1423 HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len);
1424 if (chunks_buffer == NULL) {
1428 printf(
"REASSCHUNK START: \n");
1430 printf(
"REASSCHUNK END: \n");
1433 HtpRequestBodyHandleMultipart(hstate, tx_ud, htp_tx_data_tx(d), chunks_buffer,
1434 chunks_buffer_len, (htp_tx_data_data(d) == NULL && htp_tx_data_len(d) == 0));
1438 HtpRequestBodyHandlePOSTorPUT(
1439 hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1444 SCLogDebug(
"closing file that was being stored");
1451 if (hstate->
conn != NULL) {
1452 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1453 ", last %" PRIu64
")",
1455 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1464 if ((uint64_t)htp_conn_request_data_counter(hstate->
conn) >
1466 (uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1468 (uint64_t)UINT_MAX) {
1469 uint32_t data_size =
1470 (uint32_t)((uint64_t)htp_conn_request_data_counter(hstate->
conn) -
1491 static int HTPCallbackResponseBodyData(
const htp_connp_t *connp, htp_tx_data_t *d)
1495 const htp_tx_t *tx = htp_tx_data_tx(d);
1500 if (htp_tx_data_is_empty(d))
1503 HtpState *hstate = htp_connp_user_data(connp);
1504 if (hstate == NULL) {
1508 SCLogDebug(
"New response body data available at %p -> %p -> %p, bodylen "
1510 hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
1530 (uint32_t)htp_tx_data_len(d));
1535 HtpResponseBodyHandle(hstate, tx_ud, htp_tx_data_tx(d), htp_tx_data_data(d),
len);
1538 SCLogDebug(
"closing file that was being stored");
1544 if (hstate->
conn != NULL) {
1545 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1546 ", last %" PRIu64
")",
1548 (uint64_t)htp_conn_request_data_counter(hstate->
conn),
1556 if ((uint64_t)htp_conn_response_data_counter(hstate->
conn) >
1558 (uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1560 (uint64_t)UINT_MAX) {
1561 uint32_t data_size =
1562 (uint32_t)((uint64_t)htp_conn_response_data_counter(hstate->
conn) -
1586 SCLogDebug(
"http_state_memcnt %"PRIu64
", http_state_memuse %"PRIu64
"",
1587 htp_state_memcnt, htp_state_memuse);
1604 htp_config_destroy(cfglist.
cfg);
1605 while (nextrec != NULL) {
1607 nextrec = nextrec->
next;
1609 htp_config_destroy(htprec->
cfg);
1617 static int HTPCallbackRequestHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1622 return HTP_STATUS_OK;
1625 static int HTPCallbackResponseHasTrailer(
const htp_connp_t *connp, htp_tx_t *tx)
1630 return HTP_STATUS_OK;
1633 static void *HTPCallbackTxCreate(
bool request)
1652 static int HTPCallbackRequestStart(
const htp_connp_t *connp, htp_tx_t *tx)
1654 HtpState *hstate = htp_connp_user_data(connp);
1655 if (hstate == NULL) {
1659 uint64_t consumed = hstate->
slice->
offset + htp_connp_request_data_consumed(hstate->
connp);
1660 SCLogDebug(
"HTTP request start: data offset %" PRIu64
", in_data_counter %" PRIu64, consumed,
1661 (uint64_t)htp_conn_request_data_counter(hstate->
conn));
1685 static int HTPCallbackResponseStart(
const htp_connp_t *connp, htp_tx_t *tx)
1687 HtpState *hstate = htp_connp_user_data(connp);
1688 if (hstate == NULL) {
1692 uint64_t consumed = hstate->
slice->
offset + htp_connp_response_data_consumed(hstate->
connp);
1693 SCLogDebug(
"HTTP response start: data offset %" PRIu64
", out_data_counter %" PRIu64, consumed,
1694 (uint64_t)htp_conn_response_data_counter(hstate->
conn));
1719 static int HTPCallbackRequestComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1727 HtpState *hstate = htp_connp_user_data(connp);
1728 if (hstate == NULL) {
1732 const uint64_t abs_right_edge =
1741 SCLogDebug(
"HTTP request complete: data offset %" PRIu64
", request_size %" PRIu64,
1743 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1745 frame->
len = (int64_t)request_size;
1751 SCLogDebug(
"transaction_cnt %"PRIu64
", list_size %"PRIu64,
1756 HTPErrorCheckTxRequestFlags(hstate, tx);
1761 SCLogDebug(
"closing file that was being stored");
1764 if (abs_right_edge < (uint64_t)UINT32_MAX) {
1766 hstate->
f->
protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
1783 static int HTPCallbackResponseComplete(
const htp_connp_t *connp, htp_tx_t *tx)
1787 HtpState *hstate = htp_connp_user_data(connp);
1788 if (hstate == NULL) {
1795 const uint64_t abs_right_edge =
1803 SCLogDebug(
"HTTP response complete: data offset %" PRIu64
", response_size %" PRIu64,
1805 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1807 frame->
len = (int64_t)response_size;
1815 SCLogDebug(
"closing file that was being stored");
1825 if (htp_tx_request_method_number(tx) == HTP_METHOD_CONNECT) {
1828 if ((htp_tx_response_status_number(tx) >= 200) &&
1829 (htp_tx_response_status_number(tx) < 300) && (hstate->
transaction_cnt == 1)) {
1831 if (htp_tx_request_port_number(tx) != -1) {
1832 dp = (uint16_t)htp_tx_request_port_number(tx);
1846 static int HTPCallbackRequestLine(
const htp_connp_t *connp, htp_tx_t *tx)
1848 HtpState *hstate = htp_connp_user_data(connp);
1850 if (htp_tx_flags(tx)) {
1851 HTPErrorCheckTxRequestFlags(hstate, tx);
1853 return HTP_STATUS_OK;
1856 static int HTPCallbackRequestHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1859 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1860 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1861 return HTP_STATUS_OK;
1867 return HTP_STATUS_OK;
1873 htp_tx_data_len(tx_data));
1876 if (tx && htp_tx_flags(tx)) {
1877 HtpState *hstate = htp_connp_user_data(connp);
1878 HTPErrorCheckTxRequestFlags(hstate, tx);
1880 return HTP_STATUS_OK;
1883 static int HTPCallbackResponseHeaderData(
const htp_connp_t *connp, htp_tx_data_t *tx_data)
1886 const htp_tx_t *tx = htp_tx_data_tx(tx_data);
1887 if (htp_tx_data_is_empty(tx_data) || tx == NULL)
1888 return HTP_STATUS_OK;
1895 return HTP_STATUS_OK;
1900 htp_tx_data_len(tx_data));
1903 return HTP_STATUS_OK;
1909 static void HTPConfigSetDefaultsPhase1(
HTPCfgRec *cfg_prec)
1911 htp_config_set_normalized_uri_include_all(cfg_prec->
cfg,
false);
1926 htp_config_register_request_header_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1927 htp_config_register_request_trailer_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
1928 htp_config_register_response_header_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1929 htp_config_register_response_trailer_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
1931 htp_config_register_request_trailer(cfg_prec->
cfg, HTPCallbackRequestHasTrailer);
1932 htp_config_register_response_trailer(cfg_prec->
cfg, HTPCallbackResponseHasTrailer);
1934 htp_config_register_request_body_data(cfg_prec->
cfg, HTPCallbackRequestBodyData);
1935 htp_config_register_response_body_data(cfg_prec->
cfg, HTPCallbackResponseBodyData);
1937 htp_config_register_tx_create(cfg_prec->
cfg, HTPCallbackTxCreate);
1938 htp_config_register_tx_destroy(cfg_prec->
cfg, HtpTxUserDataFree);
1940 htp_config_register_request_start(cfg_prec->
cfg, HTPCallbackRequestStart);
1941 htp_config_register_request_complete(cfg_prec->
cfg, HTPCallbackRequestComplete);
1943 htp_config_register_response_start(cfg_prec->
cfg, HTPCallbackResponseStart);
1944 htp_config_register_response_complete(cfg_prec->
cfg, HTPCallbackResponseComplete);
1946 htp_config_set_parse_request_cookies(cfg_prec->
cfg, 0);
1947 htp_config_set_allow_space_uri(cfg_prec->
cfg, 1);
1950 htp_config_set_plusspace_decode(cfg_prec->
cfg, 0);
1952 htp_config_set_request_decompression(cfg_prec->
cfg, 1);
1957 #define HTP_CONFIG_DEFAULT_MAX_TX_LIMIT 512
1959 #define HTP_CONFIG_DEFAULT_HEADERS_LIMIT 1024
1967 static int RandomGetWrap(
void)
1973 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
1975 return r % RAND_MAX;
1984 static void HTPConfigSetDefaultsPhase2(
const char *
name,
HTPCfgRec *cfg_prec)
1990 long int r = RandomGetWrap();
1992 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
1994 r = RandomGetWrap();
1996 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
1997 SCLogConfig(
"'%s' server has 'request-body-minimal-inspect-size' set to"
1998 " %u and 'request-body-inspect-window' set to %u after"
2002 r = RandomGetWrap();
2004 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2006 r = RandomGetWrap();
2008 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2010 SCLogConfig(
"'%s' server has 'response-body-minimal-inspect-size' set to"
2011 " %u and 'response-body-inspect-window' set to %u after"
2016 htp_config_register_request_line(cfg_prec->
cfg, HTPCallbackRequestLine);
2019 static void HTPConfigParseParameters(
HTPCfgRec *cfg_prec,
SCConfNode *s,
struct HTPConfigTree *tree)
2021 if (cfg_prec == NULL || s == NULL || tree == NULL)
2028 if (strcasecmp(
"address",
p->name) == 0) {
2034 if (strchr(pval->
val,
':') != NULL) {
2035 SCLogDebug(
"LIBHTP adding ipv6 server %s at %s: %p",
2039 SCLogWarning(
"LIBHTP failed to add ipv6 server %s, ignoring", pval->
val);
2042 SCLogDebug(
"LIBHTP adding ipv4 server %s at %s: %p",
2046 SCLogWarning(
"LIBHTP failed to add ipv4 server %s, ignoring", pval->
val);
2051 }
else if (strcasecmp(
"personality",
p->name) == 0) {
2053 int personality = HTPLookupPersonality(
p->val);
2054 SCLogDebug(
"LIBHTP default: %s = %s",
p->name,
p->val);
2055 SCLogDebug(
"LIBHTP default: %s = %s",
p->name,
p->val);
2057 if (personality >= 0) {
2058 SCLogDebug(
"LIBHTP default: %s=%s (%d)",
p->name,
p->val,
2060 if (htp_config_set_server_personality(cfg_prec->
cfg, personality) ==
2063 "personality \"%s\", ignoring",
2067 HTPLookupPersonalityString(personality));
2073 htp_config_set_convert_lowercase(cfg_prec->
cfg, 0);
2081 }
else if (strcasecmp(
"request-body-limit",
p->name) == 0 ||
2082 strcasecmp(
"request_body_limit",
p->name) == 0) {
2084 SCLogError(
"Error parsing request-body-limit "
2085 "from conf file - %s. Killing engine",
2090 }
else if (strcasecmp(
"response-body-limit",
p->name) == 0) {
2092 SCLogError(
"Error parsing response-body-limit "
2093 "from conf file - %s. Killing engine",
2098 }
else if (strcasecmp(
"request-body-minimal-inspect-size",
p->name) == 0) {
2100 SCLogError(
"Error parsing request-body-minimal-inspect-size "
2101 "from conf file - %s. Killing engine",
2106 }
else if (strcasecmp(
"request-body-inspect-window",
p->name) == 0) {
2108 SCLogError(
"Error parsing request-body-inspect-window "
2109 "from conf file - %s. Killing engine",
2114 }
else if (strcasecmp(
"double-decode-query",
p->name) == 0) {
2116 }
else if (strcasecmp(
"double-decode-path",
p->name) == 0) {
2118 }
else if (strcasecmp(
"response-body-minimal-inspect-size",
p->name) == 0) {
2120 SCLogError(
"Error parsing response-body-minimal-inspect-size "
2121 "from conf file - %s. Killing engine",
2126 }
else if (strcasecmp(
"response-body-inspect-window",
p->name) == 0) {
2128 SCLogError(
"Error parsing response-body-inspect-window "
2129 "from conf file - %s. Killing engine",
2134 }
else if (strcasecmp(
"response-body-decompress-layer-limit",
p->name) == 0) {
2137 SCLogError(
"Error parsing response-body-inspect-window "
2138 "from conf file - %s. Killing engine",
2142 htp_config_set_decompression_layer_limit(cfg_prec->
cfg, value);
2143 }
else if (strcasecmp(
"path-convert-backslash-separators",
p->name) == 0) {
2145 }
else if (strcasecmp(
"path-bestfit-replacement-char",
p->name) == 0) {
2146 if (strlen(
p->val) == 1) {
2147 htp_config_set_bestfit_replacement_byte(cfg_prec->
cfg,
p->val[0]);
2150 "for libhtp param path-bestfit-replacement-char");
2152 }
else if (strcasecmp(
"path-convert-lowercase",
p->name) == 0) {
2154 }
else if (strcasecmp(
"path-nul-encoded-terminates",
p->name) == 0) {
2156 }
else if (strcasecmp(
"path-nul-raw-terminates",
p->name) == 0) {
2158 }
else if (strcasecmp(
"path-separators-compress",
p->name) == 0) {
2160 }
else if (strcasecmp(
"path-separators-decode",
p->name) == 0) {
2162 }
else if (strcasecmp(
"path-u-encoding-decode",
p->name) == 0) {
2164 }
else if (strcasecmp(
"path-url-encoding-invalid-handling",
p->name) == 0) {
2165 enum htp_url_encoding_handling_t handling;
2166 if (strcasecmp(
p->val,
"preserve_percent") == 0) {
2167 handling = HTP_URL_ENCODING_HANDLING_PRESERVE_PERCENT;
2168 }
else if (strcasecmp(
p->val,
"remove_percent") == 0) {
2169 handling = HTP_URL_ENCODING_HANDLING_REMOVE_PERCENT;
2170 }
else if (strcasecmp(
p->val,
"decode_invalid") == 0) {
2171 handling = HTP_URL_ENCODING_HANDLING_PROCESS_INVALID;
2174 "for libhtp param path-url-encoding-invalid-handling");
2177 htp_config_set_url_encoding_invalid_handling(cfg_prec->
cfg, handling);
2178 }
else if (strcasecmp(
"path-utf8-convert-bestfit",
p->name) == 0) {
2180 }
else if (strcasecmp(
"uri-include-all",
p->name) == 0) {
2183 }
else if (strcasecmp(
"query-plusspace-decode",
p->name) == 0) {
2185 }
else if (strcasecmp(
"meta-field-limit",
p->name) == 0) {
2189 "from conf file - %s. Killing engine",
2195 "from conf file cannot be 0. Killing engine");
2198 htp_config_set_field_limit(cfg_prec->
cfg, (
size_t)limit);
2199 }
else if (strcasecmp(
"lzma-memlimit",
p->name) == 0) {
2202 FatalError(
"failed to parse 'lzma-memlimit' "
2203 "from conf file - %s.",
2208 "from conf file cannot be 0.");
2211 SCLogConfig(
"Setting HTTP LZMA memory limit to %"PRIu32
" bytes", limit);
2212 htp_config_set_lzma_memlimit(cfg_prec->
cfg, (
size_t)limit);
2213 }
else if (strcasecmp(
"lzma-enabled",
p->name) == 0) {
2215 htp_config_set_lzma_layers(cfg_prec->
cfg, 1);
2220 "from conf file - %s.",
2223 SCLogConfig(
"Setting HTTP LZMA decompression layers to %" PRIu32
"", (
int)limit);
2224 htp_config_set_lzma_layers(cfg_prec->
cfg, limit);
2226 }
else if (strcasecmp(
"compression-bomb-count",
p->name) == 0) {
2229 FatalError(
"failed to parse 'compression-bomb-count' "
2230 "from conf file - %s.",
2235 "from conf file cannot be 0.");
2238 SCLogConfig(
"Setting HTTP compression bomb count limit to %" PRIu8, limit);
2239 htp_config_set_max_nb_compression_bombs(cfg_prec->
cfg, (
size_t)limit);
2240 }
else if (strcasecmp(
"compression-bomb-limit",
p->name) == 0) {
2243 FatalError(
"failed to parse 'compression-bomb-limit' "
2244 "from conf file - %s.",
2249 "from conf file cannot be 0.");
2252 SCLogConfig(
"Setting HTTP compression bomb limit to %"PRIu32
" bytes", limit);
2253 htp_config_set_compression_bomb_limit(cfg_prec->
cfg, (
size_t)limit);
2254 }
else if (strcasecmp(
"decompression-time-limit",
p->name) == 0) {
2258 FatalError(
"failed to parse 'decompression-time-limit' "
2259 "from conf file - %s.",
2262 SCLogConfig(
"Setting HTTP decompression time limit to %" PRIu32
" usec", limit);
2263 htp_config_set_compression_time_limit(cfg_prec->
cfg, limit);
2264 }
else if (strcasecmp(
"max-tx",
p->name) == 0) {
2268 "from conf file - %s.",
2272 SCLogConfig(
"Setting HTTP max-tx limit to %" PRIu32
" bytes", limit);
2273 htp_config_set_max_tx(cfg_prec->
cfg, limit);
2274 }
else if (strcasecmp(
"headers-limit",
p->name) == 0) {
2277 FatalError(
"failed to parse 'headers-limit' "
2278 "from conf file - %s.",
2281 SCLogConfig(
"Setting HTTP headers limit to %" PRIu32, limit);
2282 htp_config_set_number_headers_limit(cfg_prec->
cfg, limit);
2283 }
else if (strcasecmp(
"randomize-inspection-sizes",
p->name) == 0) {
2287 }
else if (strcasecmp(
"randomize-inspection-range",
p->name) == 0) {
2290 (
const char *)
p->val, 0, 100) < 0) {
2292 "-inspection-range setting from conf file - \"%s\"."
2293 " It should be a valid integer less than or equal to 100."
2299 }
else if (strcasecmp(
"http-body-inline",
p->name) == 0) {
2305 if (strcmp(
"auto",
p->val) != 0) {
2314 }
else if (strcasecmp(
"swf-decompression",
p->name) == 0) {
2318 if (strcasecmp(
"enabled", pval->
name) == 0) {
2326 }
else if (strcasecmp(
"type", pval->
name) == 0) {
2327 if (strcasecmp(
"no", pval->
val) == 0) {
2329 }
else if (strcasecmp(
"deflate", pval->
val) == 0) {
2331 }
else if (strcasecmp(
"lzma", pval->
val) == 0) {
2333 }
else if (strcasecmp(
"both", pval->
val) == 0) {
2337 "swf-decompression.type: %s - "
2342 }
else if (strcasecmp(
"compress-depth", pval->
name) == 0) {
2344 SCLogError(
"Error parsing swf-decompression.compression-depth "
2345 "from conf file - %s. Killing engine",
2349 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2351 SCLogError(
"Error parsing swf-decompression.decompression-depth "
2352 "from conf file - %s. Killing engine",
2362 "default config: %s",
2372 cfglist.
next = NULL;
2379 cfglist.
cfg = htp_config_create();
2380 if (NULL == cfglist.
cfg) {
2381 FatalError(
"Failed to create HTP default config");
2384 HTPConfigSetDefaultsPhase1(&cfglist);
2385 if (
SCConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2386 HTPConfigParseParameters(&cfglist,
SCConfGetNode(
"libhtp.default-config"), &cfgtree);
2388 HTPConfigParseParameters(&cfglist,
2389 SCConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), &cfgtree);
2391 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2397 if (server_config == NULL) {
2399 if (server_config == NULL) {
2400 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2404 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2423 cfglist.
next = htprec;
2426 cfglist.
next->
cfg = htp_config_create();
2427 if (NULL == cfglist.
next->
cfg) {
2428 FatalError(
"Failed to create HTP server config");
2431 HTPConfigSetDefaultsPhase1(htprec);
2432 HTPConfigParseParameters(htprec, s, &cfgtree);
2433 HTPConfigSetDefaultsPhase2(s->
name, htprec);
2443 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
2457 htp_tx_t *tx = (htp_tx_t *)txv;
2459 if (direction & STREAM_TOCLIENT) {
2467 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
2469 if (direction & STREAM_TOSERVER)
2470 return htp_tx_request_progress((htp_tx_t *)tx);
2472 return htp_tx_response_progress((htp_tx_t *)tx);
2475 static uint64_t HTPStateGetTxCnt(
void *alstate)
2479 if (http_state != NULL && http_state->
connp != NULL) {
2480 const int64_t size = htp_connp_tx_size(http_state->
connp);
2484 return (uint64_t)size;
2490 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
2494 if (http_state != NULL && http_state->
connp != NULL)
2495 return (
void *)htp_connp_tx(http_state->
connp, tx_id);
2504 uint64_t size = HTPStateGetTxCnt(alstate);
2507 while (state->
un.
u64 < size) {
2508 htp_tx_t *tx = htp_connp_tx_index(http_state->
connp, state->
un.
u64);
2512 uint64_t tx_id = htp_tx_index(tx);
2513 if (tx_id < min_tx_id) {
2520 .has_next = (tx_id + 1) < size,
2532 if (http_state != NULL && http_state->
connp != NULL) {
2533 size_t txid = htp_connp_tx_size(http_state->
connp);
2535 return (
void *)htp_connp_tx(http_state->
connp, txid - 1);
2541 static int HTPStateGetEventInfo(
2551 static int HTPStateGetEventInfoById(
2555 if (*event_name == NULL) {
2557 "http's enum map table.",
2570 htp_tx_t *tx = (htp_tx_t *)vtx;
2581 static int HTPRegisterPatternsForProtocolDetection(
void)
2583 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
2584 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
2585 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
2586 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
2587 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
2588 const char *spacings[] = {
"|20|",
"|09|", NULL };
2589 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
2594 int register_result;
2595 char method_buffer[32] =
"";
2598 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
2599 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
2602 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
2609 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
2610 if (register_result < 0) {
2617 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
2619 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
2621 if (register_result < 0) {
2637 const char *proto_name =
"http";
2642 if (HTPRegisterPatternsForProtocolDetection() < 0)
2645 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
2660 ALPROTO_HTTP1, HTP_REQUEST_PROGRESS_COMPLETE, HTP_RESPONSE_PROGRESS_COMPLETE);
2672 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
2674 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
2678 IPPROTO_TCP,
ALPROTO_HTTP1, APP_LAYER_PARSER_OPT_ACCEPT_GAPS);
2680 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
2683 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
2686 IPPROTO_TCP,
ALPROTO_HTTP1, HtpStateGetStateIdByName, HtpStateGetStateNameById);
2690 SCLogInfo(
"Parser disabled for %s protocol. Protocol detection still on.", proto_name);
2706 cfglist_backup = cfglist;
2711 cfglist = cfglist_backup;
2716 static int HTPParserTest01(
void)
2718 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2720 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2723 memset(&ssn, 0,
sizeof(ssn));
2731 f->
proto = IPPROTO_TCP;
2737 for (u = 0; u < httplen1; u++) {
2741 flags = STREAM_TOSERVER|STREAM_START;
2742 else if (u == (httplen1 - 1))
2743 flags = STREAM_TOSERVER|STREAM_EOF;
2745 flags = STREAM_TOSERVER;
2754 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2757 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2760 FAIL_IF(bstr_cmp_c(htp_header_value(h),
"Victor/1.0"));
2761 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2762 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2771 static int HTPParserTest01b(
void)
2773 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2775 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2778 memset(&ssn, 0,
sizeof(ssn));
2786 f->
proto = IPPROTO_TCP;
2791 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
2798 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2801 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2804 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2805 FAIL_IF(strcmp(v,
"Victor/1.0"));
2807 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2808 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2817 static int HTPParserTest01c(
void)
2819 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2821 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2824 memset(&ssn, 0,
sizeof(ssn));
2832 f->
proto = IPPROTO_TCP;
2838 for (u = 0; u < httplen1; u++) {
2842 flags = STREAM_TOSERVER|STREAM_START;
2843 else if (u == (httplen1 - 1))
2844 flags = STREAM_TOSERVER|STREAM_EOF;
2846 flags = STREAM_TOSERVER;
2855 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2858 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2861 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2862 FAIL_IF(strcmp(v,
"Victor/1.0"));
2864 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2865 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2875 static int HTPParserTest01a(
void)
2878 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2880 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2885 memset(&ssn, 0,
sizeof(ssn));
2887 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2890 f->
proto = IPPROTO_TCP;
2896 for (u = 0; u < httplen1; u++) {
2900 flags = STREAM_TOSERVER|STREAM_START;
2901 else if (u == (httplen1 - 1))
2902 flags = STREAM_TOSERVER|STREAM_EOF;
2904 flags = STREAM_TOSERVER;
2913 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2916 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2919 char *v = bstr_util_strdup_to_c(htp_header_value(h));
2920 FAIL_IF(strcmp(v,
"Victor/1.0"));
2922 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_POST);
2923 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
2932 static int HTPParserTest02(
void)
2935 uint8_t httpbuf1[] =
"POST";
2936 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2941 memset(&ssn, 0,
sizeof(ssn));
2943 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2946 f->
proto = IPPROTO_TCP;
2952 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
2958 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
2960 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
2964 char *method = bstr_util_strdup_to_c(htp_tx_request_method(tx));
2967 FAIL_IF(strcmp(method,
"POST") != 0);
2978 static int HTPParserTest03(
void)
2981 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
2982 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2987 memset(&ssn, 0,
sizeof(ssn));
2989 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
2992 f->
proto = IPPROTO_TCP;
2998 for (u = 0; u < httplen1; u++) {
3001 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3002 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3003 else flags = STREAM_TOSERVER;
3011 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3014 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3016 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3017 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_0);
3027 static int HTPParserTest04(
void)
3031 uint8_t httpbuf1[] =
"World!\r\n";
3032 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3036 memset(&ssn, 0,
sizeof(ssn));
3038 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3041 f->
proto = IPPROTO_TCP;
3047 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3053 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3055 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3057 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_UNKNOWN);
3058 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V0_9);
3068 static int HTPParserTest05(
void)
3070 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3071 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3072 uint8_t httpbuf2[] =
"Post D";
3073 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3074 uint8_t httpbuf3[] =
"ata is c0oL!";
3075 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3077 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3078 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3079 uint8_t httpbuf5[] =
"post R";
3080 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3081 uint8_t httpbuf6[] =
"esults are tha bomb!";
3082 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3085 memset(&ssn, 0,
sizeof(ssn));
3093 f->
proto = IPPROTO_TCP;
3123 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3125 FAIL_IF_NOT(htp_tx_request_method_number(tx) == HTP_METHOD_POST);
3126 FAIL_IF_NOT(htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_V1_0);
3128 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3131 FAIL_IF_NOT(htp_tx_response_status_number(tx) == 200);
3141 static int HTPParserTest06(
void)
3143 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3144 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3145 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3146 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3147 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3149 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3150 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3151 "FrontPage/5.0.2.2510\r\n"
3152 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3154 "Content-Type: text/html\r\n\r\n"
3156 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3157 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3158 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3159 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3160 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3161 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3162 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3163 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3164 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3165 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3166 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3167 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3168 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3169 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3170 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3171 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3172 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3173 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3174 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3175 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3176 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3177 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3178 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3179 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3180 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3181 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3182 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3183 "aHA=\r\n0\r\n\r\n";
3184 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3190 memset(&ssn, 0,
sizeof(ssn));
3195 f->
proto = IPPROTO_TCP;
3210 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3213 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
3214 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3216 FAIL_IF(htp_tx_response_status_number(tx) != 200);
3217 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
3219 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3230 static int HTPParserTest07(
void)
3233 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3234 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3239 memset(&ssn, 0,
sizeof(ssn));
3241 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3244 f->
proto = IPPROTO_TCP;
3250 for (u = 0; u < httplen1; u++) {
3254 flags = STREAM_TOSERVER|STREAM_START;
3255 else if (u == (httplen1 - 1))
3256 flags = STREAM_TOSERVER|STREAM_EOF;
3258 flags = STREAM_TOSERVER;
3267 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3268 size_t reflen =
sizeof(ref) - 1;
3270 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3272 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3274 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3276 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref, bstr_len(request_uri_normalized)) != 0);
3288 static int HTPParserTest08(
void)
3291 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3292 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3313 memset(&ssn, 0,
sizeof(ssn));
3315 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3318 f->
proto = IPPROTO_TCP;
3323 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3331 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3333 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3335 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3349 static int HTPParserTest09(
void)
3352 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3353 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3363 personality: Apache_2_2\n\
3375 memset(&ssn, 0,
sizeof(ssn));
3377 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3380 f->
proto = IPPROTO_TCP;
3385 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3393 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3395 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3397 PrintRawDataFp(stdout, bstr_ptr(request_uri_normalized), bstr_len(request_uri_normalized));
3411 static int HTPParserTest10(
void)
3415 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3416 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3421 memset(&ssn, 0,
sizeof(ssn));
3423 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3426 f->
proto = IPPROTO_TCP;
3432 for (u = 0; u < httplen1; u++) {
3436 flags = STREAM_TOSERVER|STREAM_START;
3437 else if (u == (httplen1 - 1))
3438 flags = STREAM_TOSERVER|STREAM_EOF;
3440 flags = STREAM_TOSERVER;
3449 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3450 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3453 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3457 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3459 FAIL_IF(strcmp(value,
"www.google.com") != 0);
3471 static int HTPParserTest11(
void)
3474 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3475 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3480 memset(&ssn, 0,
sizeof(ssn));
3482 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3485 f->
proto = IPPROTO_TCP;
3491 for (u = 0; u < httplen1; u++) {
3495 flags = STREAM_TOSERVER|STREAM_START;
3496 else if (u == (httplen1 - 1))
3497 flags = STREAM_TOSERVER|STREAM_EOF;
3499 flags = STREAM_TOSERVER;
3508 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3510 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3513 FAIL_IF(bstr_len(request_uri_normalized) != 4);
3514 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3515 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'%');
3516 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'0');
3517 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'0');
3527 static int HTPParserTest12(
void)
3530 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3531 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3536 memset(&ssn, 0,
sizeof(ssn));
3538 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3541 f->
proto = IPPROTO_TCP;
3547 for (u = 0; u < httplen1; u++) {
3551 flags = STREAM_TOSERVER|STREAM_START;
3552 else if (u == (httplen1 - 1))
3553 flags = STREAM_TOSERVER|STREAM_EOF;
3555 flags = STREAM_TOSERVER;
3564 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3566 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3569 FAIL_IF(bstr_len(request_uri_normalized) != 7);
3570 FAIL_IF(bstr_ptr(request_uri_normalized)[0] !=
'/');
3571 FAIL_IF(bstr_ptr(request_uri_normalized)[1] !=
'?');
3572 FAIL_IF(bstr_ptr(request_uri_normalized)[2] !=
'a');
3573 FAIL_IF(bstr_ptr(request_uri_normalized)[3] !=
'=');
3574 FAIL_IF(bstr_ptr(request_uri_normalized)[4] !=
'%');
3575 FAIL_IF(bstr_ptr(request_uri_normalized)[5] !=
'0');
3576 FAIL_IF(bstr_ptr(request_uri_normalized)[6] !=
'0');
3586 static int HTPParserTest13(
void)
3589 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3590 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3595 memset(&ssn, 0,
sizeof(ssn));
3597 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3600 f->
proto = IPPROTO_TCP;
3606 for (u = 0; u < httplen1; u++) {
3610 flags = STREAM_TOSERVER|STREAM_START;
3611 else if (u == (httplen1 - 1))
3612 flags = STREAM_TOSERVER|STREAM_EOF;
3614 flags = STREAM_TOSERVER;
3622 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3623 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
3626 char *
name = bstr_util_strdup_to_c(htp_header_name(h));
3630 char *value = bstr_util_strdup_to_c(htp_header_value(h));
3632 FAIL_IF(strcmp(value,
"www.google.com\rName: Value") != 0);
3644 static int HTPParserConfigTest01(
void)
3657 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3658 personality: Tomcat_6_0\n\
3663 - 192.168.10.0/24\n\
3664 personality: IIS_7_0\n\
3673 outputs =
SCConfGetNode(
"libhtp.default-config.personality");
3684 FAIL_IF(strcmp(node->
name,
"apache-tomcat") != 0);
3691 FAIL_IF(strcmp(node2->
val,
"Tomcat_6_0") != 0);
3701 FAIL_IF(strcmp(n->
val,
"192.168.1.0/24") != 0);
3741 FAIL_IF(strcmp(n->
val,
"192.168.0.0/24") != 0);
3745 FAIL_IF(strcmp(n->
val,
"192.168.10.0/24") != 0);
3760 static int HTPParserConfigTest02(
void)
3773 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3774 personality: Tomcat_6_0\n\
3779 - 192.168.10.0/24\n\
3780 personality: IIS_7_0\n\
3792 htp_cfg_t *htp = cfglist.
cfg;
3795 void *user_data = NULL;
3797 addr =
"192.168.10.42";
3798 FAIL_IF(inet_pton(AF_INET, addr, buf) != 1);
3802 htp = htp_cfg_rec->
cfg;
3808 FAIL_IF(inet_pton(AF_INET6, addr, buf) != 1);
3811 htp_cfg_rec = user_data;
3812 htp = htp_cfg_rec->
cfg;
3825 static int HTPParserConfigTest03(
void)
3828 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3830 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3846 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3847 personality: Tomcat_6_0\n\
3852 - 192.168.10.0/24\n\
3853 personality: IIS_7_0\n\
3864 const char *addr =
"192.168.10.42";
3866 memset(&ssn, 0,
sizeof(ssn));
3871 f->
proto = IPPROTO_TCP;
3874 htp_cfg_t *htp = cfglist.
cfg;
3877 void *user_data = NULL;
3882 htp = htp_cfg_rec->
cfg;
3889 for (u = 0; u < httplen1; u++) {
3892 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3893 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3894 else flags = STREAM_TOSERVER;
3903 FAIL_IF(HTPStateGetTxCnt(htp_state) != 2);
3905 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3907 tx = HTPStateGetTx(htp_state, 1);
3926 static int HTPParserDecodingTest01(
void)
3928 uint8_t httpbuf1[] =
3929 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3930 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
3931 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
3932 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3943 personality: Apache_2\n\
3951 const char *addr =
"4.3.2.1";
3952 memset(&ssn, 0,
sizeof(ssn));
3957 f->
proto = IPPROTO_TCP;
3962 for (uint32_t u = 0; u < httplen1; u++) {
3964 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3965 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3966 else flags = STREAM_TOSERVER;
3975 uint8_t ref1[] =
"/abc%2fdef";
3976 size_t reflen =
sizeof(ref1) - 1;
3978 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3982 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3985 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3986 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
3988 uint8_t ref2[] =
"/abc/def?ghi/jkl";
3989 reflen =
sizeof(ref2) - 1;
3991 tx = HTPStateGetTx(htp_state, 1);
3995 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
3998 FAIL_IF(reflen != bstr_len(request_uri_normalized));
3999 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4001 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4002 reflen =
sizeof(ref3) - 1;
4003 tx = HTPStateGetTx(htp_state, 2);
4007 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4010 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4011 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4023 static int HTPParserDecodingTest01a(
void)
4025 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4026 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4027 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4028 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4039 personality: Apache_2\n\
4047 const char *addr =
"4.3.2.1";
4048 memset(&ssn, 0,
sizeof(ssn));
4053 f->
proto = IPPROTO_TCP;
4059 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4065 uint8_t ref1[] =
"/abc%2fdef";
4066 size_t reflen =
sizeof(ref1) - 1;
4068 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4072 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4075 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4076 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4078 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4079 reflen =
sizeof(ref2) - 1;
4081 tx = HTPStateGetTx(htp_state, 1);
4084 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4087 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4089 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4091 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4092 reflen =
sizeof(ref3) - 1;
4093 tx = HTPStateGetTx(htp_state, 2);
4096 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4099 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4101 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4119 static int HTPParserDecodingTest02(
void)
4122 uint8_t httpbuf1[] =
4123 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4124 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4125 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4126 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4138 double-decode-path: no\n\
4139 double-decode-query: no\n\
4147 const char *addr =
"4.3.2.1";
4148 memset(&ssn, 0,
sizeof(ssn));
4153 f->
proto = IPPROTO_TCP;
4159 for (u = 0; u < httplen1; u++) {
4162 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4163 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4164 else flags = STREAM_TOSERVER;
4173 uint8_t ref1[] =
"/abc/def";
4174 size_t reflen =
sizeof(ref1) - 1;
4176 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4178 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4180 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4181 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4183 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4184 reflen =
sizeof(ref2) - 1;
4186 tx = HTPStateGetTx(htp_state, 1);
4188 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4190 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4192 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4194 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4195 reflen =
sizeof(ref3) - 1;
4196 tx = HTPStateGetTx(htp_state, 2);
4198 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4200 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4202 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref3, bstr_len(request_uri_normalized)) != 0);
4219 static int HTPParserDecodingTest03(
void)
4222 uint8_t httpbuf1[] =
4223 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4224 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4225 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4237 double-decode-path: yes\n\
4238 double-decode-query: yes\n\
4246 const char *addr =
"4.3.2.1";
4247 memset(&ssn, 0,
sizeof(ssn));
4252 f->
proto = IPPROTO_TCP;
4258 for (u = 0; u < httplen1; u++) {
4261 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4262 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4263 else flags = STREAM_TOSERVER;
4272 uint8_t ref1[] =
"/abc/def";
4273 size_t reflen =
sizeof(ref1) - 1;
4275 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4277 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4279 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4281 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4283 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4284 reflen =
sizeof(ref2) - 1;
4286 tx = HTPStateGetTx(htp_state, 1);
4288 request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4290 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4292 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref2, bstr_len(request_uri_normalized)) != 0);
4306 static int HTPParserDecodingTest04(
void)
4309 uint8_t httpbuf1[] =
4310 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4311 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4323 double-decode-path: yes\n\
4324 double-decode-query: yes\n\
4332 const char *addr =
"4.3.2.1";
4333 memset(&ssn, 0,
sizeof(ssn));
4338 f->
proto = IPPROTO_TCP;
4344 for (u = 0; u < httplen1; u++) {
4347 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4348 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4349 else flags = STREAM_TOSERVER;
4358 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
4359 size_t reflen =
sizeof(ref1) - 1;
4361 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4363 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4365 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4367 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4381 static int HTPParserDecodingTest05(
void)
4384 uint8_t httpbuf1[] =
4385 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4386 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4398 double-decode-path: yes\n\
4399 double-decode-query: yes\n\
4407 const char *addr =
"4.3.2.1";
4408 memset(&ssn, 0,
sizeof(ssn));
4413 f->
proto = IPPROTO_TCP;
4419 for (u = 0; u < httplen1; u++) {
4422 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4423 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4424 else flags = STREAM_TOSERVER;
4433 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
4434 size_t reflen =
sizeof(ref1) - 1;
4436 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4438 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4440 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4442 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4456 static int HTPParserDecodingTest06(
void)
4459 uint8_t httpbuf1[] =
4460 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4461 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4473 double-decode-path: yes\n\
4474 double-decode-query: yes\n\
4482 const char *addr =
"4.3.2.1";
4483 memset(&ssn, 0,
sizeof(ssn));
4488 f->
proto = IPPROTO_TCP;
4494 for (u = 0; u < httplen1; u++) {
4497 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4498 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4499 else flags = STREAM_TOSERVER;
4508 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
4509 size_t reflen =
sizeof(ref1) - 1;
4511 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4513 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4515 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4517 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4531 static int HTPParserDecodingTest07(
void)
4534 uint8_t httpbuf1[] =
4535 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4536 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4548 double-decode-path: yes\n\
4549 double-decode-query: yes\n\
4550 query-plusspace-decode: yes\n\
4558 const char *addr =
"4.3.2.1";
4559 memset(&ssn, 0,
sizeof(ssn));
4564 f->
proto = IPPROTO_TCP;
4570 for (u = 0; u < httplen1; u++) {
4573 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4574 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4575 else flags = STREAM_TOSERVER;
4584 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
4585 size_t reflen =
sizeof(ref1) - 1;
4587 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4589 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4591 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4593 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4607 static int HTPParserDecodingTest08(
void)
4610 uint8_t httpbuf1[] =
4611 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4612 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4631 const char *addr =
"4.3.2.1";
4632 memset(&ssn, 0,
sizeof(ssn));
4637 f->
proto = IPPROTO_TCP;
4643 for (u = 0; u < httplen1; u++) {
4646 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4647 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4648 else flags = STREAM_TOSERVER;
4657 uint8_t ref1[] =
"/blah/";
4658 size_t reflen =
sizeof(ref1) - 1;
4660 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4662 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4664 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4666 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4680 static int HTPParserDecodingTest09(
void)
4683 uint8_t httpbuf1[] =
4684 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4685 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4697 uri-include-all: true\n\
4705 const char *addr =
"4.3.2.1";
4706 memset(&ssn, 0,
sizeof(ssn));
4711 f->
proto = IPPROTO_TCP;
4717 for (u = 0; u < httplen1; u++) {
4720 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4721 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4722 else flags = STREAM_TOSERVER;
4731 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
4732 size_t reflen =
sizeof(ref1) - 1;
4734 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4736 bstr *request_uri_normalized = (bstr *)htp_tx_normalized_uri(tx);
4738 FAIL_IF(reflen != bstr_len(request_uri_normalized));
4740 FAIL_IF(memcmp(bstr_ptr(request_uri_normalized), ref1, bstr_len(request_uri_normalized)) != 0);
4753 static int HTPBodyReassemblyTest01(
void)
4758 memset(&hstate, 0x00,
sizeof(hstate));
4760 memset(&flow, 0x00,
sizeof(flow));
4762 htp_cfg_t *cfg = htp_config_create();
4764 htp_connp_t *connp = htp_connp_create(cfg);
4766 const htp_tx_t *tx = htp_connp_get_request_tx(connp);
4772 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
4773 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";
4780 const uint8_t *chunks_buffer = NULL;
4781 uint32_t chunks_buffer_len = 0;
4783 HtpRequestBodyReassemble(htud, &chunks_buffer, &chunks_buffer_len);
4786 printf(
"REASSCHUNK START: \n");
4788 printf(
"REASSCHUNK END: \n");
4791 htud->
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
4792 strlen(
"multipart/form-data; boundary=toto"));
4795 HtpRequestBodyHandleMultipart(&hstate, htud, &tx, chunks_buffer, chunks_buffer_len,
false);
4801 htp_connp_destroy_all(connp);
4802 HtpTxUserDataFree(htud);
4804 htp_config_destroy(cfg);
4809 static int HTPSegvTest01(
void)
4812 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";
4813 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4821 double-decode-path: no\n\
4822 double-decode-query: no\n\
4823 request-body-limit: 0\n\
4824 response-body-limit: 0\n\
4837 memset(&ssn, 0,
sizeof(ssn));
4839 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4842 f->
proto = IPPROTO_TCP;
4847 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
4851 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
4872 static int HTPParserTest14(
void)
4883 double-decode-path: no\n\
4884 double-decode-query: no\n\
4885 request-body-limit: 0\n\
4886 response-body-limit: 0\n\
4891 memset(&ssn, 0,
sizeof(ssn));
4901 memset(httpbuf, 0x00,
len);
4904 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
4905 "Host: myhost.lan\r\n"
4906 "Connection: keep-alive\r\n"
4908 "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"
4909 "Referer: http://blah.lan/\r\n"
4910 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
4912 size_t o = strlen(httpbuf);
4913 for ( ; o <
len - 4; o++) {
4916 httpbuf[
len - 4] =
'\r';
4917 httpbuf[
len - 3] =
'\n';
4918 httpbuf[
len - 2] =
'\r';
4919 httpbuf[
len - 1] =
'\n';
4925 f->
proto = IPPROTO_TCP;
4930 for (u = 0; u <
len; u++) {
4933 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4934 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4935 else flags = STREAM_TOSERVER;
4943 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4945 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
4946 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
4953 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_REQUEST_FIELD_TOO_LONG);
4968 static int HTPParserTest15(
void)
4971 char *httpbuf = NULL;
4982 double-decode-path: no\n\
4983 double-decode-query: no\n\
4984 request-body-limit: 0\n\
4985 response-body-limit: 0\n\
4986 meta-field-limit: 20000\n\
4990 memset(&ssn, 0,
sizeof(ssn));
5001 memset(httpbuf, 0x00,
len);
5004 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5005 "Host: myhost.lan\r\n"
5006 "Connection: keep-alive\r\n"
5008 "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"
5009 "Referer: http://blah.lan/\r\n"
5010 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5012 size_t o = strlen(httpbuf);
5013 for ( ; o <
len - 4; o++) {
5016 httpbuf[
len - 4] =
'\r';
5017 httpbuf[
len - 3] =
'\n';
5018 httpbuf[
len - 2] =
'\r';
5019 httpbuf[
len - 1] =
'\n';
5021 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5024 f->
proto = IPPROTO_TCP;
5030 for (u = 0; u <
len; u++) {
5033 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5034 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5035 else flags = STREAM_TOSERVER;
5044 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5046 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5047 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5066 static int HTPParserTest16(
void)
5073 memset(&ssn, 0,
sizeof(ssn));
5075 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5076 "Host: myhost.lan\r\n"
5077 "Connection: keep-alive\r\n"
5079 "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"
5080 "Referer: http://blah.lan/\r\n"
5081 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5082 "Cookie: blah\r\n\r\n";
5083 size_t len =
sizeof(httpbuf) - 1;
5085 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5088 f->
proto = IPPROTO_TCP;
5093 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5101 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5103 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5104 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5106 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5113 FAIL_IF(decoder_events->
events[0] != HTP_LOG_CODE_METHOD_DELIM_NON_COMPLIANT);
5114 FAIL_IF(decoder_events->
events[1] != HTP_LOG_CODE_URI_DELIM_NON_COMPLIANT);
5125 static int HTPParserTest20(
void)
5128 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5129 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5130 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5131 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5132 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
5133 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5134 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5135 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5141 memset(&ssn, 0,
sizeof(ssn));
5143 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5146 f->
proto = IPPROTO_TCP;
5165 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5167 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5170 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5171 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5173 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5174 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5184 static int HTPParserTest21(
void)
5187 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5188 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5189 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5190 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5191 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
5192 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5193 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5194 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5200 memset(&ssn, 0,
sizeof(ssn));
5202 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5205 f->
proto = IPPROTO_TCP;
5224 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5226 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5229 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5230 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5232 FAIL_IF(htp_tx_response_status_number(tx) != 0);
5233 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5243 static int HTPParserTest22(
void)
5246 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5247 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5248 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5249 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5250 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
5251 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5252 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5258 memset(&ssn, 0,
sizeof(ssn));
5260 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5263 f->
proto = IPPROTO_TCP;
5278 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5280 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5283 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5284 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5286 FAIL_IF(htp_tx_response_status_number(tx) != -0);
5287 FAIL_IF(htp_tx_response_protocol_number(tx) != -1);
5297 static int HTPParserTest23(
void)
5300 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5301 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5302 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5303 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5304 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
5305 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5306 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5312 memset(&ssn, 0,
sizeof(ssn));
5314 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5317 f->
proto = IPPROTO_TCP;
5332 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5334 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5337 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5338 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5340 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5341 FAIL_IF(htp_tx_response_protocol_number(tx) != -2);
5352 static int HTPParserTest24(
void)
5355 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5356 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5357 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5358 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5359 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
5360 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5361 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5367 memset(&ssn, 0,
sizeof(ssn));
5369 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5372 f->
proto = IPPROTO_TCP;
5387 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5389 const htp_header_t *h = htp_tx_request_header_index(tx, 0);
5392 FAIL_IF(htp_tx_request_method_number(tx) != HTP_METHOD_GET);
5393 FAIL_IF(htp_tx_request_protocol_number(tx) != HTP_PROTOCOL_V1_1);
5395 FAIL_IF(htp_tx_response_status_number(tx) != -1);
5396 FAIL_IF(htp_tx_response_protocol_number(tx) != HTP_PROTOCOL_V1_0);
5406 static int HTPParserTest25(
void)
5413 memset(&ssn, 0,
sizeof(ssn));
5418 f->
proto = IPPROTO_TCP;
5422 const char *
str =
"GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
5424 (uint8_t *)
str, strlen(
str));
5448 str =
"HTTP 1.1 200 OK\r\nServer: Suricata/1.0\r\nContent-Length: 8\r\n\r\nSuricata";
5450 (uint8_t *)
str, strlen(
str));
5484 (uint8_t *)
str, strlen(
str));
5495 (uint8_t *)
str, strlen(
str));
5516 static int HTPParserTest26(
void)
5525 request-body-limit: 1\n\
5526 response-body-limit: 1\n\
5540 uint8_t httpbuf1[] =
"GET /alice.txt HTTP/1.1\r\n\r\n";
5541 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5542 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\n"
5543 "Content-Type: text/plain\r\n"
5544 "Content-Length: 228\r\n\r\n"
5545 "Alice was beginning to get very tired of sitting by her sister on the bank."
5546 "Alice was beginning to get very tired of sitting by her sister on the bank.";
5547 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5548 uint8_t httpbuf3[] =
"Alice was beginning to get very tired of sitting by her sister on the bank.\r\n\r\n";
5549 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5557 memset(&f, 0,
sizeof(f));
5558 memset(&ssn, 0,
sizeof(ssn));
5565 f.
proto = IPPROTO_TCP;
5586 "(filestore; sid:1; rev:1;)");
5655 static int HTPParserTest27(
void)
5658 memset(&cfg, 0,
sizeof(cfg));
5662 uint32_t
len = 1000;
5687 static void HTPParserRegisterTests(
void)
5709 UtRegisterTest(
"HTPParserDecodingTest01", HTPParserDecodingTest01);
5710 UtRegisterTest(
"HTPParserDecodingTest01a", HTPParserDecodingTest01a);
5711 UtRegisterTest(
"HTPParserDecodingTest02", HTPParserDecodingTest02);
5712 UtRegisterTest(
"HTPParserDecodingTest03", HTPParserDecodingTest03);
5713 UtRegisterTest(
"HTPParserDecodingTest04", HTPParserDecodingTest04);
5714 UtRegisterTest(
"HTPParserDecodingTest05", HTPParserDecodingTest05);
5715 UtRegisterTest(
"HTPParserDecodingTest06", HTPParserDecodingTest06);
5716 UtRegisterTest(
"HTPParserDecodingTest07", HTPParserDecodingTest07);
5717 UtRegisterTest(
"HTPParserDecodingTest08", HTPParserDecodingTest08);
5718 UtRegisterTest(
"HTPParserDecodingTest09", HTPParserDecodingTest09);
5720 UtRegisterTest(
"HTPBodyReassemblyTest01", HTPBodyReassemblyTest01);