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);
369 SCAppLayerTxDataCleanup(&htud->
tx_data);
393 if (s->
connp != NULL) {
397 uint64_t total_txs = HTPStateGetTxCnt(state);
399 if (s->
conn != NULL) {
400 for (tx_id = s->
tx_freed; tx_id < total_txs; tx_id++) {
401 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
404 HtpTxUserDataFree(s, htud);
405 htp_tx_set_user_data(tx, NULL);
409 htp_connp_destroy_all(s->
connp);
417 htp_state_memuse -=
sizeof(
HtpState);
418 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
431 static void HTPStateTransactionFree(
void *state, uint64_t
id)
439 htp_tx_t *tx = HTPStateGetTx(s,
id);
443 HtpTxUserDataFree(s, htud);
444 htp_tx_set_user_data(tx, NULL);
503 static void AppLayerHtpSetStreamDepthFlag(
void *tx,
const uint8_t
flags)
508 if (
flags & STREAM_TOCLIENT) {
518 SCLogDebug(
"cfg->body_limit %u stream_depth %u body->content_len_so_far %" PRIu64,
535 static uint32_t AppLayerHtpComputeChunkLength(uint64_t content_len_so_far, uint32_t body_limit,
536 uint32_t stream_depth, uint8_t
flags, uint32_t data_len)
538 uint32_t chunk_len = 0;
540 (content_len_so_far < (uint64_t)body_limit) &&
541 (content_len_so_far + (uint64_t)data_len) > body_limit)
543 chunk_len = (uint32_t)(body_limit - content_len_so_far);
545 (content_len_so_far < (uint64_t)stream_depth) &&
546 (content_len_so_far + (uint64_t)data_len) > stream_depth)
548 chunk_len = (uint32_t)(stream_depth - content_len_so_far);
551 return (chunk_len == 0 ? data_len : chunk_len);
579 {
"C-T multipart/byteranges in responses not supported",
606 {
"Request line: non-compliant delimiter between Method and URI",
615 {
"Transfer-encoding has abnormal chunked value",
617 {
"Chunked transfer-encoding on HTTP/0.9 or HTTP/1.0",
632 #define HTP_ERROR_MAX (sizeof(htp_errors) / sizeof(htp_errors[0]))
633 #define HTP_WARNING_MAX (sizeof(htp_warnings) / sizeof(htp_warnings[0]))
644 static uint8_t HTPHandleWarningGetId(
const char *
msg)
668 static uint8_t HTPHandleErrorGetId(
const char *
msg)
692 static void HTPHandleError(
HtpState *s,
const uint8_t dir)
694 if (s == NULL || s->
conn == NULL ||
695 s->
conn->messages == NULL) {
699 size_t size = htp_list_size(s->
conn->messages);
714 htp_log_t *log = htp_list_get(s->
conn->messages,
msg);
719 htp_tx_t *tx = log->tx;
725 uint8_t
id = HTPHandleErrorGetId(log->msg);
727 id = HTPHandleWarningGetId(log->msg);
733 HTPSetEvent(s, htud, dir,
id);
740 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s,
const htp_tx_t *tx)
743 BUG_ON(s == NULL || tx == NULL);
753 HTPSetEvent(s, htud, STREAM_TOSERVER,
789 htp_cfg_t *htp = cfglist.
cfg;
790 void *user_data = NULL;
806 if (user_data != NULL) {
807 htp_cfg_rec = user_data;
808 htp = htp_cfg_rec->
cfg;
811 SCLogDebug(
"Using default HTP config: %p", htp);
815 #ifdef DEBUG_VALIDATION
822 hstate->
connp = htp_connp_create(htp);
823 if (hstate->
connp == NULL) {
827 hstate->
conn = htp_connp_get_connection(hstate->
connp);
829 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
830 hstate->
cfg = htp_cfg_rec;
835 htp_connp_open(hstate->
connp, NULL, f->
sp, NULL, f->
dp, &
tv);
857 StreamSlice stream_slice,
void *local_data)
867 if (NULL == hstate->
conn) {
868 if (Setup(f, hstate) != 0) {
873 hstate->
slice = &stream_slice;
875 const uint8_t *input = StreamSliceGetData(&stream_slice);
876 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
881 const int r = htp_connp_req_data(hstate->
connp, &
ts, input, input_len);
889 HTPHandleError(hstate, STREAM_TOSERVER);
896 htp_connp_req_close(hstate->
connp, &
ts);
898 SCLogDebug(
"stream eof encountered, closing htp handle for ts");
902 hstate->
slice = NULL;
924 StreamSlice stream_slice,
void *local_data)
930 const uint8_t *input = StreamSliceGetData(&stream_slice);
931 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
937 if (NULL == hstate->
conn) {
938 if (Setup(f, hstate) != 0) {
943 hstate->
slice = &stream_slice;
947 uint32_t consumed = 0;
949 const int r = htp_connp_res_data(hstate->
connp, &
ts, input, input_len);
955 tx = htp_connp_get_out_tx(hstate->
connp);
965 consumed = (uint32_t)htp_connp_res_data_consumed(hstate->
connp);
971 hstate->
slice = NULL;
973 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
978 if (consumed > 0 && consumed < input_len) {
987 hstate->
slice = NULL;
989 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
994 if (consumed > 0 && consumed < input_len) {
1004 HTPHandleError(hstate, STREAM_TOCLIENT);
1011 htp_connp_close(hstate->
connp, &
ts);
1016 hstate->
slice = NULL;
1027 static int HTTPParseContentDispositionHeader(
const uint8_t *
name,
size_t name_len,
1028 const uint8_t *data,
size_t len, uint8_t
const **retptr,
size_t *retlen)
1031 printf(
"DATA START: \n");
1033 printf(
"DATA END: \n");
1038 for (x = 0; x <
len; x++) {
1039 if (!(isspace(data[x])))
1046 const uint8_t *line = data + x;
1047 size_t line_len =
len-x;
1050 printf(
"LINE START: \n");
1052 printf(
"LINE END: \n");
1054 for (x = 0 ; x < line_len; x++) {
1056 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
1060 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
1061 const uint8_t *token = line +
offset;
1062 size_t token_len = x -
offset;
1064 if ((x + 1) == line_len) {
1075 printf(
"TOKEN START: \n");
1077 printf(
"TOKEN END: \n");
1079 if (token_len > name_len) {
1080 if (
name == NULL || SCMemcmpLowercase(
name, token, name_len) == 0) {
1081 const uint8_t *value = token + name_len;
1082 size_t value_len = token_len - name_len;
1084 if (value[0] ==
'\"') {
1088 if (value[value_len-1] ==
'\"') {
1092 printf(
"VALUE START: \n");
1094 printf(
"VALUE END: \n");
1097 *retlen = value_len;
1121 static int HtpRequestBodySetupMultipart(
const htp_tx_t *tx,
HtpTxUserData *htud)
1143 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1146 chunks_buffer, chunks_buffer_len,
1150 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1153 if (tx && tx->
tx_data.de_state) {
1154 if (dir == STREAM_TOSERVER) {
1155 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1157 }
else if (dir == STREAM_TOCLIENT) {
1158 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1165 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len,
bool eof)
1168 printf(
"CHUNK START: \n");
1170 printf(
"CHUNK END: \n");
1178 const uint8_t *cur_buf = chunks_buffer;
1179 uint32_t cur_buf_len = chunks_buffer_len;
1195 const uint8_t *filename = NULL;
1196 uint16_t filename_len = 0;
1199 while (cur_buf_len > 0) {
1200 MimeParserResult r =
1201 SCMimeParse(htud->
mime_state, cur_buf, cur_buf_len, &consumed, &warnings);
1205 if (warnings & MIME_EVENT_FLAG_INVALID_HEADER) {
1209 if (warnings & MIME_EVENT_FLAG_NO_FILEDATA) {
1220 SCMimeStateGetFilename(htud->
mime_state, &filename, &filename_len);
1221 if (filename_len > 0) {
1225 hstate, htud, filename, filename_len, NULL, 0, STREAM_TOSERVER);
1228 }
else if (result == -2) {
1231 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1239 }
else if (result == -2) {
1247 uint32_t lastsize = consumed;
1248 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\n') {
1250 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\r') {
1254 HTPFileClose(htud, cur_buf, lastsize, 0, STREAM_TOSERVER);
1259 cur_buf += consumed;
1260 cur_buf_len -= consumed;
1272 const uint8_t *data, uint32_t data_len)
1279 uint8_t *filename = NULL;
1280 size_t filename_len = 0;
1283 if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) {
1284 filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path);
1285 filename_len = bstr_len(tx->parsed_uri->path);
1288 if (filename != NULL) {
1294 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1298 }
else if (result == -2) {
1301 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1315 }
else if (result == -2) {
1328 const uint8_t *data, uint32_t data_len)
1341 const uint8_t *filename = NULL;
1342 size_t filename_len = 0;
1348 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1354 if (filename == NULL) {
1356 if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) {
1357 filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path);
1358 filename_len = bstr_len(tx->parsed_uri->path);
1362 if (filename != NULL) {
1370 if (h_content_range != NULL) {
1372 data_len, tx, h_content_range->value, htud);
1374 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1380 }
else if (result == -2) {
1383 FlagDetectStateNewFile(htud, STREAM_TOCLIENT);
1396 }
else if (result == -2) {
1414 static int HTPCallbackRequestBodyData(htp_tx_data_t *d)
1425 printf(
"HTPBODY START: \n");
1427 printf(
"HTPBODY END: \n");
1430 HtpState *hstate = htp_connp_get_user_data(d->tx->connp);
1431 if (hstate == NULL) {
1435 SCLogDebug(
"New request body data available at %p -> %p -> %p, bodylen "
1440 if (tx_ud == NULL) {
1443 tx_ud->
tx_data.updated_ts =
true;
1454 }
else if (r == 0) {
1458 }
else if (d->htp_tx_request_method_number(tx) ==
HTP_METHOD_PUT) {
1479 const uint8_t *chunks_buffer = NULL;
1480 uint32_t chunks_buffer_len = 0;
1488 HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len);
1489 if (chunks_buffer == NULL) {
1493 printf(
"REASSCHUNK START: \n");
1495 printf(
"REASSCHUNK END: \n");
1498 HtpRequestBodyHandleMultipart(hstate, tx_ud,
htp_tx_data_tx(d), chunks_buffer,
1503 HtpRequestBodyHandlePOSTorPUT(
1509 SCLogDebug(
"closing file that was being stored");
1516 if (hstate->
conn != NULL) {
1517 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1518 ", last %" PRIu64
")",
1533 (uint64_t)UINT_MAX) {
1534 const uint32_t data_size =
1556 static int HTPCallbackResponseBodyData(htp_tx_data_t *d)
1566 HtpState *hstate = htp_connp_get_user_data(d->tx->connp);
1567 if (hstate == NULL) {
1571 SCLogDebug(
"New response body data available at %p -> %p -> %p, bodylen "
1576 if (tx_ud == NULL) {
1579 tx_ud->
tx_data.updated_tc =
true;
1601 HtpResponseBodyHandle(
1605 SCLogDebug(
"closing file that was being stored");
1611 if (hstate->
conn != NULL) {
1612 SCLogDebug(
"checking body size %" PRIu64
" against inspect limit %u (cur %" PRIu64
1613 ", last %" PRIu64
")",
1627 (uint64_t)UINT_MAX) {
1628 const uint32_t data_size =
1653 SCLogDebug(
"http_state_memcnt %"PRIu64
", http_state_memuse %"PRIu64
"",
1654 htp_state_memcnt, htp_state_memuse);
1672 htp_config_destroy(cfglist.
cfg);
1673 while (nextrec != NULL) {
1675 nextrec = nextrec->
next;
1677 htp_config_destroy(htprec->
cfg);
1685 static int HTPCallbackRequestHasTrailer(htp_tx_t *tx)
1689 htud->
tx_data.updated_ts =
true;
1695 static int HTPCallbackResponseHasTrailer(htp_tx_t *tx)
1699 htud->
tx_data.updated_tc =
true;
1709 static int HTPCallbackRequestStart(htp_tx_t *tx)
1711 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1712 if (hstate == NULL) {
1716 uint64_t consumed = hstate->
slice->offset + htp_connp_req_data_consumed(hstate->
connp);
1717 SCLogDebug(
"HTTP request start: data offset %" PRIu64
", in_data_counter %" PRIu64, consumed,
1735 if (tx_ud == NULL) {
1740 tx_ud->
tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT;
1741 htp_tx_set_user_data(tx, tx_ud);
1743 tx_ud->
tx_data.updated_ts =
true;
1752 static int HTPCallbackResponseStart(htp_tx_t *tx)
1754 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1755 if (hstate == NULL) {
1759 uint64_t consumed = hstate->
slice->offset + htp_connp_res_data_consumed(hstate->
connp);
1760 SCLogDebug(
"HTTP response start: data offset %" PRIu64
", out_data_counter %" PRIu64, consumed,
1776 if (tx_ud == NULL) {
1783 htp_tx_set_user_data(tx, tx_ud);
1785 tx_ud->
tx_data.updated_tc =
true;
1796 static int HTPCallbackRequestComplete(htp_tx_t *tx)
1804 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1805 if (hstate == NULL) {
1809 const uint64_t abs_right_edge =
1810 hstate->
slice->offset + htp_connp_req_data_consumed(hstate->
connp);
1818 SCLogDebug(
"HTTP request complete: data offset %" PRIu64
", request_size %" PRIu64,
1820 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1822 frame->
len = (int64_t)request_size;
1828 SCLogDebug(
"transaction_cnt %"PRIu64
", list_size %"PRIu64,
1833 HTPErrorCheckTxRequestFlags(hstate, tx);
1837 htud->
tx_data.updated_ts =
true;
1839 SCLogDebug(
"closing file that was being stored");
1842 if (abs_right_edge < (uint64_t)UINT32_MAX) {
1844 hstate->
f->
protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
1862 static int HTPCallbackResponseComplete(htp_tx_t *tx)
1866 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1867 if (hstate == NULL) {
1874 const uint64_t abs_right_edge =
1875 hstate->
slice->offset + htp_connp_res_data_consumed(hstate->
connp);
1882 SCLogDebug(
"HTTP response complete: data offset %" PRIu64
", response_size %" PRIu64,
1884 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1886 frame->
len = (int64_t)response_size;
1893 htud->
tx_data.updated_tc =
true;
1895 SCLogDebug(
"closing file that was being stored");
1929 static int HTPCallbackRequestLine(htp_tx_t *tx)
1932 bstr *request_uri_normalized;
1933 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1937 if (request_uri_normalized == NULL)
1940 tx_ud = htp_tx_get_user_data(tx);
1942 bstr_free(request_uri_normalized);
1950 HTPErrorCheckTxRequestFlags(hstate, tx);
1955 static int HTPCallbackDoubleDecodeUriPart(htp_tx_t *tx, bstr *part)
1961 size_t prevlen = bstr_len(part);
1962 htp_status_t res = htp_urldecode_inplace(tx->cfg, HTP_DECODER_URLENCODED, part, &
flags);
1968 HtpState *s = htp_connp_get_user_data(tx->connp);
1977 static int HTPCallbackDoubleDecodeQuery(htp_tx_t *tx)
1979 if (tx->parsed_uri == NULL)
1982 return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->query);
1985 static int HTPCallbackDoubleDecodePath(htp_tx_t *tx)
1987 if (tx->parsed_uri == NULL)
1990 return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->path);
1993 static int HTPCallbackRequestHeaderData(htp_tx_data_t *tx_data)
2000 if (tx_ud == NULL) {
2009 tx_ud->
tx_data.updated_ts =
true;
2022 static int HTPCallbackResponseHeaderData(htp_tx_data_t *tx_data)
2029 if (tx_ud == NULL) {
2032 tx_ud->
tx_data.updated_tc =
true;
2050 static void HTPConfigSetDefaultsPhase1(
HTPCfgRec *cfg_prec)
2067 htp_config_register_request_header_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
2068 htp_config_register_request_trailer_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
2069 htp_config_register_response_header_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
2070 htp_config_register_response_trailer_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
2072 htp_config_register_request_trailer(cfg_prec->
cfg, HTPCallbackRequestHasTrailer);
2073 htp_config_register_response_trailer(cfg_prec->
cfg, HTPCallbackResponseHasTrailer);
2075 htp_config_register_request_body_data(cfg_prec->
cfg, HTPCallbackRequestBodyData);
2076 htp_config_register_response_body_data(cfg_prec->
cfg, HTPCallbackResponseBodyData);
2078 htp_config_register_request_start(cfg_prec->
cfg, HTPCallbackRequestStart);
2079 htp_config_register_request_complete(cfg_prec->
cfg, HTPCallbackRequestComplete);
2081 htp_config_register_response_start(cfg_prec->
cfg, HTPCallbackResponseStart);
2082 htp_config_register_response_complete(cfg_prec->
cfg, HTPCallbackResponseComplete);
2084 htp_config_set_parse_request_cookies(cfg_prec->
cfg, 0);
2085 #ifdef HAVE_HTP_CONFIG_SET_ALLOW_SPACE_URI
2086 htp_config_set_allow_space_uri(cfg_prec->
cfg, 1);
2090 htp_config_set_plusspace_decode(cfg_prec->
cfg, HTP_DECODER_URLENCODED, 0);
2092 htp_config_set_request_decompression(cfg_prec->
cfg, 1);
2093 #ifdef HAVE_HTP_CONFIG_SET_LZMA_LAYERS
2097 #ifdef HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT
2098 htp_config_set_lzma_memlimit(cfg_prec->
cfg,
2101 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT
2102 htp_config_set_compression_bomb_limit(cfg_prec->
cfg,
2105 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
2108 #ifdef HAVE_HTP_CONFIG_SET_MAX_TX
2109 #define HTP_CONFIG_DEFAULT_MAX_TX_LIMIT 512
2110 htp_config_set_max_tx(cfg_prec->
cfg, HTP_CONFIG_DEFAULT_MAX_TX_LIMIT);
2112 #ifdef HAVE_HTP_CONFIG_SET_HEADERS_LIMIT
2113 #define HTP_CONFIG_DEFAULT_HEADERS_LIMIT 1024
2114 htp_config_set_number_headers_limit(cfg_prec->
cfg, HTP_CONFIG_DEFAULT_HEADERS_LIMIT);
2129 static int RandomGetWrap(
void)
2135 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
2137 return r % RAND_MAX;
2146 static void HTPConfigSetDefaultsPhase2(
const char *
name,
HTPCfgRec *cfg_prec)
2152 long int r = RandomGetWrap();
2154 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2156 r = RandomGetWrap();
2158 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2159 SCLogConfig(
"'%s' server has 'request-body-minimal-inspect-size' set to"
2160 " %u and 'request-body-inspect-window' set to %u after"
2164 r = RandomGetWrap();
2166 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2168 r = RandomGetWrap();
2170 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2172 SCLogConfig(
"'%s' server has 'response-body-minimal-inspect-size' set to"
2173 " %u and 'response-body-inspect-window' set to %u after"
2178 htp_config_register_request_line(cfg_prec->
cfg, HTPCallbackRequestLine);
2181 static void HTPConfigParseParameters(
HTPCfgRec *cfg_prec,
ConfNode *s,
struct HTPConfigTree *tree)
2183 if (cfg_prec == NULL || s == NULL || tree == NULL)
2190 if (strcasecmp(
"address", p->
name) == 0) {
2196 if (strchr(pval->
val,
':') != NULL) {
2197 SCLogDebug(
"LIBHTP adding ipv6 server %s at %s: %p",
2201 SCLogWarning(
"LIBHTP failed to add ipv6 server %s, ignoring", pval->
val);
2204 SCLogDebug(
"LIBHTP adding ipv4 server %s at %s: %p",
2208 SCLogWarning(
"LIBHTP failed to add ipv4 server %s, ignoring", pval->
val);
2213 }
else if (strcasecmp(
"personality", p->
name) == 0) {
2215 int personality = HTPLookupPersonality(p->
val);
2219 if (personality >= 0) {
2222 if (htp_config_set_server_personality(cfg_prec->
cfg, personality) ==
2225 "personality \"%s\", ignoring",
2229 HTPLookupPersonalityString(personality));
2235 htp_config_set_convert_lowercase(cfg_prec->
cfg, HTP_DECODER_URL_PATH, 0);
2243 }
else if (strcasecmp(
"request-body-limit", p->
name) == 0 ||
2244 strcasecmp(
"request_body_limit", p->
name) == 0) {
2246 SCLogError(
"Error parsing request-body-limit "
2247 "from conf file - %s. Killing engine",
2252 }
else if (strcasecmp(
"response-body-limit", p->
name) == 0) {
2254 SCLogError(
"Error parsing response-body-limit "
2255 "from conf file - %s. Killing engine",
2260 }
else if (strcasecmp(
"request-body-minimal-inspect-size", p->
name) == 0) {
2262 SCLogError(
"Error parsing request-body-minimal-inspect-size "
2263 "from conf file - %s. Killing engine",
2268 }
else if (strcasecmp(
"request-body-inspect-window", p->
name) == 0) {
2270 SCLogError(
"Error parsing request-body-inspect-window "
2271 "from conf file - %s. Killing engine",
2276 }
else if (strcasecmp(
"double-decode-query", p->
name) == 0) {
2278 htp_config_register_request_line(cfg_prec->
cfg,
2279 HTPCallbackDoubleDecodeQuery);
2282 }
else if (strcasecmp(
"double-decode-path", p->
name) == 0) {
2284 htp_config_register_request_line(cfg_prec->
cfg,
2285 HTPCallbackDoubleDecodePath);
2288 }
else if (strcasecmp(
"response-body-minimal-inspect-size", p->
name) == 0) {
2290 SCLogError(
"Error parsing response-body-minimal-inspect-size "
2291 "from conf file - %s. Killing engine",
2296 }
else if (strcasecmp(
"response-body-inspect-window", p->
name) == 0) {
2298 SCLogError(
"Error parsing response-body-inspect-window "
2299 "from conf file - %s. Killing engine",
2304 }
else if (strcasecmp(
"response-body-decompress-layer-limit", p->
name) == 0) {
2307 SCLogError(
"Error parsing response-body-inspect-window "
2308 "from conf file - %s. Killing engine",
2312 #ifdef HAVE_HTP_CONFIG_SET_RESPONSE_DECOMPRESSION_LAYER_LIMIT
2313 htp_config_set_response_decompression_layer_limit(cfg_prec->
cfg, value);
2315 SCLogWarning(
"can't set response-body-decompress-layer-limit "
2316 "to %u, libhtp version too old",
2319 }
else if (strcasecmp(
"path-convert-backslash-separators", p->
name) == 0) {
2320 htp_config_set_backslash_convert_slashes(cfg_prec->
cfg,
2321 HTP_DECODER_URL_PATH,
2323 }
else if (strcasecmp(
"path-bestfit-replacement-char", p->
name) == 0) {
2324 if (strlen(p->
val) == 1) {
2325 htp_config_set_bestfit_replacement_byte(cfg_prec->
cfg,
2326 HTP_DECODER_URL_PATH,
2330 "for libhtp param path-bestfit-replacement-char");
2332 }
else if (strcasecmp(
"path-convert-lowercase", p->
name) == 0) {
2333 htp_config_set_convert_lowercase(cfg_prec->
cfg,
2334 HTP_DECODER_URL_PATH,
2336 }
else if (strcasecmp(
"path-nul-encoded-terminates", p->
name) == 0) {
2337 htp_config_set_nul_encoded_terminates(cfg_prec->
cfg,
2338 HTP_DECODER_URL_PATH,
2340 }
else if (strcasecmp(
"path-nul-raw-terminates", p->
name) == 0) {
2341 htp_config_set_nul_raw_terminates(cfg_prec->
cfg,
2342 HTP_DECODER_URL_PATH,
2344 }
else if (strcasecmp(
"path-separators-compress", p->
name) == 0) {
2345 htp_config_set_path_separators_compress(cfg_prec->
cfg,
2346 HTP_DECODER_URL_PATH,
2348 }
else if (strcasecmp(
"path-separators-decode", p->
name) == 0) {
2349 htp_config_set_path_separators_decode(cfg_prec->
cfg,
2350 HTP_DECODER_URL_PATH,
2352 }
else if (strcasecmp(
"path-u-encoding-decode", p->
name) == 0) {
2353 htp_config_set_u_encoding_decode(cfg_prec->
cfg,
2354 HTP_DECODER_URL_PATH,
2356 }
else if (strcasecmp(
"path-url-encoding-invalid-handling", p->
name) == 0) {
2357 enum htp_url_encoding_handling_t handling;
2358 if (strcasecmp(p->
val,
"preserve_percent") == 0) {
2359 handling = HTP_URL_DECODE_PRESERVE_PERCENT;
2360 }
else if (strcasecmp(p->
val,
"remove_percent") == 0) {
2361 handling = HTP_URL_DECODE_REMOVE_PERCENT;
2362 }
else if (strcasecmp(p->
val,
"decode_invalid") == 0) {
2363 handling = HTP_URL_DECODE_PROCESS_INVALID;
2366 "for libhtp param path-url-encoding-invalid-handling");
2369 htp_config_set_url_encoding_invalid_handling(cfg_prec->
cfg,
2370 HTP_DECODER_URL_PATH,
2372 }
else if (strcasecmp(
"path-utf8-convert-bestfit", p->
name) == 0) {
2373 htp_config_set_utf8_convert_bestfit(cfg_prec->
cfg,
2374 HTP_DECODER_URL_PATH,
2376 }
else if (strcasecmp(
"uri-include-all", p->
name) == 0) {
2380 }
else if (strcasecmp(
"query-plusspace-decode", p->
name) == 0) {
2381 htp_config_set_plusspace_decode(cfg_prec->
cfg,
2382 HTP_DECODER_URLENCODED,
2384 }
else if (strcasecmp(
"meta-field-limit", p->
name) == 0) {
2388 "from conf file - %s. Killing engine",
2394 "from conf file cannot be 0. Killing engine");
2397 htp_config_set_field_limits(cfg_prec->
cfg,
2400 #ifdef HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT
2401 }
else if (strcasecmp(
"lzma-memlimit", p->
name) == 0) {
2404 FatalError(
"failed to parse 'lzma-memlimit' "
2405 "from conf file - %s.",
2410 "from conf file cannot be 0.");
2413 SCLogConfig(
"Setting HTTP LZMA memory limit to %"PRIu32
" bytes", limit);
2414 htp_config_set_lzma_memlimit(cfg_prec->
cfg, (
size_t)limit);
2416 #ifdef HAVE_HTP_CONFIG_SET_LZMA_LAYERS
2417 }
else if (strcasecmp(
"lzma-enabled", p->
name) == 0) {
2419 htp_config_set_lzma_layers(cfg_prec->
cfg, 1);
2424 "from conf file - %s.",
2427 SCLogConfig(
"Setting HTTP LZMA decompression layers to %" PRIu32
"", (
int)limit);
2428 htp_config_set_lzma_layers(cfg_prec->
cfg, limit);
2431 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT
2432 }
else if (strcasecmp(
"compression-bomb-limit", p->
name) == 0) {
2435 FatalError(
"failed to parse 'compression-bomb-limit' "
2436 "from conf file - %s.",
2441 "from conf file cannot be 0.");
2444 SCLogConfig(
"Setting HTTP compression bomb limit to %"PRIu32
" bytes", limit);
2445 htp_config_set_compression_bomb_limit(cfg_prec->
cfg, (
size_t)limit);
2447 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
2448 }
else if (strcasecmp(
"decompression-time-limit", p->
name) == 0) {
2452 FatalError(
"failed to parse 'decompression-time-limit' "
2453 "from conf file - %s.",
2456 SCLogConfig(
"Setting HTTP decompression time limit to %" PRIu32
" usec", limit);
2457 htp_config_set_compression_time_limit(cfg_prec->
cfg, (
size_t)limit);
2459 #ifdef HAVE_HTP_CONFIG_SET_MAX_TX
2460 }
else if (strcasecmp(
"max-tx", p->
name) == 0) {
2464 "from conf file - %s.",
2468 SCLogConfig(
"Setting HTTP max-tx limit to %" PRIu32
" bytes", limit);
2469 htp_config_set_max_tx(cfg_prec->
cfg, limit);
2471 #ifdef HAVE_HTP_CONFIG_SET_HEADERS_LIMIT
2472 }
else if (strcasecmp(
"headers-limit", p->
name) == 0) {
2475 FatalError(
"failed to parse 'headers-limit' "
2476 "from conf file - %s.",
2479 SCLogConfig(
"Setting HTTP headers limit to %" PRIu32, limit);
2480 htp_config_set_number_headers_limit(cfg_prec->
cfg, limit);
2482 }
else if (strcasecmp(
"randomize-inspection-sizes", p->
name) == 0) {
2486 }
else if (strcasecmp(
"randomize-inspection-range", p->
name) == 0) {
2489 (
const char *)p->
val, 0, 100) < 0) {
2491 "-inspection-range setting from conf file - \"%s\"."
2492 " It should be a valid integer less than or equal to 100."
2498 }
else if (strcasecmp(
"http-body-inline", p->
name) == 0) {
2504 if (strcmp(
"auto", p->
val) != 0) {
2513 }
else if (strcasecmp(
"swf-decompression", p->
name) == 0) {
2517 if (strcasecmp(
"enabled", pval->
name) == 0) {
2525 }
else if (strcasecmp(
"type", pval->
name) == 0) {
2526 if (strcasecmp(
"no", pval->
val) == 0) {
2528 }
else if (strcasecmp(
"deflate", pval->
val) == 0) {
2530 }
else if (strcasecmp(
"lzma", pval->
val) == 0) {
2532 }
else if (strcasecmp(
"both", pval->
val) == 0) {
2536 "swf-decompression.type: %s - "
2541 }
else if (strcasecmp(
"compress-depth", pval->
name) == 0) {
2543 SCLogError(
"Error parsing swf-decompression.compression-depth "
2544 "from conf file - %s. Killing engine",
2548 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2550 SCLogError(
"Error parsing swf-decompression.decompression-depth "
2551 "from conf file - %s. Killing engine",
2561 "default config: %s",
2571 cfglist.
next = NULL;
2578 cfglist.
cfg = htp_config_create();
2579 if (NULL == cfglist.
cfg) {
2580 FatalError(
"Failed to create HTP default config");
2583 HTPConfigSetDefaultsPhase1(&cfglist);
2584 if (
ConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2585 HTPConfigParseParameters(&cfglist,
ConfGetNode(
"libhtp.default-config"), &cfgtree);
2587 HTPConfigParseParameters(
2588 &cfglist,
ConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), &cfgtree);
2590 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2596 if (server_config == NULL) {
2597 server_config =
ConfGetNode(
"libhtp.server-config");
2598 if (server_config == NULL) {
2599 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2603 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2622 cfglist.
next = htprec;
2625 cfglist.
next->
cfg = htp_config_create();
2626 if (NULL == cfglist.
next->
cfg) {
2627 FatalError(
"Failed to create HTP server config");
2630 HTPConfigSetDefaultsPhase1(htprec);
2631 HTPConfigParseParameters(htprec, s, &cfgtree);
2632 HTPConfigSetDefaultsPhase2(s->
name, htprec);
2642 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
2653 static AppLayerGetFileState HTPGetTxFiles(
void *txv, uint8_t direction)
2655 AppLayerGetFileState files = { .fc = NULL, .cfg = &
htp_sbcfg };
2656 htp_tx_t *tx = (htp_tx_t *)txv;
2659 if (direction & STREAM_TOCLIENT) {
2668 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
2670 if (direction & STREAM_TOSERVER)
2671 return ((htp_tx_t *)tx)->request_progress;
2673 return ((htp_tx_t *)tx)->response_progress;
2676 static uint64_t HTPStateGetTxCnt(
void *alstate)
2680 if (http_state != NULL && http_state->
conn != NULL) {
2681 const int64_t size = (int64_t)htp_list_size(http_state->
conn->transactions);
2685 return (uint64_t)size + http_state->
tx_freed;
2691 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
2695 if (http_state != NULL && http_state->
conn != NULL && tx_id >= http_state->
tx_freed)
2696 return htp_list_get(http_state->
conn->transactions, tx_id - http_state->
tx_freed);
2705 if (http_state != NULL && http_state->
conn != NULL) {
2706 size_t txid = HTPStateGetTxCnt(http_state);
2708 return htp_list_get(http_state->
conn->transactions, txid - http_state->
tx_freed - 1);
2714 static int HTPStateGetEventInfo(
2715 const char *event_name, uint8_t *event_id, AppLayerEventType *event_type)
2718 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2724 static int HTPStateGetEventInfoById(
2725 uint8_t event_id,
const char **event_name, AppLayerEventType *event_type)
2728 if (*event_name == NULL) {
2730 "http's enum map table.",
2736 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2743 htp_tx_t *tx = (htp_tx_t *)vtx;
2751 static AppLayerStateData *HTPGetStateData(
void *vstate)
2757 static int HTPRegisterPatternsForProtocolDetection(
void)
2759 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
2760 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
2761 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
2762 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
2763 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
2764 const char *spacings[] = {
"|20|",
"|09|", NULL };
2765 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
2770 int register_result;
2771 char method_buffer[32] =
"";
2774 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
2775 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
2778 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
2785 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
2786 if (register_result < 0) {
2793 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
2795 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
2797 if (register_result < 0) {
2813 const char *proto_name =
"http";
2818 if (HTPRegisterPatternsForProtocolDetection() < 0)
2821 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
2848 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
2850 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
2856 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
2859 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
2863 SCLogInfo(
"Parser disabled for %s protocol. Protocol detection still on.", proto_name);
2879 cfglist_backup = cfglist;
2884 cfglist = cfglist_backup;
2889 static int HTPParserTest01(
void)
2891 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2893 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2896 memset(&ssn, 0,
sizeof(ssn));
2904 f->
proto = IPPROTO_TCP;
2910 for (u = 0; u < httplen1; u++) {
2914 flags = STREAM_TOSERVER|STREAM_START;
2915 else if (u == (httplen1 - 1))
2916 flags = STREAM_TOSERVER|STREAM_EOF;
2918 flags = STREAM_TOSERVER;
2927 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2944 static int HTPParserTest01b(
void)
2946 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2948 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2951 memset(&ssn, 0,
sizeof(ssn));
2959 f->
proto = IPPROTO_TCP;
2964 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
2971 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2988 static int HTPParserTest01c(
void)
2990 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2992 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2995 memset(&ssn, 0,
sizeof(ssn));
3003 f->
proto = IPPROTO_TCP;
3009 for (u = 0; u < httplen1; u++) {
3013 flags = STREAM_TOSERVER|STREAM_START;
3014 else if (u == (httplen1 - 1))
3015 flags = STREAM_TOSERVER|STREAM_EOF;
3017 flags = STREAM_TOSERVER;
3026 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3044 static int HTPParserTest01a(
void)
3047 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3049 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3054 memset(&ssn, 0,
sizeof(ssn));
3056 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3059 f->
proto = IPPROTO_TCP;
3065 for (u = 0; u < httplen1; u++) {
3069 flags = STREAM_TOSERVER|STREAM_START;
3070 else if (u == (httplen1 - 1))
3071 flags = STREAM_TOSERVER|STREAM_EOF;
3073 flags = STREAM_TOSERVER;
3082 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3099 static int HTPParserTest02(
void)
3102 uint8_t httpbuf1[] =
"POST";
3103 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3108 memset(&ssn, 0,
sizeof(ssn));
3110 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3113 f->
proto = IPPROTO_TCP;
3119 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3125 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3134 FAIL_IF(strcmp(method,
"POST") != 0);
3145 static int HTPParserTest03(
void)
3148 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
3149 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3154 memset(&ssn, 0,
sizeof(ssn));
3156 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3159 f->
proto = IPPROTO_TCP;
3165 for (u = 0; u < httplen1; u++) {
3168 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3169 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3170 else flags = STREAM_TOSERVER;
3178 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3194 static int HTPParserTest04(
void)
3198 uint8_t httpbuf1[] =
"World!\r\n";
3199 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3203 memset(&ssn, 0,
sizeof(ssn));
3205 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3208 f->
proto = IPPROTO_TCP;
3214 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3220 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3236 static int HTPParserTest05(
void)
3238 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3239 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3240 uint8_t httpbuf2[] =
"Post D";
3241 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3242 uint8_t httpbuf3[] =
"ata is c0oL!";
3243 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3245 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3246 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3247 uint8_t httpbuf5[] =
"post R";
3248 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3249 uint8_t httpbuf6[] =
"esults are tha bomb!";
3250 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3253 memset(&ssn, 0,
sizeof(ssn));
3261 f->
proto = IPPROTO_TCP;
3291 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3309 static int HTPParserTest06(
void)
3311 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3312 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3313 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3314 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3315 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3317 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3318 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3319 "FrontPage/5.0.2.2510\r\n"
3320 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3322 "Content-Type: text/html\r\n\r\n"
3324 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3325 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3326 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3327 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3328 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3329 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3330 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3331 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3332 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3333 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3334 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3335 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3336 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3337 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3338 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3339 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3340 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3341 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3342 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3343 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3344 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3345 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3346 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3347 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3348 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3349 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3350 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3351 "aHA=\r\n0\r\n\r\n";
3352 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3358 memset(&ssn, 0,
sizeof(ssn));
3363 f->
proto = IPPROTO_TCP;
3378 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3398 static int HTPParserTest07(
void)
3401 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3402 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3407 memset(&ssn, 0,
sizeof(ssn));
3409 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3412 f->
proto = IPPROTO_TCP;
3418 for (u = 0; u < httplen1; u++) {
3422 flags = STREAM_TOSERVER|STREAM_START;
3423 else if (u == (httplen1 - 1))
3424 flags = STREAM_TOSERVER|STREAM_EOF;
3426 flags = STREAM_TOSERVER;
3435 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3436 size_t reflen =
sizeof(ref) - 1;
3438 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3459 static int HTPParserTest08(
void)
3462 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3463 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3484 memset(&ssn, 0,
sizeof(ssn));
3486 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3489 f->
proto = IPPROTO_TCP;
3494 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3502 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3522 static int HTPParserTest09(
void)
3525 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3526 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3536 personality: Apache_2_2\n\
3548 memset(&ssn, 0,
sizeof(ssn));
3550 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3553 f->
proto = IPPROTO_TCP;
3558 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3566 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3587 static int HTPParserTest10(
void)
3591 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3592 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3597 memset(&ssn, 0,
sizeof(ssn));
3599 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3602 f->
proto = IPPROTO_TCP;
3608 for (u = 0; u < httplen1; u++) {
3612 flags = STREAM_TOSERVER|STREAM_START;
3613 else if (u == (httplen1 - 1))
3614 flags = STREAM_TOSERVER|STREAM_EOF;
3616 flags = STREAM_TOSERVER;
3625 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3635 FAIL_IF(strcmp(value,
"www.google.com") != 0);
3647 static int HTPParserTest11(
void)
3650 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3651 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3656 memset(&ssn, 0,
sizeof(ssn));
3658 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3661 f->
proto = IPPROTO_TCP;
3667 for (u = 0; u < httplen1; u++) {
3671 flags = STREAM_TOSERVER|STREAM_START;
3672 else if (u == (httplen1 - 1))
3673 flags = STREAM_TOSERVER|STREAM_EOF;
3675 flags = STREAM_TOSERVER;
3684 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3706 static int HTPParserTest12(
void)
3709 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3710 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3715 memset(&ssn, 0,
sizeof(ssn));
3717 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3720 f->
proto = IPPROTO_TCP;
3726 for (u = 0; u < httplen1; u++) {
3730 flags = STREAM_TOSERVER|STREAM_START;
3731 else if (u == (httplen1 - 1))
3732 flags = STREAM_TOSERVER|STREAM_EOF;
3734 flags = STREAM_TOSERVER;
3743 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3767 static int HTPParserTest13(
void)
3770 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3771 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3776 memset(&ssn, 0,
sizeof(ssn));
3778 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3781 f->
proto = IPPROTO_TCP;
3787 for (u = 0; u < httplen1; u++) {
3791 flags = STREAM_TOSERVER|STREAM_START;
3792 else if (u == (httplen1 - 1))
3793 flags = STREAM_TOSERVER|STREAM_EOF;
3795 flags = STREAM_TOSERVER;
3803 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3813 FAIL_IF(strcmp(value,
"www.google.com\rName: Value") != 0);
3825 static int HTPParserConfigTest01(
void)
3838 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3839 personality: Tomcat_6_0\n\
3844 - 192.168.10.0/24\n\
3845 personality: IIS_7_0\n\
3854 outputs =
ConfGetNode(
"libhtp.default-config.personality");
3865 FAIL_IF(strcmp(node->
name,
"apache-tomcat") != 0);
3872 FAIL_IF(strcmp(node2->
val,
"Tomcat_6_0") != 0);
3882 FAIL_IF(strcmp(n->
val,
"192.168.1.0/24") != 0);
3922 FAIL_IF(strcmp(n->
val,
"192.168.0.0/24") != 0);
3926 FAIL_IF(strcmp(n->
val,
"192.168.10.0/24") != 0);
3941 static int HTPParserConfigTest02(
void)
3954 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3955 personality: Tomcat_6_0\n\
3960 - 192.168.10.0/24\n\
3961 personality: IIS_7_0\n\
3973 htp_cfg_t *htp = cfglist.
cfg;
3976 void *user_data = NULL;
3978 addr =
"192.168.10.42";
3979 FAIL_IF(inet_pton(AF_INET, addr, buf) != 1);
3983 htp = htp_cfg_rec->
cfg;
3989 FAIL_IF(inet_pton(AF_INET6, addr, buf) != 1);
3992 htp_cfg_rec = user_data;
3993 htp = htp_cfg_rec->
cfg;
4006 static int HTPParserConfigTest03(
void)
4009 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
4011 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4027 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
4028 personality: Tomcat_6_0\n\
4033 - 192.168.10.0/24\n\
4034 personality: IIS_7_0\n\
4045 const char *addr =
"192.168.10.42";
4047 memset(&ssn, 0,
sizeof(ssn));
4052 f->
proto = IPPROTO_TCP;
4055 htp_cfg_t *htp = cfglist.
cfg;
4058 void *user_data = NULL;
4063 htp = htp_cfg_rec->
cfg;
4070 for (u = 0; u < httplen1; u++) {
4073 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4074 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4075 else flags = STREAM_TOSERVER;
4084 FAIL_IF(HTPStateGetTxCnt(htp_state) != 2);
4086 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4090 tx = HTPStateGetTx(htp_state, 1);
4111 static int HTPParserDecodingTest01(
void)
4113 uint8_t httpbuf1[] =
4114 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4115 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4116 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4117 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4128 personality: Apache_2\n\
4136 const char *addr =
"4.3.2.1";
4137 memset(&ssn, 0,
sizeof(ssn));
4142 f->
proto = IPPROTO_TCP;
4147 for (uint32_t u = 0; u < httplen1; u++) {
4149 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4150 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4151 else flags = STREAM_TOSERVER;
4160 uint8_t ref1[] =
"/abc%2fdef";
4161 size_t reflen =
sizeof(ref1) - 1;
4163 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4173 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4174 reflen =
sizeof(ref2) - 1;
4176 tx = HTPStateGetTx(htp_state, 1);
4186 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4187 reflen =
sizeof(ref3) - 1;
4188 tx = HTPStateGetTx(htp_state, 2);
4209 static int HTPParserDecodingTest01a(
void)
4211 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4212 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4213 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4214 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4225 personality: Apache_2\n\
4233 const char *addr =
"4.3.2.1";
4234 memset(&ssn, 0,
sizeof(ssn));
4239 f->
proto = IPPROTO_TCP;
4245 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4251 uint8_t ref1[] =
"/abc%2fdef";
4252 size_t reflen =
sizeof(ref1) - 1;
4254 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4264 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4265 reflen =
sizeof(ref2) - 1;
4267 tx = HTPStateGetTx(htp_state, 1);
4277 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4278 reflen =
sizeof(ref3) - 1;
4279 tx = HTPStateGetTx(htp_state, 2);
4306 static int HTPParserDecodingTest02(
void)
4309 uint8_t httpbuf1[] =
4310 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4311 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4312 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4313 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4325 double-decode-path: no\n\
4326 double-decode-query: no\n\
4334 const char *addr =
"4.3.2.1";
4335 memset(&ssn, 0,
sizeof(ssn));
4340 f->
proto = IPPROTO_TCP;
4346 for (u = 0; u < httplen1; u++) {
4349 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4350 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4351 else flags = STREAM_TOSERVER;
4360 uint8_t ref1[] =
"/abc/def";
4361 size_t reflen =
sizeof(ref1) - 1;
4363 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4372 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4373 reflen =
sizeof(ref2) - 1;
4375 tx = HTPStateGetTx(htp_state, 1);
4385 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4386 reflen =
sizeof(ref3) - 1;
4387 tx = HTPStateGetTx(htp_state, 2);
4413 static int HTPParserDecodingTest03(
void)
4416 uint8_t httpbuf1[] =
4417 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4418 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4419 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4431 double-decode-path: yes\n\
4432 double-decode-query: yes\n\
4440 const char *addr =
"4.3.2.1";
4441 memset(&ssn, 0,
sizeof(ssn));
4446 f->
proto = IPPROTO_TCP;
4452 for (u = 0; u < httplen1; u++) {
4455 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4456 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4457 else flags = STREAM_TOSERVER;
4466 uint8_t ref1[] =
"/abc/def";
4467 size_t reflen =
sizeof(ref1) - 1;
4469 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4479 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4480 reflen =
sizeof(ref2) - 1;
4482 tx = HTPStateGetTx(htp_state, 1);
4505 static int HTPParserDecodingTest04(
void)
4508 uint8_t httpbuf1[] =
4509 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4510 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4522 double-decode-path: yes\n\
4523 double-decode-query: yes\n\
4531 const char *addr =
"4.3.2.1";
4532 memset(&ssn, 0,
sizeof(ssn));
4537 f->
proto = IPPROTO_TCP;
4543 for (u = 0; u < httplen1; u++) {
4546 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4547 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4548 else flags = STREAM_TOSERVER;
4557 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
4558 size_t reflen =
sizeof(ref1) - 1;
4560 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4583 static int HTPParserDecodingTest05(
void)
4586 uint8_t httpbuf1[] =
4587 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4588 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4600 double-decode-path: yes\n\
4601 double-decode-query: yes\n\
4609 const char *addr =
"4.3.2.1";
4610 memset(&ssn, 0,
sizeof(ssn));
4615 f->
proto = IPPROTO_TCP;
4621 for (u = 0; u < httplen1; u++) {
4624 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4625 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4626 else flags = STREAM_TOSERVER;
4635 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
4636 size_t reflen =
sizeof(ref1) - 1;
4638 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4661 static int HTPParserDecodingTest06(
void)
4664 uint8_t httpbuf1[] =
4665 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4666 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4678 double-decode-path: yes\n\
4679 double-decode-query: yes\n\
4687 const char *addr =
"4.3.2.1";
4688 memset(&ssn, 0,
sizeof(ssn));
4693 f->
proto = IPPROTO_TCP;
4699 for (u = 0; u < httplen1; u++) {
4702 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4703 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4704 else flags = STREAM_TOSERVER;
4713 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
4714 size_t reflen =
sizeof(ref1) - 1;
4716 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4739 static int HTPParserDecodingTest07(
void)
4742 uint8_t httpbuf1[] =
4743 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4744 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4756 double-decode-path: yes\n\
4757 double-decode-query: yes\n\
4758 query-plusspace-decode: yes\n\
4766 const char *addr =
"4.3.2.1";
4767 memset(&ssn, 0,
sizeof(ssn));
4772 f->
proto = IPPROTO_TCP;
4778 for (u = 0; u < httplen1; u++) {
4781 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4782 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4783 else flags = STREAM_TOSERVER;
4792 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
4793 size_t reflen =
sizeof(ref1) - 1;
4795 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4818 static int HTPParserDecodingTest08(
void)
4821 uint8_t httpbuf1[] =
4822 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4823 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4842 const char *addr =
"4.3.2.1";
4843 memset(&ssn, 0,
sizeof(ssn));
4848 f->
proto = IPPROTO_TCP;
4854 for (u = 0; u < httplen1; u++) {
4857 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4858 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4859 else flags = STREAM_TOSERVER;
4868 uint8_t ref1[] =
"/blah/";
4869 size_t reflen =
sizeof(ref1) - 1;
4871 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4894 static int HTPParserDecodingTest09(
void)
4897 uint8_t httpbuf1[] =
4898 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4899 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4911 uri-include-all: true\n\
4919 const char *addr =
"4.3.2.1";
4920 memset(&ssn, 0,
sizeof(ssn));
4925 f->
proto = IPPROTO_TCP;
4931 for (u = 0; u < httplen1; u++) {
4934 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4935 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4936 else flags = STREAM_TOSERVER;
4945 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
4946 size_t reflen =
sizeof(ref1) - 1;
4948 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4970 static int HTPBodyReassemblyTest01(
void)
4973 memset(&htud, 0x00,
sizeof(htud));
4975 memset(&hstate, 0x00,
sizeof(hstate));
4977 memset(&flow, 0x00,
sizeof(flow));
4980 memset(&tx, 0,
sizeof(tx));
4985 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
4986 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";
4993 const uint8_t *chunks_buffer = NULL;
4994 uint32_t chunks_buffer_len = 0;
4996 HtpRequestBodyReassemble(&htud, &chunks_buffer, &chunks_buffer_len);
4999 printf(
"REASSCHUNK START: \n");
5001 printf(
"REASSCHUNK END: \n");
5004 htud.
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
5005 strlen(
"multipart/form-data; boundary=toto"));
5008 HtpRequestBodyHandleMultipart(&hstate, &htud, &tx, chunks_buffer, chunks_buffer_len,
false);
5018 static int HTPSegvTest01(
void)
5021 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";
5022 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5030 double-decode-path: no\n\
5031 double-decode-query: no\n\
5032 request-body-limit: 0\n\
5033 response-body-limit: 0\n\
5046 memset(&ssn, 0,
sizeof(ssn));
5048 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5051 f->
proto = IPPROTO_TCP;
5056 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
5060 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
5081 static int HTPParserTest14(
void)
5092 double-decode-path: no\n\
5093 double-decode-query: no\n\
5094 request-body-limit: 0\n\
5095 response-body-limit: 0\n\
5100 memset(&ssn, 0,
sizeof(ssn));
5110 memset(httpbuf, 0x00,
len);
5113 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5114 "Host: myhost.lan\r\n"
5115 "Connection: keep-alive\r\n"
5117 "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"
5118 "Referer: http://blah.lan/\r\n"
5119 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5121 size_t o = strlen(httpbuf);
5122 for ( ; o <
len - 4; o++) {
5125 httpbuf[
len - 4] =
'\r';
5126 httpbuf[
len - 3] =
'\n';
5127 httpbuf[
len - 2] =
'\r';
5128 httpbuf[
len - 1] =
'\n';
5134 f->
proto = IPPROTO_TCP;
5139 for (u = 0; u <
len; u++) {
5142 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5143 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5144 else flags = STREAM_TOSERVER;
5152 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5177 static int HTPParserTest15(
void)
5180 char *httpbuf = NULL;
5191 double-decode-path: no\n\
5192 double-decode-query: no\n\
5193 request-body-limit: 0\n\
5194 response-body-limit: 0\n\
5195 meta-field-limit: 20000\n\
5199 memset(&ssn, 0,
sizeof(ssn));
5210 memset(httpbuf, 0x00,
len);
5213 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5214 "Host: myhost.lan\r\n"
5215 "Connection: keep-alive\r\n"
5217 "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"
5218 "Referer: http://blah.lan/\r\n"
5219 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5221 size_t o = strlen(httpbuf);
5222 for ( ; o <
len - 4; o++) {
5225 httpbuf[
len - 4] =
'\r';
5226 httpbuf[
len - 3] =
'\n';
5227 httpbuf[
len - 2] =
'\r';
5228 httpbuf[
len - 1] =
'\n';
5230 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5233 f->
proto = IPPROTO_TCP;
5239 for (u = 0; u <
len; u++) {
5242 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5243 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5244 else flags = STREAM_TOSERVER;
5253 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5275 static int HTPParserTest16(
void)
5282 memset(&ssn, 0,
sizeof(ssn));
5284 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5285 "Host: myhost.lan\r\n"
5286 "Connection: keep-alive\r\n"
5288 "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"
5289 "Referer: http://blah.lan/\r\n"
5290 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5291 "Cookie: blah\r\n\r\n";
5292 size_t len =
sizeof(httpbuf) - 1;
5294 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5297 f->
proto = IPPROTO_TCP;
5302 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5310 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5315 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5335 static int HTPParserTest20(
void)
5338 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5339 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5340 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5341 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5342 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
5343 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5344 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5345 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5351 memset(&ssn, 0,
sizeof(ssn));
5353 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5356 f->
proto = IPPROTO_TCP;
5375 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5394 static int HTPParserTest21(
void)
5397 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5398 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5399 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5400 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5401 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
5402 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5403 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5404 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5410 memset(&ssn, 0,
sizeof(ssn));
5412 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5415 f->
proto = IPPROTO_TCP;
5434 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5453 static int HTPParserTest22(
void)
5456 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5457 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5458 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5459 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5460 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
5461 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5462 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5468 memset(&ssn, 0,
sizeof(ssn));
5470 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5473 f->
proto = IPPROTO_TCP;
5488 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5507 static int HTPParserTest23(
void)
5510 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5511 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5512 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5513 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5514 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
5515 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5516 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5522 memset(&ssn, 0,
sizeof(ssn));
5524 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5527 f->
proto = IPPROTO_TCP;
5542 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5561 static int HTPParserTest24(
void)
5564 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5565 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5566 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5567 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5568 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
5569 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5570 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5576 memset(&ssn, 0,
sizeof(ssn));
5578 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5581 f->
proto = IPPROTO_TCP;
5596 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5614 static int HTPParserTest25(
void)
5621 memset(&ssn, 0,
sizeof(ssn));
5626 f->
proto = IPPROTO_TCP;
5630 const char *
str =
"GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
5632 (uint8_t *)
str, strlen(
str));
5656 str =
"HTTP 1.1 200 OK\r\nServer: Suricata/1.0\r\nContent-Length: 8\r\n\r\nSuricata";
5658 (uint8_t *)
str, strlen(
str));
5692 (uint8_t *)
str, strlen(
str));
5703 (uint8_t *)
str, strlen(
str));
5723 static int HTPParserTest26(
void)
5732 request-body-limit: 1\n\
5733 response-body-limit: 1\n\
5747 uint8_t httpbuf1[] =
"GET /alice.txt HTTP/1.1\r\n\r\n";
5748 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5749 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\n"
5750 "Content-Type: text/plain\r\n"
5751 "Content-Length: 228\r\n\r\n"
5752 "Alice was beginning to get very tired of sitting by her sister on the bank."
5753 "Alice was beginning to get very tired of sitting by her sister on the bank.";
5754 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5755 uint8_t httpbuf3[] =
"Alice was beginning to get very tired of sitting by her sister on the bank.\r\n\r\n";
5756 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5762 memset(&th_v, 0,
sizeof(th_v));
5763 memset(&f, 0,
sizeof(f));
5764 memset(&ssn, 0,
sizeof(ssn));
5771 f.
proto = IPPROTO_TCP;
5792 "(filestore; sid:1; rev:1;)");
5837 AppLayerGetFileState files = HTPGetTxFiles(tx_ptr, STREAM_TOCLIENT);
5859 static int HTPParserTest27(
void)
5862 memset(&cfg, 0,
sizeof(cfg));
5866 uint32_t
len = 1000;
5891 static void HTPParserRegisterTests(
void)
5913 UtRegisterTest(
"HTPParserDecodingTest01", HTPParserDecodingTest01);
5914 UtRegisterTest(
"HTPParserDecodingTest01a", HTPParserDecodingTest01a);
5915 UtRegisterTest(
"HTPParserDecodingTest02", HTPParserDecodingTest02);
5916 UtRegisterTest(
"HTPParserDecodingTest03", HTPParserDecodingTest03);
5917 UtRegisterTest(
"HTPParserDecodingTest04", HTPParserDecodingTest04);
5918 UtRegisterTest(
"HTPParserDecodingTest05", HTPParserDecodingTest05);
5919 UtRegisterTest(
"HTPParserDecodingTest06", HTPParserDecodingTest06);
5920 UtRegisterTest(
"HTPParserDecodingTest07", HTPParserDecodingTest07);
5921 UtRegisterTest(
"HTPParserDecodingTest08", HTPParserDecodingTest08);
5922 UtRegisterTest(
"HTPParserDecodingTest09", HTPParserDecodingTest09);
5924 UtRegisterTest(
"HTPBodyReassemblyTest01", HTPBodyReassemblyTest01);