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;
112 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST",
114 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE",
116 {
"INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST",
118 {
"INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE",
120 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST",
122 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE",
198 static int HTTPGetFrameIdByName(
const char *frame_name)
207 static const char *HTTPGetFrameNameById(
const uint8_t frame_id)
213 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id);
214 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction);
215 static uint64_t HTPStateGetTxCnt(
void *alstate);
217 static void HTPParserRegisterTests(
void);
220 static inline uint64_t HtpGetActiveRequestTxID(
HtpState *s)
222 uint64_t
id = HTPStateGetTxCnt(s);
227 static inline uint64_t HtpGetActiveResponseTxID(
HtpState *s)
240 static const char *HTPLookupPersonalityString(
int p)
242 #define CASE_HTP_PERSONALITY_STRING(p) \
243 case HTP_SERVER_PERSONALITY_##p: \
247 CASE_HTP_PERSONALITY_STRING(MINIMAL);
248 CASE_HTP_PERSONALITY_STRING(GENERIC);
249 CASE_HTP_PERSONALITY_STRING(IDS);
250 CASE_HTP_PERSONALITY_STRING(IIS_4_0);
251 CASE_HTP_PERSONALITY_STRING(IIS_5_0);
252 CASE_HTP_PERSONALITY_STRING(IIS_5_1);
253 CASE_HTP_PERSONALITY_STRING(IIS_6_0);
254 CASE_HTP_PERSONALITY_STRING(IIS_7_0);
255 CASE_HTP_PERSONALITY_STRING(IIS_7_5);
256 CASE_HTP_PERSONALITY_STRING(APACHE_2);
270 static int HTPLookupPersonality(
const char *
str)
272 #define IF_HTP_PERSONALITY_NUM(p) \
273 if (strcasecmp(#p, str) == 0) \
274 return HTP_SERVER_PERSONALITY_##p
286 if (strcasecmp(
"TOMCAT_6_0",
str) == 0) {
288 "longer supported by libhtp.",
291 }
else if ((strcasecmp(
"APACHE",
str) == 0) ||
292 (strcasecmp(
"APACHE_2_2",
str) == 0))
295 "longer supported by libhtp, failing back to "
296 "Apache2 personality.",
305 const uint8_t dir,
const uint8_t e)
315 const uint64_t tx_id = (dir == STREAM_TOSERVER) ?
316 HtpGetActiveRequestTxID(s) : HtpGetActiveResponseTxID(s);
318 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
319 if (tx == NULL && tx_id > 0)
320 tx = HTPStateGetTx(s, tx_id - 1);
335 static void *HTPStateAlloc(
void *orig_state,
AppProto proto_orig)
349 htp_state_memuse +=
sizeof(
HtpState);
350 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
370 if (htud->
tx_data.de_state != NULL) {
396 if (s->
connp != NULL) {
400 uint64_t total_txs = HTPStateGetTxCnt(state);
402 if (s->
conn != NULL) {
403 for (tx_id = s->
tx_freed; tx_id < total_txs; tx_id++) {
404 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
407 HtpTxUserDataFree(s, htud);
408 htp_tx_set_user_data(tx, NULL);
412 htp_connp_destroy_all(s->
connp);
420 htp_state_memuse -=
sizeof(
HtpState);
421 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
434 static void HTPStateTransactionFree(
void *state, uint64_t
id)
442 htp_tx_t *tx = HTPStateGetTx(s,
id);
446 HtpTxUserDataFree(s, htud);
447 htp_tx_set_user_data(tx, NULL);
506 static void AppLayerHtpSetStreamDepthFlag(
void *tx,
const uint8_t
flags)
511 if (
flags & STREAM_TOCLIENT) {
521 SCLogDebug(
"cfg->body_limit %u stream_depth %u body->content_len_so_far %" PRIu64,
538 static uint32_t AppLayerHtpComputeChunkLength(uint64_t content_len_so_far, uint32_t body_limit,
539 uint32_t stream_depth, uint8_t
flags, uint32_t data_len)
541 uint32_t chunk_len = 0;
543 (content_len_so_far < (uint64_t)body_limit) &&
544 (content_len_so_far + (uint64_t)data_len) > body_limit)
546 chunk_len = (uint32_t)(body_limit - content_len_so_far);
548 (content_len_so_far < (uint64_t)stream_depth) &&
549 (content_len_so_far + (uint64_t)data_len) > stream_depth)
551 chunk_len = (uint32_t)(stream_depth - content_len_so_far);
554 return (chunk_len == 0 ? data_len : chunk_len);
582 {
"C-T multipart/byteranges in responses not supported",
609 {
"Request line: non-compliant delimiter between Method and URI",
618 {
"Transfer-encoding has abnormal chunked value",
620 {
"Chunked transfer-encoding on HTTP/0.9 or HTTP/1.0",
635 #define HTP_ERROR_MAX (sizeof(htp_errors) / sizeof(htp_errors[0]))
636 #define HTP_WARNING_MAX (sizeof(htp_warnings) / sizeof(htp_warnings[0]))
647 static uint8_t HTPHandleWarningGetId(
const char *
msg)
671 static uint8_t HTPHandleErrorGetId(
const char *
msg)
695 static void HTPHandleError(
HtpState *s,
const uint8_t dir)
697 if (s == NULL || s->
conn == NULL ||
698 s->
conn->messages == NULL) {
702 size_t size = htp_list_size(s->
conn->messages);
717 htp_log_t *log = htp_list_get(s->
conn->messages,
msg);
722 htp_tx_t *tx = log->tx;
728 uint8_t
id = HTPHandleErrorGetId(log->msg);
730 id = HTPHandleWarningGetId(log->msg);
736 HTPSetEvent(s, htud, dir,
id);
743 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s,
const htp_tx_t *tx)
746 BUG_ON(s == NULL || tx == NULL);
756 HTPSetEvent(s, htud, STREAM_TOSERVER,
792 htp_cfg_t *htp = cfglist.
cfg;
793 void *user_data = NULL;
809 if (user_data != NULL) {
810 htp_cfg_rec = user_data;
811 htp = htp_cfg_rec->
cfg;
814 SCLogDebug(
"Using default HTP config: %p", htp);
818 #ifdef DEBUG_VALIDATION
825 hstate->
connp = htp_connp_create(htp);
826 if (hstate->
connp == NULL) {
830 hstate->
conn = htp_connp_get_connection(hstate->
connp);
832 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
833 hstate->
cfg = htp_cfg_rec;
838 htp_connp_open(hstate->
connp, NULL, f->
sp, NULL, f->
dp, &
tv);
860 StreamSlice stream_slice,
void *local_data)
870 if (NULL == hstate->
conn) {
871 if (Setup(f, hstate) != 0) {
876 hstate->
slice = &stream_slice;
878 const uint8_t *input = StreamSliceGetData(&stream_slice);
879 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
884 const int r = htp_connp_req_data(hstate->
connp, &
ts, input, input_len);
892 HTPHandleError(hstate, STREAM_TOSERVER);
899 htp_connp_req_close(hstate->
connp, &
ts);
901 SCLogDebug(
"stream eof encountered, closing htp handle for ts");
905 hstate->
slice = NULL;
927 StreamSlice stream_slice,
void *local_data)
933 const uint8_t *input = StreamSliceGetData(&stream_slice);
934 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
940 if (NULL == hstate->
conn) {
941 if (Setup(f, hstate) != 0) {
946 hstate->
slice = &stream_slice;
950 uint32_t consumed = 0;
952 const int r = htp_connp_res_data(hstate->
connp, &
ts, input, input_len);
958 tx = htp_connp_get_out_tx(hstate->
connp);
968 consumed = (uint32_t)htp_connp_res_data_consumed(hstate->
connp);
974 hstate->
slice = NULL;
976 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
981 if (consumed > 0 && consumed < input_len) {
990 hstate->
slice = NULL;
992 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
997 if (consumed > 0 && consumed < input_len) {
1007 HTPHandleError(hstate, STREAM_TOCLIENT);
1014 htp_connp_close(hstate->
connp, &
ts);
1019 hstate->
slice = NULL;
1030 static int HTTPParseContentDispositionHeader(
const uint8_t *
name,
size_t name_len,
1031 const uint8_t *data,
size_t len, uint8_t
const **retptr,
size_t *retlen)
1034 printf(
"DATA START: \n");
1036 printf(
"DATA END: \n");
1041 for (x = 0; x <
len; x++) {
1042 if (!(isspace(data[x])))
1049 const uint8_t *line = data + x;
1050 size_t line_len =
len-x;
1053 printf(
"LINE START: \n");
1055 printf(
"LINE END: \n");
1057 for (x = 0 ; x < line_len; x++) {
1059 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
1063 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
1064 const uint8_t *token = line +
offset;
1065 size_t token_len = x -
offset;
1067 if ((x + 1) == line_len) {
1078 printf(
"TOKEN START: \n");
1080 printf(
"TOKEN END: \n");
1082 if (token_len > name_len) {
1083 if (
name == NULL || SCMemcmpLowercase(
name, token, name_len) == 0) {
1084 const uint8_t *value = token + name_len;
1085 size_t value_len = token_len - name_len;
1087 if (value[0] ==
'\"') {
1091 if (value[value_len-1] ==
'\"') {
1095 printf(
"VALUE START: \n");
1097 printf(
"VALUE END: \n");
1100 *retlen = value_len;
1124 static int HtpRequestBodySetupMultipart(
const htp_tx_t *tx,
HtpTxUserData *htud)
1146 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1149 chunks_buffer, chunks_buffer_len,
1153 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1156 if (tx && tx->
tx_data.de_state) {
1157 if (dir == STREAM_TOSERVER) {
1158 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1160 }
else if (dir == STREAM_TOCLIENT) {
1161 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1168 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len,
bool eof)
1171 printf(
"CHUNK START: \n");
1173 printf(
"CHUNK END: \n");
1181 const uint8_t *cur_buf = chunks_buffer;
1182 uint32_t cur_buf_len = chunks_buffer_len;
1198 const uint8_t *filename = NULL;
1199 uint16_t filename_len = 0;
1202 while (cur_buf_len > 0) {
1203 MimeParserResult r =
1204 SCMimeParse(htud->
mime_state, cur_buf, cur_buf_len, &consumed, &warnings);
1208 if (warnings & MIME_EVENT_FLAG_INVALID_HEADER) {
1212 if (warnings & MIME_EVENT_FLAG_NO_FILEDATA) {
1223 SCMimeStateGetFilename(htud->
mime_state, &filename, &filename_len);
1224 if (filename_len > 0) {
1228 hstate, htud, filename, filename_len, NULL, 0, STREAM_TOSERVER);
1231 }
else if (result == -2) {
1234 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1242 }
else if (result == -2) {
1250 uint32_t lastsize = consumed;
1251 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\n') {
1253 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\r') {
1257 HTPFileClose(htud, cur_buf, lastsize, 0, STREAM_TOSERVER);
1262 cur_buf += consumed;
1263 cur_buf_len -= consumed;
1275 const uint8_t *data, uint32_t data_len)
1282 uint8_t *filename = NULL;
1283 size_t filename_len = 0;
1286 if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) {
1287 filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path);
1288 filename_len = bstr_len(tx->parsed_uri->path);
1291 if (filename != NULL) {
1297 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1301 }
else if (result == -2) {
1304 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1318 }
else if (result == -2) {
1331 const uint8_t *data, uint32_t data_len)
1344 const uint8_t *filename = NULL;
1345 size_t filename_len = 0;
1351 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1357 if (filename == NULL) {
1359 if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) {
1360 filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path);
1361 filename_len = bstr_len(tx->parsed_uri->path);
1365 if (filename != NULL) {
1373 if (h_content_range != NULL) {
1375 data_len, tx, h_content_range->value, htud);
1377 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1383 }
else if (result == -2) {
1386 FlagDetectStateNewFile(htud, STREAM_TOCLIENT);
1399 }
else if (result == -2) {
1417 static int HTPCallbackRequestBodyData(htp_tx_data_t *d)
1428 printf(
"HTPBODY START: \n");
1430 printf(
"HTPBODY END: \n");
1433 HtpState *hstate = htp_connp_get_user_data(d->tx->connp);
1434 if (hstate == NULL) {
1438 SCLogDebug(
"New request body data available at %p -> %p -> %p, bodylen "
1443 if (tx_ud == NULL) {
1446 tx_ud->
tx_data.updated_ts =
true;
1457 }
else if (r == 0) {
1461 }
else if (d->htp_tx_request_method_number(tx) ==
HTP_METHOD_PUT) {
1482 const uint8_t *chunks_buffer = NULL;
1483 uint32_t chunks_buffer_len = 0;
1491 HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len);
1492 if (chunks_buffer == NULL) {
1496 printf(
"REASSCHUNK START: \n");
1498 printf(
"REASSCHUNK END: \n");
1501 HtpRequestBodyHandleMultipart(hstate, tx_ud,
htp_tx_data_tx(d), chunks_buffer,
1506 HtpRequestBodyHandlePOSTorPUT(
1512 SCLogDebug(
"closing file that was being stored");
1519 if (hstate->
conn != NULL) {
1520 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1521 ", last %" PRIu64
")",
1536 (uint64_t)UINT_MAX) {
1537 const uint32_t data_size =
1559 static int HTPCallbackResponseBodyData(htp_tx_data_t *d)
1569 HtpState *hstate = htp_connp_get_user_data(d->tx->connp);
1570 if (hstate == NULL) {
1574 SCLogDebug(
"New response body data available at %p -> %p -> %p, bodylen "
1579 if (tx_ud == NULL) {
1582 tx_ud->
tx_data.updated_tc =
true;
1604 HtpResponseBodyHandle(
1608 SCLogDebug(
"closing file that was being stored");
1614 if (hstate->
conn != NULL) {
1615 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1616 ", last %" PRIu64
")",
1630 (uint64_t)UINT_MAX) {
1631 const uint32_t data_size =
1656 SCLogDebug(
"http_state_memcnt %"PRIu64
", http_state_memuse %"PRIu64
"",
1657 htp_state_memcnt, htp_state_memuse);
1675 htp_config_destroy(cfglist.
cfg);
1676 while (nextrec != NULL) {
1678 nextrec = nextrec->
next;
1680 htp_config_destroy(htprec->
cfg);
1688 static int HTPCallbackRequestHasTrailer(htp_tx_t *tx)
1692 htud->
tx_data.updated_ts =
true;
1698 static int HTPCallbackResponseHasTrailer(htp_tx_t *tx)
1702 htud->
tx_data.updated_tc =
true;
1712 static int HTPCallbackRequestStart(htp_tx_t *tx)
1714 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1715 if (hstate == NULL) {
1719 uint64_t consumed = hstate->
slice->offset + htp_connp_req_data_consumed(hstate->
connp);
1720 SCLogDebug(
"HTTP request start: data offset %" PRIu64
", in_data_counter %" PRIu64, consumed,
1738 if (tx_ud == NULL) {
1743 tx_ud->
tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT;
1744 htp_tx_set_user_data(tx, tx_ud);
1746 tx_ud->
tx_data.updated_ts =
true;
1755 static int HTPCallbackResponseStart(htp_tx_t *tx)
1757 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1758 if (hstate == NULL) {
1762 uint64_t consumed = hstate->
slice->offset + htp_connp_res_data_consumed(hstate->
connp);
1763 SCLogDebug(
"HTTP response start: data offset %" PRIu64
", out_data_counter %" PRIu64, consumed,
1779 if (tx_ud == NULL) {
1786 htp_tx_set_user_data(tx, tx_ud);
1788 tx_ud->
tx_data.updated_tc =
true;
1799 static int HTPCallbackRequestComplete(htp_tx_t *tx)
1807 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1808 if (hstate == NULL) {
1812 const uint64_t abs_right_edge =
1813 hstate->
slice->offset + htp_connp_req_data_consumed(hstate->
connp);
1821 SCLogDebug(
"HTTP request complete: data offset %" PRIu64
", request_size %" PRIu64,
1823 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1825 frame->
len = (int64_t)request_size;
1831 SCLogDebug(
"transaction_cnt %"PRIu64
", list_size %"PRIu64,
1836 HTPErrorCheckTxRequestFlags(hstate, tx);
1840 htud->
tx_data.updated_ts =
true;
1842 SCLogDebug(
"closing file that was being stored");
1845 if (abs_right_edge < (uint64_t)UINT32_MAX) {
1847 hstate->
f->
protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
1865 static int HTPCallbackResponseComplete(htp_tx_t *tx)
1869 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1870 if (hstate == NULL) {
1877 const uint64_t abs_right_edge =
1878 hstate->
slice->offset + htp_connp_res_data_consumed(hstate->
connp);
1885 SCLogDebug(
"HTTP response complete: data offset %" PRIu64
", response_size %" PRIu64,
1887 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1889 frame->
len = (int64_t)response_size;
1896 htud->
tx_data.updated_tc =
true;
1898 SCLogDebug(
"closing file that was being stored");
1932 static int HTPCallbackRequestLine(htp_tx_t *tx)
1935 bstr *request_uri_normalized;
1936 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1940 if (request_uri_normalized == NULL)
1943 tx_ud = htp_tx_get_user_data(tx);
1945 bstr_free(request_uri_normalized);
1953 HTPErrorCheckTxRequestFlags(hstate, tx);
1958 static int HTPCallbackDoubleDecodeUriPart(htp_tx_t *tx, bstr *part)
1964 size_t prevlen = bstr_len(part);
1965 htp_status_t res = htp_urldecode_inplace(tx->cfg, HTP_DECODER_URLENCODED, part, &
flags);
1971 HtpState *s = htp_connp_get_user_data(tx->connp);
1980 static int HTPCallbackDoubleDecodeQuery(htp_tx_t *tx)
1982 if (tx->parsed_uri == NULL)
1985 return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->query);
1988 static int HTPCallbackDoubleDecodePath(htp_tx_t *tx)
1990 if (tx->parsed_uri == NULL)
1993 return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->path);
1996 static int HTPCallbackRequestHeaderData(htp_tx_data_t *tx_data)
2003 if (tx_ud == NULL) {
2012 tx_ud->
tx_data.updated_ts =
true;
2025 static int HTPCallbackResponseHeaderData(htp_tx_data_t *tx_data)
2032 if (tx_ud == NULL) {
2035 tx_ud->
tx_data.updated_tc =
true;
2053 static void HTPConfigSetDefaultsPhase1(
HTPCfgRec *cfg_prec)
2070 htp_config_register_request_header_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
2071 htp_config_register_request_trailer_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
2072 htp_config_register_response_header_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
2073 htp_config_register_response_trailer_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
2075 htp_config_register_request_trailer(cfg_prec->
cfg, HTPCallbackRequestHasTrailer);
2076 htp_config_register_response_trailer(cfg_prec->
cfg, HTPCallbackResponseHasTrailer);
2078 htp_config_register_request_body_data(cfg_prec->
cfg, HTPCallbackRequestBodyData);
2079 htp_config_register_response_body_data(cfg_prec->
cfg, HTPCallbackResponseBodyData);
2081 htp_config_register_request_start(cfg_prec->
cfg, HTPCallbackRequestStart);
2082 htp_config_register_request_complete(cfg_prec->
cfg, HTPCallbackRequestComplete);
2084 htp_config_register_response_start(cfg_prec->
cfg, HTPCallbackResponseStart);
2085 htp_config_register_response_complete(cfg_prec->
cfg, HTPCallbackResponseComplete);
2087 htp_config_set_parse_request_cookies(cfg_prec->
cfg, 0);
2088 #ifdef HAVE_HTP_CONFIG_SET_ALLOW_SPACE_URI
2089 htp_config_set_allow_space_uri(cfg_prec->
cfg, 1);
2093 htp_config_set_plusspace_decode(cfg_prec->
cfg, HTP_DECODER_URLENCODED, 0);
2095 htp_config_set_request_decompression(cfg_prec->
cfg, 1);
2096 #ifdef HAVE_HTP_CONFIG_SET_LZMA_LAYERS
2100 #ifdef HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT
2101 htp_config_set_lzma_memlimit(cfg_prec->
cfg,
2104 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT
2105 htp_config_set_compression_bomb_limit(cfg_prec->
cfg,
2108 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
2111 #ifdef HAVE_HTP_CONFIG_SET_MAX_TX
2112 #define HTP_CONFIG_DEFAULT_MAX_TX_LIMIT 512
2113 htp_config_set_max_tx(cfg_prec->
cfg, HTP_CONFIG_DEFAULT_MAX_TX_LIMIT);
2115 #ifdef HAVE_HTP_CONFIG_SET_HEADERS_LIMIT
2116 #define HTP_CONFIG_DEFAULT_HEADERS_LIMIT 1024
2117 htp_config_set_number_headers_limit(cfg_prec->
cfg, HTP_CONFIG_DEFAULT_HEADERS_LIMIT);
2132 static int RandomGetWrap(
void)
2138 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
2140 return r % RAND_MAX;
2149 static void HTPConfigSetDefaultsPhase2(
const char *
name,
HTPCfgRec *cfg_prec)
2155 long int r = RandomGetWrap();
2157 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2159 r = RandomGetWrap();
2161 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2162 SCLogConfig(
"'%s' server has 'request-body-minimal-inspect-size' set to"
2163 " %u and 'request-body-inspect-window' set to %u after"
2167 r = RandomGetWrap();
2169 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2171 r = RandomGetWrap();
2173 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2175 SCLogConfig(
"'%s' server has 'response-body-minimal-inspect-size' set to"
2176 " %u and 'response-body-inspect-window' set to %u after"
2181 htp_config_register_request_line(cfg_prec->
cfg, HTPCallbackRequestLine);
2184 static void HTPConfigParseParameters(
HTPCfgRec *cfg_prec,
ConfNode *s,
struct HTPConfigTree *tree)
2186 if (cfg_prec == NULL || s == NULL || tree == NULL)
2193 if (strcasecmp(
"address", p->
name) == 0) {
2199 if (strchr(pval->
val,
':') != NULL) {
2200 SCLogDebug(
"LIBHTP adding ipv6 server %s at %s: %p",
2204 SCLogWarning(
"LIBHTP failed to add ipv6 server %s, ignoring", pval->
val);
2207 SCLogDebug(
"LIBHTP adding ipv4 server %s at %s: %p",
2211 SCLogWarning(
"LIBHTP failed to add ipv4 server %s, ignoring", pval->
val);
2216 }
else if (strcasecmp(
"personality", p->
name) == 0) {
2218 int personality = HTPLookupPersonality(p->
val);
2222 if (personality >= 0) {
2225 if (htp_config_set_server_personality(cfg_prec->
cfg, personality) ==
2228 "personality \"%s\", ignoring",
2232 HTPLookupPersonalityString(personality));
2238 htp_config_set_convert_lowercase(cfg_prec->
cfg, HTP_DECODER_URL_PATH, 0);
2246 }
else if (strcasecmp(
"request-body-limit", p->
name) == 0 ||
2247 strcasecmp(
"request_body_limit", p->
name) == 0) {
2249 SCLogError(
"Error parsing request-body-limit "
2250 "from conf file - %s. Killing engine",
2255 }
else if (strcasecmp(
"response-body-limit", p->
name) == 0) {
2257 SCLogError(
"Error parsing response-body-limit "
2258 "from conf file - %s. Killing engine",
2263 }
else if (strcasecmp(
"request-body-minimal-inspect-size", p->
name) == 0) {
2265 SCLogError(
"Error parsing request-body-minimal-inspect-size "
2266 "from conf file - %s. Killing engine",
2271 }
else if (strcasecmp(
"request-body-inspect-window", p->
name) == 0) {
2273 SCLogError(
"Error parsing request-body-inspect-window "
2274 "from conf file - %s. Killing engine",
2279 }
else if (strcasecmp(
"double-decode-query", p->
name) == 0) {
2281 htp_config_register_request_line(cfg_prec->
cfg,
2282 HTPCallbackDoubleDecodeQuery);
2285 }
else if (strcasecmp(
"double-decode-path", p->
name) == 0) {
2287 htp_config_register_request_line(cfg_prec->
cfg,
2288 HTPCallbackDoubleDecodePath);
2291 }
else if (strcasecmp(
"response-body-minimal-inspect-size", p->
name) == 0) {
2293 SCLogError(
"Error parsing response-body-minimal-inspect-size "
2294 "from conf file - %s. Killing engine",
2299 }
else if (strcasecmp(
"response-body-inspect-window", p->
name) == 0) {
2301 SCLogError(
"Error parsing response-body-inspect-window "
2302 "from conf file - %s. Killing engine",
2307 }
else if (strcasecmp(
"response-body-decompress-layer-limit", p->
name) == 0) {
2310 SCLogError(
"Error parsing response-body-inspect-window "
2311 "from conf file - %s. Killing engine",
2315 #ifdef HAVE_HTP_CONFIG_SET_RESPONSE_DECOMPRESSION_LAYER_LIMIT
2316 htp_config_set_response_decompression_layer_limit(cfg_prec->
cfg, value);
2318 SCLogWarning(
"can't set response-body-decompress-layer-limit "
2319 "to %u, libhtp version too old",
2322 }
else if (strcasecmp(
"path-convert-backslash-separators", p->
name) == 0) {
2323 htp_config_set_backslash_convert_slashes(cfg_prec->
cfg,
2324 HTP_DECODER_URL_PATH,
2326 }
else if (strcasecmp(
"path-bestfit-replacement-char", p->
name) == 0) {
2327 if (strlen(p->
val) == 1) {
2328 htp_config_set_bestfit_replacement_byte(cfg_prec->
cfg,
2329 HTP_DECODER_URL_PATH,
2333 "for libhtp param path-bestfit-replacement-char");
2335 }
else if (strcasecmp(
"path-convert-lowercase", p->
name) == 0) {
2336 htp_config_set_convert_lowercase(cfg_prec->
cfg,
2337 HTP_DECODER_URL_PATH,
2339 }
else if (strcasecmp(
"path-nul-encoded-terminates", p->
name) == 0) {
2340 htp_config_set_nul_encoded_terminates(cfg_prec->
cfg,
2341 HTP_DECODER_URL_PATH,
2343 }
else if (strcasecmp(
"path-nul-raw-terminates", p->
name) == 0) {
2344 htp_config_set_nul_raw_terminates(cfg_prec->
cfg,
2345 HTP_DECODER_URL_PATH,
2347 }
else if (strcasecmp(
"path-separators-compress", p->
name) == 0) {
2348 htp_config_set_path_separators_compress(cfg_prec->
cfg,
2349 HTP_DECODER_URL_PATH,
2351 }
else if (strcasecmp(
"path-separators-decode", p->
name) == 0) {
2352 htp_config_set_path_separators_decode(cfg_prec->
cfg,
2353 HTP_DECODER_URL_PATH,
2355 }
else if (strcasecmp(
"path-u-encoding-decode", p->
name) == 0) {
2356 htp_config_set_u_encoding_decode(cfg_prec->
cfg,
2357 HTP_DECODER_URL_PATH,
2359 }
else if (strcasecmp(
"path-url-encoding-invalid-handling", p->
name) == 0) {
2360 enum htp_url_encoding_handling_t handling;
2361 if (strcasecmp(p->
val,
"preserve_percent") == 0) {
2362 handling = HTP_URL_DECODE_PRESERVE_PERCENT;
2363 }
else if (strcasecmp(p->
val,
"remove_percent") == 0) {
2364 handling = HTP_URL_DECODE_REMOVE_PERCENT;
2365 }
else if (strcasecmp(p->
val,
"decode_invalid") == 0) {
2366 handling = HTP_URL_DECODE_PROCESS_INVALID;
2369 "for libhtp param path-url-encoding-invalid-handling");
2372 htp_config_set_url_encoding_invalid_handling(cfg_prec->
cfg,
2373 HTP_DECODER_URL_PATH,
2375 }
else if (strcasecmp(
"path-utf8-convert-bestfit", p->
name) == 0) {
2376 htp_config_set_utf8_convert_bestfit(cfg_prec->
cfg,
2377 HTP_DECODER_URL_PATH,
2379 }
else if (strcasecmp(
"uri-include-all", p->
name) == 0) {
2383 }
else if (strcasecmp(
"query-plusspace-decode", p->
name) == 0) {
2384 htp_config_set_plusspace_decode(cfg_prec->
cfg,
2385 HTP_DECODER_URLENCODED,
2387 }
else if (strcasecmp(
"meta-field-limit", p->
name) == 0) {
2391 "from conf file - %s. Killing engine",
2397 "from conf file cannot be 0. Killing engine");
2400 htp_config_set_field_limits(cfg_prec->
cfg,
2403 #ifdef HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT
2404 }
else if (strcasecmp(
"lzma-memlimit", p->
name) == 0) {
2407 FatalError(
"failed to parse 'lzma-memlimit' "
2408 "from conf file - %s.",
2413 "from conf file cannot be 0.");
2416 SCLogConfig(
"Setting HTTP LZMA memory limit to %"PRIu32
" bytes", limit);
2417 htp_config_set_lzma_memlimit(cfg_prec->
cfg, (
size_t)limit);
2419 #ifdef HAVE_HTP_CONFIG_SET_LZMA_LAYERS
2420 }
else if (strcasecmp(
"lzma-enabled", p->
name) == 0) {
2422 htp_config_set_lzma_layers(cfg_prec->
cfg, 1);
2427 "from conf file - %s.",
2430 SCLogConfig(
"Setting HTTP LZMA decompression layers to %" PRIu32
"", (
int)limit);
2431 htp_config_set_lzma_layers(cfg_prec->
cfg, limit);
2434 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT
2435 }
else if (strcasecmp(
"compression-bomb-limit", p->
name) == 0) {
2438 FatalError(
"failed to parse 'compression-bomb-limit' "
2439 "from conf file - %s.",
2444 "from conf file cannot be 0.");
2447 SCLogConfig(
"Setting HTTP compression bomb limit to %"PRIu32
" bytes", limit);
2448 htp_config_set_compression_bomb_limit(cfg_prec->
cfg, (
size_t)limit);
2450 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
2451 }
else if (strcasecmp(
"decompression-time-limit", p->
name) == 0) {
2455 FatalError(
"failed to parse 'decompression-time-limit' "
2456 "from conf file - %s.",
2459 SCLogConfig(
"Setting HTTP decompression time limit to %" PRIu32
" usec", limit);
2460 htp_config_set_compression_time_limit(cfg_prec->
cfg, (
size_t)limit);
2462 #ifdef HAVE_HTP_CONFIG_SET_MAX_TX
2463 }
else if (strcasecmp(
"max-tx", p->
name) == 0) {
2467 "from conf file - %s.",
2471 SCLogConfig(
"Setting HTTP max-tx limit to %" PRIu32
" bytes", limit);
2472 htp_config_set_max_tx(cfg_prec->
cfg, limit);
2474 #ifdef HAVE_HTP_CONFIG_SET_HEADERS_LIMIT
2475 }
else if (strcasecmp(
"headers-limit", p->
name) == 0) {
2478 FatalError(
"failed to parse 'headers-limit' "
2479 "from conf file - %s.",
2482 SCLogConfig(
"Setting HTTP headers limit to %" PRIu32, limit);
2483 htp_config_set_number_headers_limit(cfg_prec->
cfg, limit);
2485 }
else if (strcasecmp(
"randomize-inspection-sizes", p->
name) == 0) {
2489 }
else if (strcasecmp(
"randomize-inspection-range", p->
name) == 0) {
2492 (
const char *)p->
val, 0, 100) < 0) {
2494 "-inspection-range setting from conf file - \"%s\"."
2495 " It should be a valid integer less than or equal to 100."
2501 }
else if (strcasecmp(
"http-body-inline", p->
name) == 0) {
2507 if (strcmp(
"auto", p->
val) != 0) {
2516 }
else if (strcasecmp(
"swf-decompression", p->
name) == 0) {
2520 if (strcasecmp(
"enabled", pval->
name) == 0) {
2528 }
else if (strcasecmp(
"type", pval->
name) == 0) {
2529 if (strcasecmp(
"no", pval->
val) == 0) {
2531 }
else if (strcasecmp(
"deflate", pval->
val) == 0) {
2533 }
else if (strcasecmp(
"lzma", pval->
val) == 0) {
2535 }
else if (strcasecmp(
"both", pval->
val) == 0) {
2539 "swf-decompression.type: %s - "
2544 }
else if (strcasecmp(
"compress-depth", pval->
name) == 0) {
2546 SCLogError(
"Error parsing swf-decompression.compression-depth "
2547 "from conf file - %s. Killing engine",
2551 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2553 SCLogError(
"Error parsing swf-decompression.decompression-depth "
2554 "from conf file - %s. Killing engine",
2564 "default config: %s",
2574 cfglist.
next = NULL;
2581 cfglist.
cfg = htp_config_create();
2582 if (NULL == cfglist.
cfg) {
2583 FatalError(
"Failed to create HTP default config");
2586 HTPConfigSetDefaultsPhase1(&cfglist);
2587 if (
ConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2588 HTPConfigParseParameters(&cfglist,
ConfGetNode(
"libhtp.default-config"), &cfgtree);
2590 HTPConfigParseParameters(
2591 &cfglist,
ConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), &cfgtree);
2593 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2599 if (server_config == NULL) {
2600 server_config =
ConfGetNode(
"libhtp.server-config");
2601 if (server_config == NULL) {
2602 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2606 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2625 cfglist.
next = htprec;
2628 cfglist.
next->
cfg = htp_config_create();
2629 if (NULL == cfglist.
next->
cfg) {
2630 FatalError(
"Failed to create HTP server config");
2633 HTPConfigSetDefaultsPhase1(htprec);
2634 HTPConfigParseParameters(htprec, s, &cfgtree);
2635 HTPConfigSetDefaultsPhase2(s->
name, htprec);
2645 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
2656 static AppLayerGetFileState HTPGetTxFiles(
void *txv, uint8_t direction)
2658 AppLayerGetFileState files = { .fc = NULL, .cfg = &
htp_sbcfg };
2659 htp_tx_t *tx = (htp_tx_t *)txv;
2662 if (direction & STREAM_TOCLIENT) {
2671 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
2673 if (direction & STREAM_TOSERVER)
2674 return ((htp_tx_t *)tx)->request_progress;
2676 return ((htp_tx_t *)tx)->response_progress;
2679 static uint64_t HTPStateGetTxCnt(
void *alstate)
2683 if (http_state != NULL && http_state->
conn != NULL) {
2684 const int64_t size = (int64_t)htp_list_size(http_state->
conn->transactions);
2688 return (uint64_t)size + http_state->
tx_freed;
2694 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
2698 if (http_state != NULL && http_state->
conn != NULL && tx_id >= http_state->
tx_freed)
2699 return htp_list_get(http_state->
conn->transactions, tx_id - http_state->
tx_freed);
2708 if (http_state != NULL && http_state->
conn != NULL) {
2709 size_t txid = HTPStateGetTxCnt(http_state);
2711 return htp_list_get(http_state->
conn->transactions, txid - http_state->
tx_freed - 1);
2717 static int HTPStateGetEventInfo(
2718 const char *event_name, uint8_t *event_id, AppLayerEventType *event_type)
2721 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2727 static int HTPStateGetEventInfoById(
2728 uint8_t event_id,
const char **event_name, AppLayerEventType *event_type)
2731 if (*event_name == NULL) {
2733 "http's enum map table.",
2739 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2746 htp_tx_t *tx = (htp_tx_t *)vtx;
2754 static AppLayerStateData *HTPGetStateData(
void *vstate)
2760 static int HTPRegisterPatternsForProtocolDetection(
void)
2762 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
2763 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
2764 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
2765 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
2766 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
2767 const char *spacings[] = {
"|20|",
"|09|", NULL };
2768 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
2773 int register_result;
2774 char method_buffer[32] =
"";
2777 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
2778 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
2781 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
2788 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
2789 if (register_result < 0) {
2796 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
2798 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
2800 if (register_result < 0) {
2816 const char *proto_name =
"http";
2821 if (HTPRegisterPatternsForProtocolDetection() < 0)
2824 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
2851 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
2853 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
2859 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
2862 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
2866 SCLogInfo(
"Parser disabled for %s protocol. Protocol detection still on.", proto_name);
2882 cfglist_backup = cfglist;
2887 cfglist = cfglist_backup;
2892 static int HTPParserTest01(
void)
2894 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2896 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2899 memset(&ssn, 0,
sizeof(ssn));
2907 f->
proto = IPPROTO_TCP;
2913 for (u = 0; u < httplen1; u++) {
2917 flags = STREAM_TOSERVER|STREAM_START;
2918 else if (u == (httplen1 - 1))
2919 flags = STREAM_TOSERVER|STREAM_EOF;
2921 flags = STREAM_TOSERVER;
2930 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2947 static int HTPParserTest01b(
void)
2949 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2951 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2954 memset(&ssn, 0,
sizeof(ssn));
2962 f->
proto = IPPROTO_TCP;
2967 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
2974 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2991 static int HTPParserTest01c(
void)
2993 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2995 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2998 memset(&ssn, 0,
sizeof(ssn));
3006 f->
proto = IPPROTO_TCP;
3012 for (u = 0; u < httplen1; u++) {
3016 flags = STREAM_TOSERVER|STREAM_START;
3017 else if (u == (httplen1 - 1))
3018 flags = STREAM_TOSERVER|STREAM_EOF;
3020 flags = STREAM_TOSERVER;
3029 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3047 static int HTPParserTest01a(
void)
3050 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3052 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3057 memset(&ssn, 0,
sizeof(ssn));
3059 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3062 f->
proto = IPPROTO_TCP;
3068 for (u = 0; u < httplen1; u++) {
3072 flags = STREAM_TOSERVER|STREAM_START;
3073 else if (u == (httplen1 - 1))
3074 flags = STREAM_TOSERVER|STREAM_EOF;
3076 flags = STREAM_TOSERVER;
3085 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3102 static int HTPParserTest02(
void)
3105 uint8_t httpbuf1[] =
"POST";
3106 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3111 memset(&ssn, 0,
sizeof(ssn));
3113 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3116 f->
proto = IPPROTO_TCP;
3122 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3128 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3137 FAIL_IF(strcmp(method,
"POST") != 0);
3148 static int HTPParserTest03(
void)
3151 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
3152 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3157 memset(&ssn, 0,
sizeof(ssn));
3159 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3162 f->
proto = IPPROTO_TCP;
3168 for (u = 0; u < httplen1; u++) {
3171 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3172 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3173 else flags = STREAM_TOSERVER;
3181 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3197 static int HTPParserTest04(
void)
3201 uint8_t httpbuf1[] =
"World!\r\n";
3202 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3206 memset(&ssn, 0,
sizeof(ssn));
3208 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3211 f->
proto = IPPROTO_TCP;
3217 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3223 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3239 static int HTPParserTest05(
void)
3241 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3242 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3243 uint8_t httpbuf2[] =
"Post D";
3244 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3245 uint8_t httpbuf3[] =
"ata is c0oL!";
3246 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3248 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3249 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3250 uint8_t httpbuf5[] =
"post R";
3251 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3252 uint8_t httpbuf6[] =
"esults are tha bomb!";
3253 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3256 memset(&ssn, 0,
sizeof(ssn));
3264 f->
proto = IPPROTO_TCP;
3294 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3312 static int HTPParserTest06(
void)
3314 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3315 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3316 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3317 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3318 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3320 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3321 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3322 "FrontPage/5.0.2.2510\r\n"
3323 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3325 "Content-Type: text/html\r\n\r\n"
3327 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3328 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3329 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3330 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3331 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3332 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3333 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3334 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3335 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3336 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3337 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3338 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3339 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3340 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3341 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3342 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3343 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3344 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3345 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3346 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3347 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3348 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3349 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3350 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3351 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3352 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3353 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3354 "aHA=\r\n0\r\n\r\n";
3355 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3361 memset(&ssn, 0,
sizeof(ssn));
3366 f->
proto = IPPROTO_TCP;
3381 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3401 static int HTPParserTest07(
void)
3404 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3405 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3410 memset(&ssn, 0,
sizeof(ssn));
3412 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3415 f->
proto = IPPROTO_TCP;
3421 for (u = 0; u < httplen1; u++) {
3425 flags = STREAM_TOSERVER|STREAM_START;
3426 else if (u == (httplen1 - 1))
3427 flags = STREAM_TOSERVER|STREAM_EOF;
3429 flags = STREAM_TOSERVER;
3438 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3439 size_t reflen =
sizeof(ref) - 1;
3441 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3462 static int HTPParserTest08(
void)
3465 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3466 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3487 memset(&ssn, 0,
sizeof(ssn));
3489 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3492 f->
proto = IPPROTO_TCP;
3497 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3505 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3525 static int HTPParserTest09(
void)
3528 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3529 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3539 personality: Apache_2_2\n\
3551 memset(&ssn, 0,
sizeof(ssn));
3553 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3556 f->
proto = IPPROTO_TCP;
3561 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3569 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3590 static int HTPParserTest10(
void)
3594 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3595 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3600 memset(&ssn, 0,
sizeof(ssn));
3602 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3605 f->
proto = IPPROTO_TCP;
3611 for (u = 0; u < httplen1; u++) {
3615 flags = STREAM_TOSERVER|STREAM_START;
3616 else if (u == (httplen1 - 1))
3617 flags = STREAM_TOSERVER|STREAM_EOF;
3619 flags = STREAM_TOSERVER;
3628 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3638 FAIL_IF(strcmp(value,
"www.google.com") != 0);
3650 static int HTPParserTest11(
void)
3653 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3654 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3659 memset(&ssn, 0,
sizeof(ssn));
3661 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3664 f->
proto = IPPROTO_TCP;
3670 for (u = 0; u < httplen1; u++) {
3674 flags = STREAM_TOSERVER|STREAM_START;
3675 else if (u == (httplen1 - 1))
3676 flags = STREAM_TOSERVER|STREAM_EOF;
3678 flags = STREAM_TOSERVER;
3687 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3709 static int HTPParserTest12(
void)
3712 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3713 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3718 memset(&ssn, 0,
sizeof(ssn));
3720 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3723 f->
proto = IPPROTO_TCP;
3729 for (u = 0; u < httplen1; u++) {
3733 flags = STREAM_TOSERVER|STREAM_START;
3734 else if (u == (httplen1 - 1))
3735 flags = STREAM_TOSERVER|STREAM_EOF;
3737 flags = STREAM_TOSERVER;
3746 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3770 static int HTPParserTest13(
void)
3773 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3774 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3779 memset(&ssn, 0,
sizeof(ssn));
3781 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3784 f->
proto = IPPROTO_TCP;
3790 for (u = 0; u < httplen1; u++) {
3794 flags = STREAM_TOSERVER|STREAM_START;
3795 else if (u == (httplen1 - 1))
3796 flags = STREAM_TOSERVER|STREAM_EOF;
3798 flags = STREAM_TOSERVER;
3806 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3816 FAIL_IF(strcmp(value,
"www.google.com\rName: Value") != 0);
3828 static int HTPParserConfigTest01(
void)
3841 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3842 personality: Tomcat_6_0\n\
3847 - 192.168.10.0/24\n\
3848 personality: IIS_7_0\n\
3857 outputs =
ConfGetNode(
"libhtp.default-config.personality");
3868 FAIL_IF(strcmp(node->
name,
"apache-tomcat") != 0);
3875 FAIL_IF(strcmp(node2->
val,
"Tomcat_6_0") != 0);
3885 FAIL_IF(strcmp(n->
val,
"192.168.1.0/24") != 0);
3925 FAIL_IF(strcmp(n->
val,
"192.168.0.0/24") != 0);
3929 FAIL_IF(strcmp(n->
val,
"192.168.10.0/24") != 0);
3944 static int HTPParserConfigTest02(
void)
3957 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3958 personality: Tomcat_6_0\n\
3963 - 192.168.10.0/24\n\
3964 personality: IIS_7_0\n\
3976 htp_cfg_t *htp = cfglist.
cfg;
3979 void *user_data = NULL;
3981 addr =
"192.168.10.42";
3982 FAIL_IF(inet_pton(AF_INET, addr, buf) != 1);
3986 htp = htp_cfg_rec->
cfg;
3992 FAIL_IF(inet_pton(AF_INET6, addr, buf) != 1);
3995 htp_cfg_rec = user_data;
3996 htp = htp_cfg_rec->
cfg;
4009 static int HTPParserConfigTest03(
void)
4012 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
4014 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4030 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
4031 personality: Tomcat_6_0\n\
4036 - 192.168.10.0/24\n\
4037 personality: IIS_7_0\n\
4048 const char *addr =
"192.168.10.42";
4050 memset(&ssn, 0,
sizeof(ssn));
4055 f->
proto = IPPROTO_TCP;
4058 htp_cfg_t *htp = cfglist.
cfg;
4061 void *user_data = NULL;
4066 htp = htp_cfg_rec->
cfg;
4073 for (u = 0; u < httplen1; u++) {
4076 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4077 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4078 else flags = STREAM_TOSERVER;
4087 FAIL_IF(HTPStateGetTxCnt(htp_state) != 2);
4089 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4093 tx = HTPStateGetTx(htp_state, 1);
4114 static int HTPParserDecodingTest01(
void)
4116 uint8_t httpbuf1[] =
4117 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4118 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4119 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4120 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4131 personality: Apache_2\n\
4139 const char *addr =
"4.3.2.1";
4140 memset(&ssn, 0,
sizeof(ssn));
4145 f->
proto = IPPROTO_TCP;
4150 for (uint32_t u = 0; u < httplen1; u++) {
4152 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4153 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4154 else flags = STREAM_TOSERVER;
4163 uint8_t ref1[] =
"/abc%2fdef";
4164 size_t reflen =
sizeof(ref1) - 1;
4166 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4176 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4177 reflen =
sizeof(ref2) - 1;
4179 tx = HTPStateGetTx(htp_state, 1);
4189 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4190 reflen =
sizeof(ref3) - 1;
4191 tx = HTPStateGetTx(htp_state, 2);
4212 static int HTPParserDecodingTest01a(
void)
4214 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4215 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4216 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4217 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4228 personality: Apache_2\n\
4236 const char *addr =
"4.3.2.1";
4237 memset(&ssn, 0,
sizeof(ssn));
4242 f->
proto = IPPROTO_TCP;
4248 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4254 uint8_t ref1[] =
"/abc%2fdef";
4255 size_t reflen =
sizeof(ref1) - 1;
4257 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4267 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4268 reflen =
sizeof(ref2) - 1;
4270 tx = HTPStateGetTx(htp_state, 1);
4280 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4281 reflen =
sizeof(ref3) - 1;
4282 tx = HTPStateGetTx(htp_state, 2);
4309 static int HTPParserDecodingTest02(
void)
4312 uint8_t httpbuf1[] =
4313 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4314 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4315 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4316 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4328 double-decode-path: no\n\
4329 double-decode-query: no\n\
4337 const char *addr =
"4.3.2.1";
4338 memset(&ssn, 0,
sizeof(ssn));
4343 f->
proto = IPPROTO_TCP;
4349 for (u = 0; u < httplen1; u++) {
4352 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4353 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4354 else flags = STREAM_TOSERVER;
4363 uint8_t ref1[] =
"/abc/def";
4364 size_t reflen =
sizeof(ref1) - 1;
4366 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4375 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4376 reflen =
sizeof(ref2) - 1;
4378 tx = HTPStateGetTx(htp_state, 1);
4388 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4389 reflen =
sizeof(ref3) - 1;
4390 tx = HTPStateGetTx(htp_state, 2);
4416 static int HTPParserDecodingTest03(
void)
4419 uint8_t httpbuf1[] =
4420 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4421 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4422 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4434 double-decode-path: yes\n\
4435 double-decode-query: yes\n\
4443 const char *addr =
"4.3.2.1";
4444 memset(&ssn, 0,
sizeof(ssn));
4449 f->
proto = IPPROTO_TCP;
4455 for (u = 0; u < httplen1; u++) {
4458 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4459 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4460 else flags = STREAM_TOSERVER;
4469 uint8_t ref1[] =
"/abc/def";
4470 size_t reflen =
sizeof(ref1) - 1;
4472 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4482 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4483 reflen =
sizeof(ref2) - 1;
4485 tx = HTPStateGetTx(htp_state, 1);
4508 static int HTPParserDecodingTest04(
void)
4511 uint8_t httpbuf1[] =
4512 "GET /abc/def?a=http://www.abc.com/ 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\
4534 const char *addr =
"4.3.2.1";
4535 memset(&ssn, 0,
sizeof(ssn));
4540 f->
proto = IPPROTO_TCP;
4546 for (u = 0; u < httplen1; u++) {
4549 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4550 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4551 else flags = STREAM_TOSERVER;
4560 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
4561 size_t reflen =
sizeof(ref1) - 1;
4563 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4586 static int HTPParserDecodingTest05(
void)
4589 uint8_t httpbuf1[] =
4590 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4591 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4603 double-decode-path: yes\n\
4604 double-decode-query: yes\n\
4612 const char *addr =
"4.3.2.1";
4613 memset(&ssn, 0,
sizeof(ssn));
4618 f->
proto = IPPROTO_TCP;
4624 for (u = 0; u < httplen1; u++) {
4627 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4628 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4629 else flags = STREAM_TOSERVER;
4638 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
4639 size_t reflen =
sizeof(ref1) - 1;
4641 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4664 static int HTPParserDecodingTest06(
void)
4667 uint8_t httpbuf1[] =
4668 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4669 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4681 double-decode-path: yes\n\
4682 double-decode-query: yes\n\
4690 const char *addr =
"4.3.2.1";
4691 memset(&ssn, 0,
sizeof(ssn));
4696 f->
proto = IPPROTO_TCP;
4702 for (u = 0; u < httplen1; u++) {
4705 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4706 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4707 else flags = STREAM_TOSERVER;
4716 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
4717 size_t reflen =
sizeof(ref1) - 1;
4719 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4742 static int HTPParserDecodingTest07(
void)
4745 uint8_t httpbuf1[] =
4746 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4747 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4759 double-decode-path: yes\n\
4760 double-decode-query: yes\n\
4761 query-plusspace-decode: yes\n\
4769 const char *addr =
"4.3.2.1";
4770 memset(&ssn, 0,
sizeof(ssn));
4775 f->
proto = IPPROTO_TCP;
4781 for (u = 0; u < httplen1; u++) {
4784 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4785 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4786 else flags = STREAM_TOSERVER;
4795 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
4796 size_t reflen =
sizeof(ref1) - 1;
4798 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4821 static int HTPParserDecodingTest08(
void)
4824 uint8_t httpbuf1[] =
4825 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4826 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4845 const char *addr =
"4.3.2.1";
4846 memset(&ssn, 0,
sizeof(ssn));
4851 f->
proto = IPPROTO_TCP;
4857 for (u = 0; u < httplen1; u++) {
4860 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4861 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4862 else flags = STREAM_TOSERVER;
4871 uint8_t ref1[] =
"/blah/";
4872 size_t reflen =
sizeof(ref1) - 1;
4874 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4897 static int HTPParserDecodingTest09(
void)
4900 uint8_t httpbuf1[] =
4901 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4902 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4914 uri-include-all: true\n\
4922 const char *addr =
"4.3.2.1";
4923 memset(&ssn, 0,
sizeof(ssn));
4928 f->
proto = IPPROTO_TCP;
4934 for (u = 0; u < httplen1; u++) {
4937 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4938 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4939 else flags = STREAM_TOSERVER;
4948 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
4949 size_t reflen =
sizeof(ref1) - 1;
4951 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4973 static int HTPBodyReassemblyTest01(
void)
4976 memset(&htud, 0x00,
sizeof(htud));
4978 memset(&hstate, 0x00,
sizeof(hstate));
4980 memset(&flow, 0x00,
sizeof(flow));
4983 memset(&tx, 0,
sizeof(tx));
4988 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
4989 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";
4996 const uint8_t *chunks_buffer = NULL;
4997 uint32_t chunks_buffer_len = 0;
4999 HtpRequestBodyReassemble(&htud, &chunks_buffer, &chunks_buffer_len);
5002 printf(
"REASSCHUNK START: \n");
5004 printf(
"REASSCHUNK END: \n");
5007 htud.
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
5008 strlen(
"multipart/form-data; boundary=toto"));
5011 HtpRequestBodyHandleMultipart(&hstate, &htud, &tx, chunks_buffer, chunks_buffer_len,
false);
5021 static int HTPSegvTest01(
void)
5024 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";
5025 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5033 double-decode-path: no\n\
5034 double-decode-query: no\n\
5035 request-body-limit: 0\n\
5036 response-body-limit: 0\n\
5049 memset(&ssn, 0,
sizeof(ssn));
5051 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5054 f->
proto = IPPROTO_TCP;
5059 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
5063 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
5084 static int HTPParserTest14(
void)
5095 double-decode-path: no\n\
5096 double-decode-query: no\n\
5097 request-body-limit: 0\n\
5098 response-body-limit: 0\n\
5103 memset(&ssn, 0,
sizeof(ssn));
5113 memset(httpbuf, 0x00,
len);
5116 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5117 "Host: myhost.lan\r\n"
5118 "Connection: keep-alive\r\n"
5120 "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"
5121 "Referer: http://blah.lan/\r\n"
5122 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5124 size_t o = strlen(httpbuf);
5125 for ( ; o <
len - 4; o++) {
5128 httpbuf[
len - 4] =
'\r';
5129 httpbuf[
len - 3] =
'\n';
5130 httpbuf[
len - 2] =
'\r';
5131 httpbuf[
len - 1] =
'\n';
5137 f->
proto = IPPROTO_TCP;
5142 for (u = 0; u <
len; u++) {
5145 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5146 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5147 else flags = STREAM_TOSERVER;
5155 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5180 static int HTPParserTest15(
void)
5183 char *httpbuf = NULL;
5194 double-decode-path: no\n\
5195 double-decode-query: no\n\
5196 request-body-limit: 0\n\
5197 response-body-limit: 0\n\
5198 meta-field-limit: 20000\n\
5202 memset(&ssn, 0,
sizeof(ssn));
5213 memset(httpbuf, 0x00,
len);
5216 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5217 "Host: myhost.lan\r\n"
5218 "Connection: keep-alive\r\n"
5220 "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"
5221 "Referer: http://blah.lan/\r\n"
5222 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5224 size_t o = strlen(httpbuf);
5225 for ( ; o <
len - 4; o++) {
5228 httpbuf[
len - 4] =
'\r';
5229 httpbuf[
len - 3] =
'\n';
5230 httpbuf[
len - 2] =
'\r';
5231 httpbuf[
len - 1] =
'\n';
5233 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5236 f->
proto = IPPROTO_TCP;
5242 for (u = 0; u <
len; u++) {
5245 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5246 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5247 else flags = STREAM_TOSERVER;
5256 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5278 static int HTPParserTest16(
void)
5285 memset(&ssn, 0,
sizeof(ssn));
5287 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5288 "Host: myhost.lan\r\n"
5289 "Connection: keep-alive\r\n"
5291 "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"
5292 "Referer: http://blah.lan/\r\n"
5293 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5294 "Cookie: blah\r\n\r\n";
5295 size_t len =
sizeof(httpbuf) - 1;
5297 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5300 f->
proto = IPPROTO_TCP;
5305 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5313 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5318 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5338 static int HTPParserTest20(
void)
5341 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5342 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5343 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5344 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5345 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
5346 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5347 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5348 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5354 memset(&ssn, 0,
sizeof(ssn));
5356 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5359 f->
proto = IPPROTO_TCP;
5378 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5397 static int HTPParserTest21(
void)
5400 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5401 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5402 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5403 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5404 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
5405 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5406 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5407 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5413 memset(&ssn, 0,
sizeof(ssn));
5415 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5418 f->
proto = IPPROTO_TCP;
5437 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5456 static int HTPParserTest22(
void)
5459 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5460 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5461 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5462 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5463 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
5464 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5465 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5471 memset(&ssn, 0,
sizeof(ssn));
5473 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5476 f->
proto = IPPROTO_TCP;
5491 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5510 static int HTPParserTest23(
void)
5513 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5514 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5515 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5516 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5517 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
5518 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5519 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5525 memset(&ssn, 0,
sizeof(ssn));
5527 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5530 f->
proto = IPPROTO_TCP;
5545 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5564 static int HTPParserTest24(
void)
5567 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5568 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5569 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5570 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5571 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
5572 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5573 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5579 memset(&ssn, 0,
sizeof(ssn));
5581 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5584 f->
proto = IPPROTO_TCP;
5599 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5617 static int HTPParserTest25(
void)
5624 memset(&ssn, 0,
sizeof(ssn));
5629 f->
proto = IPPROTO_TCP;
5632 const char *
str =
"GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
5634 (uint8_t *)
str, strlen(
str));
5658 str =
"HTTP 1.1 200 OK\r\nServer: Suricata/1.0\r\nContent-Length: 8\r\n\r\nSuricata";
5660 (uint8_t *)
str, strlen(
str));
5694 (uint8_t *)
str, strlen(
str));
5705 (uint8_t *)
str, strlen(
str));
5725 static int HTPParserTest26(
void)
5734 request-body-limit: 1\n\
5735 response-body-limit: 1\n\
5749 uint8_t httpbuf1[] =
"GET /alice.txt HTTP/1.1\r\n\r\n";
5750 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5751 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\n"
5752 "Content-Type: text/plain\r\n"
5753 "Content-Length: 228\r\n\r\n"
5754 "Alice was beginning to get very tired of sitting by her sister on the bank."
5755 "Alice was beginning to get very tired of sitting by her sister on the bank.";
5756 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5757 uint8_t httpbuf3[] =
"Alice was beginning to get very tired of sitting by her sister on the bank.\r\n\r\n";
5758 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5764 memset(&th_v, 0,
sizeof(th_v));
5765 memset(&f, 0,
sizeof(f));
5766 memset(&ssn, 0,
sizeof(ssn));
5773 f.
proto = IPPROTO_TCP;
5794 "(filestore; sid:1; rev:1;)");
5839 AppLayerGetFileState files = HTPGetTxFiles(tx_ptr, STREAM_TOCLIENT);
5861 static int HTPParserTest27(
void)
5864 memset(&cfg, 0,
sizeof(cfg));
5868 uint32_t
len = 1000;
5893 static void HTPParserRegisterTests(
void)
5915 UtRegisterTest(
"HTPParserDecodingTest01", HTPParserDecodingTest01);
5916 UtRegisterTest(
"HTPParserDecodingTest01a", HTPParserDecodingTest01a);
5917 UtRegisterTest(
"HTPParserDecodingTest02", HTPParserDecodingTest02);
5918 UtRegisterTest(
"HTPParserDecodingTest03", HTPParserDecodingTest03);
5919 UtRegisterTest(
"HTPParserDecodingTest04", HTPParserDecodingTest04);
5920 UtRegisterTest(
"HTPParserDecodingTest05", HTPParserDecodingTest05);
5921 UtRegisterTest(
"HTPParserDecodingTest06", HTPParserDecodingTest06);
5922 UtRegisterTest(
"HTPParserDecodingTest07", HTPParserDecodingTest07);
5923 UtRegisterTest(
"HTPParserDecodingTest08", HTPParserDecodingTest08);
5924 UtRegisterTest(
"HTPParserDecodingTest09", HTPParserDecodingTest09);
5926 UtRegisterTest(
"HTPBodyReassemblyTest01", HTPBodyReassemblyTest01);