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",
125 {
"UNABLE_TO_MATCH_RESPONSE_TO_REQUEST",
140 {
"REQUEST_SERVER_PORT_TCP_PORT_MISMATCH",
154 {
"RESPONSE_ABNORMAL_TRANSFER_ENCODING",
201 static int HTTPGetFrameIdByName(
const char *frame_name)
210 static const char *HTTPGetFrameNameById(
const uint8_t frame_id)
216 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id);
217 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction);
218 static uint64_t HTPStateGetTxCnt(
void *alstate);
220 static void HTPParserRegisterTests(
void);
223 static inline uint64_t HtpGetActiveRequestTxID(
HtpState *s)
225 uint64_t
id = HTPStateGetTxCnt(s);
230 static inline uint64_t HtpGetActiveResponseTxID(
HtpState *s)
243 static const char *HTPLookupPersonalityString(
int p)
245 #define CASE_HTP_PERSONALITY_STRING(p) \
246 case HTP_SERVER_PERSONALITY_##p: \
250 CASE_HTP_PERSONALITY_STRING(MINIMAL);
251 CASE_HTP_PERSONALITY_STRING(GENERIC);
252 CASE_HTP_PERSONALITY_STRING(IDS);
253 CASE_HTP_PERSONALITY_STRING(IIS_4_0);
254 CASE_HTP_PERSONALITY_STRING(IIS_5_0);
255 CASE_HTP_PERSONALITY_STRING(IIS_5_1);
256 CASE_HTP_PERSONALITY_STRING(IIS_6_0);
257 CASE_HTP_PERSONALITY_STRING(IIS_7_0);
258 CASE_HTP_PERSONALITY_STRING(IIS_7_5);
259 CASE_HTP_PERSONALITY_STRING(APACHE_2);
273 static int HTPLookupPersonality(
const char *
str)
275 #define IF_HTP_PERSONALITY_NUM(p) \
276 if (strcasecmp(#p, str) == 0) \
277 return HTP_SERVER_PERSONALITY_##p
289 if (strcasecmp(
"TOMCAT_6_0",
str) == 0) {
291 "longer supported by libhtp.",
294 }
else if ((strcasecmp(
"APACHE",
str) == 0) ||
295 (strcasecmp(
"APACHE_2_2",
str) == 0))
298 "longer supported by libhtp, failing back to "
299 "Apache2 personality.",
308 const uint8_t dir,
const uint8_t e)
318 const uint64_t tx_id = (dir == STREAM_TOSERVER) ?
319 HtpGetActiveRequestTxID(s) : HtpGetActiveResponseTxID(s);
321 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
322 if (tx == NULL && tx_id > 0)
323 tx = HTPStateGetTx(s, tx_id - 1);
338 static void *HTPStateAlloc(
void *orig_state,
AppProto proto_orig)
352 htp_state_memuse +=
sizeof(
HtpState);
353 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
373 if (htud->
tx_data.de_state != NULL) {
399 if (s->
connp != NULL) {
403 uint64_t total_txs = HTPStateGetTxCnt(state);
405 if (s->
conn != NULL) {
406 for (tx_id = s->
tx_freed; tx_id < total_txs; tx_id++) {
407 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
410 HtpTxUserDataFree(s, htud);
411 htp_tx_set_user_data(tx, NULL);
415 htp_connp_destroy_all(s->
connp);
423 htp_state_memuse -=
sizeof(
HtpState);
424 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
437 static void HTPStateTransactionFree(
void *state, uint64_t
id)
445 htp_tx_t *tx = HTPStateGetTx(s,
id);
449 HtpTxUserDataFree(s, htud);
450 htp_tx_set_user_data(tx, NULL);
509 static void AppLayerHtpSetStreamDepthFlag(
void *tx,
const uint8_t
flags)
514 if (
flags & STREAM_TOCLIENT) {
524 SCLogDebug(
"cfg->body_limit %u stream_depth %u body->content_len_so_far %" PRIu64,
541 static uint32_t AppLayerHtpComputeChunkLength(uint64_t content_len_so_far, uint32_t body_limit,
542 uint32_t stream_depth, uint8_t
flags, uint32_t data_len)
544 uint32_t chunk_len = 0;
546 (content_len_so_far < (uint64_t)body_limit) &&
547 (content_len_so_far + (uint64_t)data_len) > body_limit)
549 chunk_len = (uint32_t)(body_limit - content_len_so_far);
551 (content_len_so_far < (uint64_t)stream_depth) &&
552 (content_len_so_far + (uint64_t)data_len) > stream_depth)
554 chunk_len = (uint32_t)(stream_depth - content_len_so_far);
557 return (chunk_len == 0 ? data_len : chunk_len);
568 {
"Request chunk encoding: Invalid chunk length",
570 {
"Response chunk encoding: Invalid chunk length",
579 {
"Invalid C-L field in response",
582 {
"Unable to match response to request",
584 {
"Invalid server port information in request",
590 {
"C-T multipart/byteranges in responses not supported",
616 {
"Request line: URI contains non-compliant delimiter",
618 {
"Request line: non-compliant delimiter between Method and URI",
627 {
"Transfer-encoding has abnormal chunked value",
629 {
"Chunked transfer-encoding on HTTP/0.9 or HTTP/1.0",
632 {
"Invalid response line: invalid response status",
638 {
"Ambiguous response C-L value",
646 #define HTP_ERROR_MAX (sizeof(htp_errors) / sizeof(htp_errors[0]))
647 #define HTP_WARNING_MAX (sizeof(htp_warnings) / sizeof(htp_warnings[0]))
658 static uint8_t HTPHandleWarningGetId(
const char *
msg)
682 static uint8_t HTPHandleErrorGetId(
const char *
msg)
706 static void HTPHandleError(
HtpState *s,
const uint8_t dir)
708 if (s == NULL || s->
conn == NULL ||
709 s->
conn->messages == NULL) {
713 size_t size = htp_list_size(s->
conn->messages);
728 htp_log_t *log = htp_list_get(s->
conn->messages,
msg);
733 htp_tx_t *tx = log->tx;
739 uint8_t
id = HTPHandleErrorGetId(log->msg);
741 id = HTPHandleWarningGetId(log->msg);
747 HTPSetEvent(s, htud, dir,
id);
754 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s, htp_tx_t *tx)
757 BUG_ON(s == NULL || tx == NULL);
767 HTPSetEvent(s, htud, STREAM_TOSERVER,
770 HTPSetEvent(s, htud, STREAM_TOSERVER,
773 HTPSetEvent(s, htud, STREAM_TOSERVER,
776 HTPSetEvent(s, htud, STREAM_TOSERVER,
779 HTPSetEvent(s, htud, STREAM_TOSERVER,
782 HTPSetEvent(s, htud, STREAM_TOSERVER,
789 HTPSetEvent(s, htud, STREAM_TOSERVER,
798 HTPSetEvent(s, htud, STREAM_TOSERVER,
809 htp_cfg_t *htp = cfglist.
cfg;
810 void *user_data = NULL;
826 if (user_data != NULL) {
827 htp_cfg_rec = user_data;
828 htp = htp_cfg_rec->
cfg;
831 SCLogDebug(
"Using default HTP config: %p", htp);
835 #ifdef DEBUG_VALIDATION
842 hstate->
connp = htp_connp_create(htp);
843 if (hstate->
connp == NULL) {
847 hstate->
conn = htp_connp_get_connection(hstate->
connp);
849 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
850 hstate->
cfg = htp_cfg_rec;
855 htp_connp_open(hstate->
connp, NULL, f->
sp, NULL, f->
dp, &
tv);
877 StreamSlice stream_slice,
void *local_data)
887 if (NULL == hstate->
conn) {
888 if (Setup(f, hstate) != 0) {
893 hstate->
slice = &stream_slice;
895 const uint8_t *input = StreamSliceGetData(&stream_slice);
896 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
901 const int r = htp_connp_req_data(hstate->
connp, &
ts, input, input_len);
909 HTPHandleError(hstate, STREAM_TOSERVER);
916 htp_connp_req_close(hstate->
connp, &
ts);
918 SCLogDebug(
"stream eof encountered, closing htp handle for ts");
922 hstate->
slice = NULL;
944 StreamSlice stream_slice,
void *local_data)
950 const uint8_t *input = StreamSliceGetData(&stream_slice);
951 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
957 if (NULL == hstate->
conn) {
958 if (Setup(f, hstate) != 0) {
963 hstate->
slice = &stream_slice;
967 uint32_t consumed = 0;
969 const int r = htp_connp_res_data(hstate->
connp, &
ts, input, input_len);
975 tx = htp_connp_get_out_tx(hstate->
connp);
986 consumed = (uint32_t)htp_connp_res_data_consumed(hstate->
connp);
987 if (bstr_cmp_c(h->value,
"h2c") == 0) {
992 hstate->
slice = NULL;
994 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
999 if (consumed > 0 && consumed < input_len) {
1003 }
else if (bstr_cmp_c_nocase(h->value,
"WebSocket") == 0) {
1008 hstate->
slice = NULL;
1010 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
1015 if (consumed > 0 && consumed < input_len) {
1025 HTPHandleError(hstate, STREAM_TOCLIENT);
1032 htp_connp_close(hstate->
connp, &
ts);
1037 hstate->
slice = NULL;
1048 static int HTTPParseContentDispositionHeader(uint8_t *
name,
size_t name_len,
1049 uint8_t *data,
size_t len, uint8_t **retptr,
size_t *retlen)
1052 printf(
"DATA START: \n");
1054 printf(
"DATA END: \n");
1059 for (x = 0; x <
len; x++) {
1060 if (!(isspace(data[x])))
1067 uint8_t *line = data+x;
1068 size_t line_len =
len-x;
1071 printf(
"LINE START: \n");
1073 printf(
"LINE END: \n");
1075 for (x = 0 ; x < line_len; x++) {
1077 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
1081 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
1082 uint8_t *token = line +
offset;
1083 size_t token_len = x -
offset;
1085 if ((x + 1) == line_len) {
1096 printf(
"TOKEN START: \n");
1098 printf(
"TOKEN END: \n");
1100 if (token_len > name_len) {
1101 if (
name == NULL || SCMemcmpLowercase(
name, token, name_len) == 0) {
1102 uint8_t *value = token + name_len;
1103 size_t value_len = token_len - name_len;
1105 if (value[0] ==
'\"') {
1109 if (value[value_len-1] ==
'\"') {
1113 printf(
"VALUE START: \n");
1115 printf(
"VALUE END: \n");
1118 *retlen = value_len;
1142 static int HtpRequestBodySetupMultipart(htp_tx_t *tx,
HtpTxUserData *htud)
1145 if (h != NULL && bstr_len(h->value) > 0) {
1146 htud->
mime_state = SCMimeStateInit(bstr_ptr(h->value), (uint32_t)bstr_len(h->value));
1163 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1166 chunks_buffer, chunks_buffer_len,
1170 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1173 if (tx && tx->
tx_data.de_state) {
1174 if (dir == STREAM_TOSERVER) {
1175 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1177 }
else if (dir == STREAM_TOCLIENT) {
1178 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1185 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len,
bool eof)
1188 printf(
"CHUNK START: \n");
1190 printf(
"CHUNK END: \n");
1198 const uint8_t *cur_buf = chunks_buffer;
1199 uint32_t cur_buf_len = chunks_buffer_len;
1215 const uint8_t *filename = NULL;
1216 uint16_t filename_len = 0;
1219 while (cur_buf_len > 0) {
1220 MimeParserResult r =
1221 SCMimeParse(htud->
mime_state, cur_buf, cur_buf_len, &consumed, &warnings);
1225 if (warnings & MIME_EVENT_FLAG_INVALID_HEADER) {
1229 if (warnings & MIME_EVENT_FLAG_NO_FILEDATA) {
1240 SCMimeStateGetFilename(htud->
mime_state, &filename, &filename_len);
1241 if (filename_len > 0) {
1245 hstate, htud, filename, filename_len, NULL, 0, STREAM_TOSERVER);
1248 }
else if (result == -2) {
1251 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1259 }
else if (result == -2) {
1267 uint32_t lastsize = consumed;
1268 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\n') {
1270 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\r') {
1274 HTPFileClose(htud, cur_buf, lastsize, 0, STREAM_TOSERVER);
1279 cur_buf += consumed;
1280 cur_buf_len -= consumed;
1292 htp_tx_t *tx, uint8_t *data, uint32_t data_len)
1299 uint8_t *filename = NULL;
1300 size_t filename_len = 0;
1303 if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) {
1304 filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path);
1305 filename_len = bstr_len(tx->parsed_uri->path);
1308 if (filename != NULL) {
1314 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1318 }
else if (result == -2) {
1321 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1335 }
else if (result == -2) {
1348 htp_tx_t *tx, uint8_t *data, uint32_t data_len)
1361 uint8_t *filename = NULL;
1362 size_t filename_len = 0;
1367 if (h != NULL && bstr_len(h->value) > 0) {
1369 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1370 (uint8_t *) bstr_ptr(h->value), bstr_len(h->value), &filename, &filename_len);
1374 if (filename == NULL) {
1376 if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) {
1377 filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path);
1378 filename_len = bstr_len(tx->parsed_uri->path);
1382 if (filename != NULL) {
1384 htp_header_t *h_content_range =
1391 if (h_content_range != NULL) {
1393 data_len, tx, h_content_range->value, htud);
1395 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1401 }
else if (result == -2) {
1404 FlagDetectStateNewFile(htud, STREAM_TOCLIENT);
1417 }
else if (result == -2) {
1435 static int HTPCallbackRequestBodyData(htp_tx_data_t *d)
1446 printf(
"HTPBODY START: \n");
1448 printf(
"HTPBODY END: \n");
1451 HtpState *hstate = htp_connp_get_user_data(d->tx->connp);
1452 if (hstate == NULL) {
1456 SCLogDebug(
"New request body data available at %p -> %p -> %p, bodylen "
1457 "%"PRIu32
"", hstate, d, d->data, (uint32_t)d->len);
1460 if (tx_ud == NULL) {
1463 tx_ud->
tx_data.updated_ts =
true;
1471 int r = HtpRequestBodySetupMultipart(d->tx, tx_ud);
1474 }
else if (r == 0) {
1478 }
else if (d->htp_tx_request_method_number(tx) ==
HTP_METHOD_PUT) {
1501 const uint8_t *chunks_buffer = NULL;
1502 uint32_t chunks_buffer_len = 0;
1510 HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len);
1511 if (chunks_buffer == NULL) {
1515 printf(
"REASSCHUNK START: \n");
1517 printf(
"REASSCHUNK END: \n");
1520 HtpRequestBodyHandleMultipart(hstate, tx_ud, d->tx, chunks_buffer, chunks_buffer_len,
1521 (d->data == NULL && d->len == 0));
1525 HtpRequestBodyHandlePOSTorPUT(hstate, tx_ud, d->tx, (uint8_t *)d->data,
len);
1530 SCLogDebug(
"closing file that was being stored");
1537 if (hstate->
conn != NULL) {
1538 SCLogDebug(
"checking body size %"PRIu64
" against inspect limit %u (cur %"PRIu64
", last %"PRIu64
")",
1552 const uint32_t data_size = (uint32_t)(
1573 static int HTPCallbackResponseBodyData(htp_tx_data_t *d)
1583 HtpState *hstate = htp_connp_get_user_data(d->tx->connp);
1584 if (hstate == NULL) {
1588 SCLogDebug(
"New response body data available at %p -> %p -> %p, bodylen "
1589 "%"PRIu32
"", hstate, d, d->data, (uint32_t)d->len);
1592 if (tx_ud == NULL) {
1595 tx_ud->
tx_data.updated_tc =
true;
1619 HtpResponseBodyHandle(hstate, tx_ud, d->tx, (uint8_t *)d->data,
len);
1622 SCLogDebug(
"closing file that was being stored");
1628 if (hstate->
conn != NULL) {
1629 SCLogDebug(
"checking body size %"PRIu64
" against inspect limit %u (cur %"PRIu64
", last %"PRIu64
")",
1642 const uint32_t data_size = (uint32_t)((uint64_t)hstate->
conn->out_data_counter -
1666 SCLogDebug(
"http_state_memcnt %"PRIu64
", http_state_memuse %"PRIu64
"",
1667 htp_state_memcnt, htp_state_memuse);
1685 htp_config_destroy(cfglist.
cfg);
1686 while (nextrec != NULL) {
1688 nextrec = nextrec->
next;
1690 htp_config_destroy(htprec->
cfg);
1698 static int HTPCallbackRequestHasTrailer(htp_tx_t *tx)
1702 htud->
tx_data.updated_ts =
true;
1708 static int HTPCallbackResponseHasTrailer(htp_tx_t *tx)
1712 htud->
tx_data.updated_tc =
true;
1722 static int HTPCallbackRequestStart(htp_tx_t *tx)
1724 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1725 if (hstate == NULL) {
1729 uint64_t consumed = hstate->
slice->offset + htp_connp_req_data_consumed(hstate->
connp);
1730 SCLogDebug(
"HTTP request start: data offset %" PRIu64
", in_data_counter %" PRIu64, consumed,
1731 (uint64_t)hstate->
conn->in_data_counter);
1748 if (tx_ud == NULL) {
1753 tx_ud->
tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT;
1754 htp_tx_set_user_data(tx, tx_ud);
1756 tx_ud->
tx_data.updated_ts =
true;
1765 static int HTPCallbackResponseStart(htp_tx_t *tx)
1767 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1768 if (hstate == NULL) {
1772 uint64_t consumed = hstate->
slice->offset + htp_connp_res_data_consumed(hstate->
connp);
1773 SCLogDebug(
"HTTP response start: data offset %" PRIu64
", out_data_counter %" PRIu64, consumed,
1774 (uint64_t)hstate->
conn->out_data_counter);
1789 if (tx_ud == NULL) {
1796 htp_tx_set_user_data(tx, tx_ud);
1798 tx_ud->
tx_data.updated_tc =
true;
1809 static int HTPCallbackRequestComplete(htp_tx_t *tx)
1817 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1818 if (hstate == NULL) {
1822 const uint64_t abs_right_edge =
1823 hstate->
slice->offset + htp_connp_req_data_consumed(hstate->
connp);
1831 SCLogDebug(
"HTTP request complete: data offset %" PRIu64
", request_size %" PRIu64,
1833 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1835 frame->
len = (int64_t)request_size;
1841 SCLogDebug(
"transaction_cnt %"PRIu64
", list_size %"PRIu64,
1846 HTPErrorCheckTxRequestFlags(hstate, tx);
1850 htud->
tx_data.updated_ts =
true;
1852 SCLogDebug(
"closing file that was being stored");
1855 if (abs_right_edge < (uint64_t)UINT32_MAX) {
1857 hstate->
f->
protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
1875 static int HTPCallbackResponseComplete(htp_tx_t *tx)
1879 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1880 if (hstate == NULL) {
1887 const uint64_t abs_right_edge =
1888 hstate->
slice->offset + htp_connp_res_data_consumed(hstate->
connp);
1895 SCLogDebug(
"HTTP response complete: data offset %" PRIu64
", response_size %" PRIu64,
1897 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1899 frame->
len = (int64_t)response_size;
1906 htud->
tx_data.updated_tc =
true;
1908 SCLogDebug(
"closing file that was being stored");
1942 static int HTPCallbackRequestLine(htp_tx_t *tx)
1945 bstr *request_uri_normalized;
1946 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1950 if (request_uri_normalized == NULL)
1953 tx_ud = htp_tx_get_user_data(tx);
1955 bstr_free(request_uri_normalized);
1963 HTPErrorCheckTxRequestFlags(hstate, tx);
1968 static int HTPCallbackDoubleDecodeUriPart(htp_tx_t *tx, bstr *part)
1974 size_t prevlen = bstr_len(part);
1975 htp_status_t res = htp_urldecode_inplace(tx->cfg, HTP_DECODER_URLENCODED, part, &
flags);
1981 HtpState *s = htp_connp_get_user_data(tx->connp);
1984 HTPSetEvent(s, htud, STREAM_TOSERVER,
1991 static int HTPCallbackDoubleDecodeQuery(htp_tx_t *tx)
1993 if (tx->parsed_uri == NULL)
1996 return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->query);
1999 static int HTPCallbackDoubleDecodePath(htp_tx_t *tx)
2001 if (tx->parsed_uri == NULL)
2004 return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->path);
2007 static int HTPCallbackRequestHeaderData(htp_tx_data_t *tx_data)
2010 if (tx_data->len == 0 || tx_data->tx == NULL)
2014 if (tx_ud == NULL) {
2024 tx_ud->
tx_data.updated_ts =
true;
2027 tx_data->data, tx_data->len);
2030 if (tx_data->tx && tx_data->tx->flags) {
2031 HtpState *hstate = htp_connp_get_user_data(tx_data->tx->connp);
2032 HTPErrorCheckTxRequestFlags(hstate, tx_data->tx);
2037 static int HTPCallbackResponseHeaderData(htp_tx_data_t *tx_data)
2040 if (tx_data->len == 0 || tx_data->tx == NULL)
2044 if (tx_ud == NULL) {
2047 tx_ud->
tx_data.updated_tc =
true;
2057 tx_data->data, tx_data->len);
2066 static void HTPConfigSetDefaultsPhase1(
HTPCfgRec *cfg_prec)
2083 htp_config_register_request_header_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
2084 htp_config_register_request_trailer_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
2085 htp_config_register_response_header_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
2086 htp_config_register_response_trailer_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
2088 htp_config_register_request_trailer(cfg_prec->
cfg, HTPCallbackRequestHasTrailer);
2089 htp_config_register_response_trailer(cfg_prec->
cfg, HTPCallbackResponseHasTrailer);
2091 htp_config_register_request_body_data(cfg_prec->
cfg, HTPCallbackRequestBodyData);
2092 htp_config_register_response_body_data(cfg_prec->
cfg, HTPCallbackResponseBodyData);
2094 htp_config_register_request_start(cfg_prec->
cfg, HTPCallbackRequestStart);
2095 htp_config_register_request_complete(cfg_prec->
cfg, HTPCallbackRequestComplete);
2097 htp_config_register_response_start(cfg_prec->
cfg, HTPCallbackResponseStart);
2098 htp_config_register_response_complete(cfg_prec->
cfg, HTPCallbackResponseComplete);
2100 htp_config_set_parse_request_cookies(cfg_prec->
cfg, 0);
2101 #ifdef HAVE_HTP_CONFIG_SET_ALLOW_SPACE_URI
2102 htp_config_set_allow_space_uri(cfg_prec->
cfg, 1);
2106 htp_config_set_plusspace_decode(cfg_prec->
cfg, HTP_DECODER_URLENCODED, 0);
2108 htp_config_set_request_decompression(cfg_prec->
cfg, 1);
2109 #ifdef HAVE_HTP_CONFIG_SET_LZMA_LAYERS
2113 #ifdef HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT
2114 htp_config_set_lzma_memlimit(cfg_prec->
cfg,
2117 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT
2118 htp_config_set_compression_bomb_limit(cfg_prec->
cfg,
2121 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
2124 #ifdef HAVE_HTP_CONFIG_SET_MAX_TX
2125 #define HTP_CONFIG_DEFAULT_MAX_TX_LIMIT 512
2126 htp_config_set_max_tx(cfg_prec->
cfg, HTP_CONFIG_DEFAULT_MAX_TX_LIMIT);
2128 #ifdef HAVE_HTP_CONFIG_SET_HEADERS_LIMIT
2129 #define HTP_CONFIG_DEFAULT_HEADERS_LIMIT 1024
2130 htp_config_set_number_headers_limit(cfg_prec->
cfg, HTP_CONFIG_DEFAULT_HEADERS_LIMIT);
2145 static int RandomGetWrap(
void)
2151 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
2153 return r % RAND_MAX;
2162 static void HTPConfigSetDefaultsPhase2(
const char *
name,
HTPCfgRec *cfg_prec)
2168 long int r = RandomGetWrap();
2170 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2172 r = RandomGetWrap();
2174 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2175 SCLogConfig(
"'%s' server has 'request-body-minimal-inspect-size' set to"
2176 " %u and 'request-body-inspect-window' set to %u after"
2180 r = RandomGetWrap();
2182 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2184 r = RandomGetWrap();
2186 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2188 SCLogConfig(
"'%s' server has 'response-body-minimal-inspect-size' set to"
2189 " %u and 'response-body-inspect-window' set to %u after"
2194 htp_config_register_request_line(cfg_prec->
cfg, HTPCallbackRequestLine);
2197 static void HTPConfigParseParameters(
HTPCfgRec *cfg_prec,
ConfNode *s,
struct HTPConfigTree *tree)
2199 if (cfg_prec == NULL || s == NULL || tree == NULL)
2206 if (strcasecmp(
"address", p->
name) == 0) {
2212 if (strchr(pval->
val,
':') != NULL) {
2213 SCLogDebug(
"LIBHTP adding ipv6 server %s at %s: %p",
2217 SCLogWarning(
"LIBHTP failed to add ipv6 server %s, ignoring", pval->
val);
2220 SCLogDebug(
"LIBHTP adding ipv4 server %s at %s: %p",
2224 SCLogWarning(
"LIBHTP failed to add ipv4 server %s, ignoring", pval->
val);
2229 }
else if (strcasecmp(
"personality", p->
name) == 0) {
2231 int personality = HTPLookupPersonality(p->
val);
2235 if (personality >= 0) {
2238 if (htp_config_set_server_personality(cfg_prec->
cfg, personality) ==
2241 "personality \"%s\", ignoring",
2245 HTPLookupPersonalityString(personality));
2251 htp_config_set_convert_lowercase(cfg_prec->
cfg, HTP_DECODER_URL_PATH, 0);
2259 }
else if (strcasecmp(
"request-body-limit", p->
name) == 0 ||
2260 strcasecmp(
"request_body_limit", p->
name) == 0) {
2262 SCLogError(
"Error parsing request-body-limit "
2263 "from conf file - %s. Killing engine",
2268 }
else if (strcasecmp(
"response-body-limit", p->
name) == 0) {
2270 SCLogError(
"Error parsing response-body-limit "
2271 "from conf file - %s. Killing engine",
2276 }
else if (strcasecmp(
"request-body-minimal-inspect-size", p->
name) == 0) {
2278 SCLogError(
"Error parsing request-body-minimal-inspect-size "
2279 "from conf file - %s. Killing engine",
2284 }
else if (strcasecmp(
"request-body-inspect-window", p->
name) == 0) {
2286 SCLogError(
"Error parsing request-body-inspect-window "
2287 "from conf file - %s. Killing engine",
2292 }
else if (strcasecmp(
"double-decode-query", p->
name) == 0) {
2294 htp_config_register_request_line(cfg_prec->
cfg,
2295 HTPCallbackDoubleDecodeQuery);
2298 }
else if (strcasecmp(
"double-decode-path", p->
name) == 0) {
2300 htp_config_register_request_line(cfg_prec->
cfg,
2301 HTPCallbackDoubleDecodePath);
2304 }
else if (strcasecmp(
"response-body-minimal-inspect-size", p->
name) == 0) {
2306 SCLogError(
"Error parsing response-body-minimal-inspect-size "
2307 "from conf file - %s. Killing engine",
2312 }
else if (strcasecmp(
"response-body-inspect-window", p->
name) == 0) {
2314 SCLogError(
"Error parsing response-body-inspect-window "
2315 "from conf file - %s. Killing engine",
2320 }
else if (strcasecmp(
"response-body-decompress-layer-limit", p->
name) == 0) {
2323 SCLogError(
"Error parsing response-body-inspect-window "
2324 "from conf file - %s. Killing engine",
2328 #ifdef HAVE_HTP_CONFIG_SET_RESPONSE_DECOMPRESSION_LAYER_LIMIT
2329 htp_config_set_response_decompression_layer_limit(cfg_prec->
cfg, value);
2331 SCLogWarning(
"can't set response-body-decompress-layer-limit "
2332 "to %u, libhtp version too old",
2335 }
else if (strcasecmp(
"path-convert-backslash-separators", p->
name) == 0) {
2336 htp_config_set_backslash_convert_slashes(cfg_prec->
cfg,
2337 HTP_DECODER_URL_PATH,
2339 }
else if (strcasecmp(
"path-bestfit-replacement-char", p->
name) == 0) {
2340 if (strlen(p->
val) == 1) {
2341 htp_config_set_bestfit_replacement_byte(cfg_prec->
cfg,
2342 HTP_DECODER_URL_PATH,
2346 "for libhtp param path-bestfit-replacement-char");
2348 }
else if (strcasecmp(
"path-convert-lowercase", p->
name) == 0) {
2349 htp_config_set_convert_lowercase(cfg_prec->
cfg,
2350 HTP_DECODER_URL_PATH,
2352 }
else if (strcasecmp(
"path-nul-encoded-terminates", p->
name) == 0) {
2353 htp_config_set_nul_encoded_terminates(cfg_prec->
cfg,
2354 HTP_DECODER_URL_PATH,
2356 }
else if (strcasecmp(
"path-nul-raw-terminates", p->
name) == 0) {
2357 htp_config_set_nul_raw_terminates(cfg_prec->
cfg,
2358 HTP_DECODER_URL_PATH,
2360 }
else if (strcasecmp(
"path-separators-compress", p->
name) == 0) {
2361 htp_config_set_path_separators_compress(cfg_prec->
cfg,
2362 HTP_DECODER_URL_PATH,
2364 }
else if (strcasecmp(
"path-separators-decode", p->
name) == 0) {
2365 htp_config_set_path_separators_decode(cfg_prec->
cfg,
2366 HTP_DECODER_URL_PATH,
2368 }
else if (strcasecmp(
"path-u-encoding-decode", p->
name) == 0) {
2369 htp_config_set_u_encoding_decode(cfg_prec->
cfg,
2370 HTP_DECODER_URL_PATH,
2372 }
else if (strcasecmp(
"path-url-encoding-invalid-handling", p->
name) == 0) {
2373 enum htp_url_encoding_handling_t handling;
2374 if (strcasecmp(p->
val,
"preserve_percent") == 0) {
2375 handling = HTP_URL_DECODE_PRESERVE_PERCENT;
2376 }
else if (strcasecmp(p->
val,
"remove_percent") == 0) {
2377 handling = HTP_URL_DECODE_REMOVE_PERCENT;
2378 }
else if (strcasecmp(p->
val,
"decode_invalid") == 0) {
2379 handling = HTP_URL_DECODE_PROCESS_INVALID;
2382 "for libhtp param path-url-encoding-invalid-handling");
2385 htp_config_set_url_encoding_invalid_handling(cfg_prec->
cfg,
2386 HTP_DECODER_URL_PATH,
2388 }
else if (strcasecmp(
"path-utf8-convert-bestfit", p->
name) == 0) {
2389 htp_config_set_utf8_convert_bestfit(cfg_prec->
cfg,
2390 HTP_DECODER_URL_PATH,
2392 }
else if (strcasecmp(
"uri-include-all", p->
name) == 0) {
2396 }
else if (strcasecmp(
"query-plusspace-decode", p->
name) == 0) {
2397 htp_config_set_plusspace_decode(cfg_prec->
cfg,
2398 HTP_DECODER_URLENCODED,
2400 }
else if (strcasecmp(
"meta-field-limit", p->
name) == 0) {
2404 "from conf file - %s. Killing engine",
2410 "from conf file cannot be 0. Killing engine");
2413 htp_config_set_field_limits(cfg_prec->
cfg,
2416 #ifdef HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT
2417 }
else if (strcasecmp(
"lzma-memlimit", p->
name) == 0) {
2420 FatalError(
"failed to parse 'lzma-memlimit' "
2421 "from conf file - %s.",
2426 "from conf file cannot be 0.");
2429 SCLogConfig(
"Setting HTTP LZMA memory limit to %"PRIu32
" bytes", limit);
2430 htp_config_set_lzma_memlimit(cfg_prec->
cfg, (
size_t)limit);
2432 #ifdef HAVE_HTP_CONFIG_SET_LZMA_LAYERS
2433 }
else if (strcasecmp(
"lzma-enabled", p->
name) == 0) {
2435 htp_config_set_lzma_layers(cfg_prec->
cfg, 1);
2440 "from conf file - %s.",
2443 SCLogConfig(
"Setting HTTP LZMA decompression layers to %" PRIu32
"", (
int)limit);
2444 htp_config_set_lzma_layers(cfg_prec->
cfg, limit);
2447 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT
2448 }
else if (strcasecmp(
"compression-bomb-limit", p->
name) == 0) {
2451 FatalError(
"failed to parse 'compression-bomb-limit' "
2452 "from conf file - %s.",
2457 "from conf file cannot be 0.");
2460 SCLogConfig(
"Setting HTTP compression bomb limit to %"PRIu32
" bytes", limit);
2461 htp_config_set_compression_bomb_limit(cfg_prec->
cfg, (
size_t)limit);
2463 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
2464 }
else if (strcasecmp(
"decompression-time-limit", p->
name) == 0) {
2468 FatalError(
"failed to parse 'decompression-time-limit' "
2469 "from conf file - %s.",
2472 SCLogConfig(
"Setting HTTP decompression time limit to %" PRIu32
" usec", limit);
2473 htp_config_set_compression_time_limit(cfg_prec->
cfg, (
size_t)limit);
2475 #ifdef HAVE_HTP_CONFIG_SET_MAX_TX
2476 }
else if (strcasecmp(
"max-tx", p->
name) == 0) {
2480 "from conf file - %s.",
2484 SCLogConfig(
"Setting HTTP max-tx limit to %" PRIu32
" bytes", limit);
2485 htp_config_set_max_tx(cfg_prec->
cfg, limit);
2487 #ifdef HAVE_HTP_CONFIG_SET_HEADERS_LIMIT
2488 }
else if (strcasecmp(
"headers-limit", p->
name) == 0) {
2491 FatalError(
"failed to parse 'headers-limit' "
2492 "from conf file - %s.",
2495 SCLogConfig(
"Setting HTTP headers limit to %" PRIu32, limit);
2496 htp_config_set_number_headers_limit(cfg_prec->
cfg, limit);
2498 }
else if (strcasecmp(
"randomize-inspection-sizes", p->
name) == 0) {
2502 }
else if (strcasecmp(
"randomize-inspection-range", p->
name) == 0) {
2505 (
const char *)p->
val, 0, 100) < 0) {
2507 "-inspection-range setting from conf file - \"%s\"."
2508 " It should be a valid integer less than or equal to 100."
2514 }
else if (strcasecmp(
"http-body-inline", p->
name) == 0) {
2520 if (strcmp(
"auto", p->
val) != 0) {
2529 }
else if (strcasecmp(
"swf-decompression", p->
name) == 0) {
2533 if (strcasecmp(
"enabled", pval->
name) == 0) {
2541 }
else if (strcasecmp(
"type", pval->
name) == 0) {
2542 if (strcasecmp(
"no", pval->
val) == 0) {
2544 }
else if (strcasecmp(
"deflate", pval->
val) == 0) {
2546 }
else if (strcasecmp(
"lzma", pval->
val) == 0) {
2548 }
else if (strcasecmp(
"both", pval->
val) == 0) {
2552 "swf-decompression.type: %s - "
2557 }
else if (strcasecmp(
"compress-depth", pval->
name) == 0) {
2559 SCLogError(
"Error parsing swf-decompression.compression-depth "
2560 "from conf file - %s. Killing engine",
2564 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2566 SCLogError(
"Error parsing swf-decompression.decompression-depth "
2567 "from conf file - %s. Killing engine",
2577 "default config: %s",
2587 cfglist.
next = NULL;
2594 cfglist.
cfg = htp_config_create();
2595 if (NULL == cfglist.
cfg) {
2596 FatalError(
"Failed to create HTP default config");
2599 HTPConfigSetDefaultsPhase1(&cfglist);
2600 if (
ConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2601 HTPConfigParseParameters(&cfglist,
ConfGetNode(
"libhtp.default-config"), &cfgtree);
2603 HTPConfigParseParameters(
2604 &cfglist,
ConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), &cfgtree);
2606 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2612 if (server_config == NULL) {
2613 server_config =
ConfGetNode(
"libhtp.server-config");
2614 if (server_config == NULL) {
2615 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2619 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2638 cfglist.
next = htprec;
2641 cfglist.
next->
cfg = htp_config_create();
2642 if (NULL == cfglist.
next->
cfg) {
2643 FatalError(
"Failed to create HTP server config");
2646 HTPConfigSetDefaultsPhase1(htprec);
2647 HTPConfigParseParameters(htprec, s, &cfgtree);
2648 HTPConfigSetDefaultsPhase2(s->
name, htprec);
2658 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
2669 static AppLayerGetFileState HTPGetTxFiles(
void *txv, uint8_t direction)
2671 AppLayerGetFileState files = { .fc = NULL, .cfg = &
htp_sbcfg };
2672 htp_tx_t *tx = (htp_tx_t *)txv;
2675 if (direction & STREAM_TOCLIENT) {
2684 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
2686 if (direction & STREAM_TOSERVER)
2687 return ((htp_tx_t *)tx)->request_progress;
2689 return ((htp_tx_t *)tx)->response_progress;
2692 static uint64_t HTPStateGetTxCnt(
void *alstate)
2696 if (http_state != NULL && http_state->
conn != NULL) {
2697 const int64_t size = (int64_t)htp_list_size(http_state->
conn->transactions);
2701 return (uint64_t)size + http_state->
tx_freed;
2707 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
2711 if (http_state != NULL && http_state->
conn != NULL && tx_id >= http_state->
tx_freed)
2712 return htp_list_get(http_state->
conn->transactions, tx_id - http_state->
tx_freed);
2721 if (http_state != NULL && http_state->
conn != NULL) {
2722 size_t txid = HTPStateGetTxCnt(http_state);
2724 return htp_list_get(http_state->
conn->transactions, txid - http_state->
tx_freed - 1);
2730 static int HTPStateGetEventInfo(
2731 const char *event_name, uint8_t *event_id, AppLayerEventType *event_type)
2734 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2740 static int HTPStateGetEventInfoById(
2741 uint8_t event_id,
const char **event_name, AppLayerEventType *event_type)
2744 if (*event_name == NULL) {
2746 "http's enum map table.",
2752 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2759 htp_tx_t *tx = (htp_tx_t *)vtx;
2767 static AppLayerStateData *HTPGetStateData(
void *vstate)
2773 static int HTPRegisterPatternsForProtocolDetection(
void)
2775 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
2776 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
2777 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
2778 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
2779 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
2780 const char *spacings[] = {
"|20|",
"|09|", NULL };
2781 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
2786 int register_result;
2787 char method_buffer[32] =
"";
2790 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
2791 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
2794 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
2801 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
2802 if (register_result < 0) {
2809 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
2811 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
2813 if (register_result < 0) {
2829 const char *proto_name =
"http";
2834 if (HTPRegisterPatternsForProtocolDetection() < 0)
2837 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
2864 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
2866 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
2872 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
2875 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
2879 SCLogInfo(
"Parser disabled for %s protocol. Protocol detection still on.", proto_name);
2895 cfglist_backup = cfglist;
2900 cfglist = cfglist_backup;
2905 static int HTPParserTest01(
void)
2907 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2909 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2912 memset(&ssn, 0,
sizeof(ssn));
2920 f->
proto = IPPROTO_TCP;
2926 for (u = 0; u < httplen1; u++) {
2930 flags = STREAM_TOSERVER|STREAM_START;
2931 else if (u == (httplen1 - 1))
2932 flags = STREAM_TOSERVER|STREAM_EOF;
2934 flags = STREAM_TOSERVER;
2943 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2949 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
2960 static int HTPParserTest01b(
void)
2962 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2964 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2967 memset(&ssn, 0,
sizeof(ssn));
2975 f->
proto = IPPROTO_TCP;
2980 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
2987 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2993 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
3004 static int HTPParserTest01c(
void)
3006 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
3008 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3011 memset(&ssn, 0,
sizeof(ssn));
3019 f->
proto = IPPROTO_TCP;
3025 for (u = 0; u < httplen1; u++) {
3029 flags = STREAM_TOSERVER|STREAM_START;
3030 else if (u == (httplen1 - 1))
3031 flags = STREAM_TOSERVER|STREAM_EOF;
3033 flags = STREAM_TOSERVER;
3042 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3048 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
3060 static int HTPParserTest01a(
void)
3063 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3065 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3070 memset(&ssn, 0,
sizeof(ssn));
3072 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3075 f->
proto = IPPROTO_TCP;
3081 for (u = 0; u < httplen1; u++) {
3085 flags = STREAM_TOSERVER|STREAM_START;
3086 else if (u == (httplen1 - 1))
3087 flags = STREAM_TOSERVER|STREAM_EOF;
3089 flags = STREAM_TOSERVER;
3098 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3104 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
3115 static int HTPParserTest02(
void)
3118 uint8_t httpbuf1[] =
"POST";
3119 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3124 memset(&ssn, 0,
sizeof(ssn));
3126 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3129 f->
proto = IPPROTO_TCP;
3135 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3141 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3150 FAIL_IF(strcmp(method,
"POST") != 0);
3161 static int HTPParserTest03(
void)
3164 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
3165 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3170 memset(&ssn, 0,
sizeof(ssn));
3172 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3175 f->
proto = IPPROTO_TCP;
3181 for (u = 0; u < httplen1; u++) {
3184 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3185 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3186 else flags = STREAM_TOSERVER;
3194 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3210 static int HTPParserTest04(
void)
3214 uint8_t httpbuf1[] =
"World!\r\n";
3215 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3219 memset(&ssn, 0,
sizeof(ssn));
3221 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3224 f->
proto = IPPROTO_TCP;
3230 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3236 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3252 static int HTPParserTest05(
void)
3254 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3255 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3256 uint8_t httpbuf2[] =
"Post D";
3257 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3258 uint8_t httpbuf3[] =
"ata is c0oL!";
3259 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3261 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3262 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3263 uint8_t httpbuf5[] =
"post R";
3264 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3265 uint8_t httpbuf6[] =
"esults are tha bomb!";
3266 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3269 memset(&ssn, 0,
sizeof(ssn));
3277 f->
proto = IPPROTO_TCP;
3307 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3325 static int HTPParserTest06(
void)
3327 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3328 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3329 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3330 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3331 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3333 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3334 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3335 "FrontPage/5.0.2.2510\r\n"
3336 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3338 "Content-Type: text/html\r\n\r\n"
3340 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3341 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3342 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3343 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3344 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3345 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3346 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3347 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3348 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3349 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3350 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3351 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3352 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3353 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3354 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3355 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3356 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3357 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3358 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3359 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3360 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3361 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3362 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3363 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3364 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3365 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3366 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3367 "aHA=\r\n0\r\n\r\n";
3368 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3374 memset(&ssn, 0,
sizeof(ssn));
3379 f->
proto = IPPROTO_TCP;
3394 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3414 static int HTPParserTest07(
void)
3417 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3418 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3423 memset(&ssn, 0,
sizeof(ssn));
3425 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3428 f->
proto = IPPROTO_TCP;
3434 for (u = 0; u < httplen1; u++) {
3438 flags = STREAM_TOSERVER|STREAM_START;
3439 else if (u == (httplen1 - 1))
3440 flags = STREAM_TOSERVER|STREAM_EOF;
3442 flags = STREAM_TOSERVER;
3451 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3452 size_t reflen =
sizeof(ref) - 1;
3454 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3475 static int HTPParserTest08(
void)
3478 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3479 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3500 memset(&ssn, 0,
sizeof(ssn));
3502 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3505 f->
proto = IPPROTO_TCP;
3510 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3518 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3538 static int HTPParserTest09(
void)
3541 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3542 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3552 personality: Apache_2_2\n\
3564 memset(&ssn, 0,
sizeof(ssn));
3566 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3569 f->
proto = IPPROTO_TCP;
3574 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3582 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3603 static int HTPParserTest10(
void)
3607 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3608 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3613 memset(&ssn, 0,
sizeof(ssn));
3615 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3618 f->
proto = IPPROTO_TCP;
3624 for (u = 0; u < httplen1; u++) {
3628 flags = STREAM_TOSERVER|STREAM_START;
3629 else if (u == (httplen1 - 1))
3630 flags = STREAM_TOSERVER|STREAM_EOF;
3632 flags = STREAM_TOSERVER;
3641 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3645 char *
name = bstr_util_strdup_to_c(h->name);
3649 char *value = bstr_util_strdup_to_c(h->value);
3651 FAIL_IF(strcmp(value,
"www.google.com") != 0);
3663 static int HTPParserTest11(
void)
3666 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3667 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3672 memset(&ssn, 0,
sizeof(ssn));
3674 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3677 f->
proto = IPPROTO_TCP;
3683 for (u = 0; u < httplen1; u++) {
3687 flags = STREAM_TOSERVER|STREAM_START;
3688 else if (u == (httplen1 - 1))
3689 flags = STREAM_TOSERVER|STREAM_EOF;
3691 flags = STREAM_TOSERVER;
3700 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3722 static int HTPParserTest12(
void)
3725 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3726 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3731 memset(&ssn, 0,
sizeof(ssn));
3733 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3736 f->
proto = IPPROTO_TCP;
3742 for (u = 0; u < httplen1; u++) {
3746 flags = STREAM_TOSERVER|STREAM_START;
3747 else if (u == (httplen1 - 1))
3748 flags = STREAM_TOSERVER|STREAM_EOF;
3750 flags = STREAM_TOSERVER;
3759 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3783 static int HTPParserTest13(
void)
3786 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3787 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3792 memset(&ssn, 0,
sizeof(ssn));
3794 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3797 f->
proto = IPPROTO_TCP;
3803 for (u = 0; u < httplen1; u++) {
3807 flags = STREAM_TOSERVER|STREAM_START;
3808 else if (u == (httplen1 - 1))
3809 flags = STREAM_TOSERVER|STREAM_EOF;
3811 flags = STREAM_TOSERVER;
3819 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3823 char *
name = bstr_util_strdup_to_c(h->name);
3827 char *value = bstr_util_strdup_to_c(h->value);
3829 FAIL_IF(strcmp(value,
"www.google.com\rName: Value") != 0);
3841 static int HTPParserConfigTest01(
void)
3854 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3855 personality: Tomcat_6_0\n\
3860 - 192.168.10.0/24\n\
3861 personality: IIS_7_0\n\
3870 outputs =
ConfGetNode(
"libhtp.default-config.personality");
3881 FAIL_IF(strcmp(node->
name,
"apache-tomcat") != 0);
3888 FAIL_IF(strcmp(node2->
val,
"Tomcat_6_0") != 0);
3898 FAIL_IF(strcmp(n->
val,
"192.168.1.0/24") != 0);
3938 FAIL_IF(strcmp(n->
val,
"192.168.0.0/24") != 0);
3942 FAIL_IF(strcmp(n->
val,
"192.168.10.0/24") != 0);
3957 static int HTPParserConfigTest02(
void)
3970 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3971 personality: Tomcat_6_0\n\
3976 - 192.168.10.0/24\n\
3977 personality: IIS_7_0\n\
3989 htp_cfg_t *htp = cfglist.
cfg;
3992 void *user_data = NULL;
3994 addr =
"192.168.10.42";
3995 FAIL_IF(inet_pton(AF_INET, addr, buf) != 1);
3999 htp = htp_cfg_rec->
cfg;
4005 FAIL_IF(inet_pton(AF_INET6, addr, buf) != 1);
4008 htp_cfg_rec = user_data;
4009 htp = htp_cfg_rec->
cfg;
4022 static int HTPParserConfigTest03(
void)
4025 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
4027 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4043 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
4044 personality: Tomcat_6_0\n\
4049 - 192.168.10.0/24\n\
4050 personality: IIS_7_0\n\
4061 const char *addr =
"192.168.10.42";
4063 memset(&ssn, 0,
sizeof(ssn));
4068 f->
proto = IPPROTO_TCP;
4071 htp_cfg_t *htp = cfglist.
cfg;
4074 void *user_data = NULL;
4079 htp = htp_cfg_rec->
cfg;
4086 for (u = 0; u < httplen1; u++) {
4089 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4090 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4091 else flags = STREAM_TOSERVER;
4100 FAIL_IF(HTPStateGetTxCnt(htp_state) != 2);
4102 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4106 tx = HTPStateGetTx(htp_state, 1);
4127 static int HTPParserDecodingTest01(
void)
4129 uint8_t httpbuf1[] =
4130 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4131 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4132 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4133 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4144 personality: Apache_2\n\
4152 const char *addr =
"4.3.2.1";
4153 memset(&ssn, 0,
sizeof(ssn));
4158 f->
proto = IPPROTO_TCP;
4163 for (uint32_t u = 0; u < httplen1; u++) {
4165 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4166 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4167 else flags = STREAM_TOSERVER;
4176 uint8_t ref1[] =
"/abc%2fdef";
4177 size_t reflen =
sizeof(ref1) - 1;
4179 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4189 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4190 reflen =
sizeof(ref2) - 1;
4192 tx = HTPStateGetTx(htp_state, 1);
4202 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4203 reflen =
sizeof(ref3) - 1;
4204 tx = HTPStateGetTx(htp_state, 2);
4225 static int HTPParserDecodingTest01a(
void)
4227 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4228 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4229 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4230 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4241 personality: Apache_2\n\
4249 const char *addr =
"4.3.2.1";
4250 memset(&ssn, 0,
sizeof(ssn));
4255 f->
proto = IPPROTO_TCP;
4261 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4267 uint8_t ref1[] =
"/abc%2fdef";
4268 size_t reflen =
sizeof(ref1) - 1;
4270 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4280 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4281 reflen =
sizeof(ref2) - 1;
4283 tx = HTPStateGetTx(htp_state, 1);
4293 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4294 reflen =
sizeof(ref3) - 1;
4295 tx = HTPStateGetTx(htp_state, 2);
4322 static int HTPParserDecodingTest02(
void)
4325 uint8_t httpbuf1[] =
4326 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4327 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4328 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4329 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4341 double-decode-path: no\n\
4342 double-decode-query: no\n\
4350 const char *addr =
"4.3.2.1";
4351 memset(&ssn, 0,
sizeof(ssn));
4356 f->
proto = IPPROTO_TCP;
4362 for (u = 0; u < httplen1; u++) {
4365 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4366 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4367 else flags = STREAM_TOSERVER;
4376 uint8_t ref1[] =
"/abc/def";
4377 size_t reflen =
sizeof(ref1) - 1;
4379 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4388 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4389 reflen =
sizeof(ref2) - 1;
4391 tx = HTPStateGetTx(htp_state, 1);
4401 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4402 reflen =
sizeof(ref3) - 1;
4403 tx = HTPStateGetTx(htp_state, 2);
4429 static int HTPParserDecodingTest03(
void)
4432 uint8_t httpbuf1[] =
4433 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4434 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4435 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4447 double-decode-path: yes\n\
4448 double-decode-query: yes\n\
4456 const char *addr =
"4.3.2.1";
4457 memset(&ssn, 0,
sizeof(ssn));
4462 f->
proto = IPPROTO_TCP;
4468 for (u = 0; u < httplen1; u++) {
4471 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4472 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4473 else flags = STREAM_TOSERVER;
4482 uint8_t ref1[] =
"/abc/def";
4483 size_t reflen =
sizeof(ref1) - 1;
4485 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4495 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4496 reflen =
sizeof(ref2) - 1;
4498 tx = HTPStateGetTx(htp_state, 1);
4521 static int HTPParserDecodingTest04(
void)
4524 uint8_t httpbuf1[] =
4525 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4526 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4538 double-decode-path: yes\n\
4539 double-decode-query: yes\n\
4547 const char *addr =
"4.3.2.1";
4548 memset(&ssn, 0,
sizeof(ssn));
4553 f->
proto = IPPROTO_TCP;
4559 for (u = 0; u < httplen1; u++) {
4562 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4563 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4564 else flags = STREAM_TOSERVER;
4573 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
4574 size_t reflen =
sizeof(ref1) - 1;
4576 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4599 static int HTPParserDecodingTest05(
void)
4602 uint8_t httpbuf1[] =
4603 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4604 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4616 double-decode-path: yes\n\
4617 double-decode-query: yes\n\
4625 const char *addr =
"4.3.2.1";
4626 memset(&ssn, 0,
sizeof(ssn));
4631 f->
proto = IPPROTO_TCP;
4637 for (u = 0; u < httplen1; u++) {
4640 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4641 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4642 else flags = STREAM_TOSERVER;
4651 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
4652 size_t reflen =
sizeof(ref1) - 1;
4654 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4677 static int HTPParserDecodingTest06(
void)
4680 uint8_t httpbuf1[] =
4681 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4682 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4694 double-decode-path: yes\n\
4695 double-decode-query: yes\n\
4703 const char *addr =
"4.3.2.1";
4704 memset(&ssn, 0,
sizeof(ssn));
4709 f->
proto = IPPROTO_TCP;
4715 for (u = 0; u < httplen1; u++) {
4718 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4719 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4720 else flags = STREAM_TOSERVER;
4729 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
4730 size_t reflen =
sizeof(ref1) - 1;
4732 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4755 static int HTPParserDecodingTest07(
void)
4758 uint8_t httpbuf1[] =
4759 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4760 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4772 double-decode-path: yes\n\
4773 double-decode-query: yes\n\
4774 query-plusspace-decode: yes\n\
4782 const char *addr =
"4.3.2.1";
4783 memset(&ssn, 0,
sizeof(ssn));
4788 f->
proto = IPPROTO_TCP;
4794 for (u = 0; u < httplen1; u++) {
4797 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4798 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4799 else flags = STREAM_TOSERVER;
4808 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
4809 size_t reflen =
sizeof(ref1) - 1;
4811 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4834 static int HTPParserDecodingTest08(
void)
4837 uint8_t httpbuf1[] =
4838 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4839 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4858 const char *addr =
"4.3.2.1";
4859 memset(&ssn, 0,
sizeof(ssn));
4864 f->
proto = IPPROTO_TCP;
4870 for (u = 0; u < httplen1; u++) {
4873 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4874 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4875 else flags = STREAM_TOSERVER;
4884 uint8_t ref1[] =
"/blah/";
4885 size_t reflen =
sizeof(ref1) - 1;
4887 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4910 static int HTPParserDecodingTest09(
void)
4913 uint8_t httpbuf1[] =
4914 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4915 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4927 uri-include-all: true\n\
4935 const char *addr =
"4.3.2.1";
4936 memset(&ssn, 0,
sizeof(ssn));
4941 f->
proto = IPPROTO_TCP;
4947 for (u = 0; u < httplen1; u++) {
4950 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4951 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4952 else flags = STREAM_TOSERVER;
4961 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
4962 size_t reflen =
sizeof(ref1) - 1;
4964 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4986 static int HTPBodyReassemblyTest01(
void)
4989 memset(&htud, 0x00,
sizeof(htud));
4991 memset(&hstate, 0x00,
sizeof(hstate));
4993 memset(&flow, 0x00,
sizeof(flow));
4996 memset(&tx, 0,
sizeof(tx));
5001 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
5002 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";
5009 const uint8_t *chunks_buffer = NULL;
5010 uint32_t chunks_buffer_len = 0;
5012 HtpRequestBodyReassemble(&htud, &chunks_buffer, &chunks_buffer_len);
5015 printf(
"REASSCHUNK START: \n");
5017 printf(
"REASSCHUNK END: \n");
5020 htud.
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
5021 strlen(
"multipart/form-data; boundary=toto"));
5024 HtpRequestBodyHandleMultipart(&hstate, &htud, &tx, chunks_buffer, chunks_buffer_len,
false);
5034 static int HTPSegvTest01(
void)
5037 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";
5038 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5046 double-decode-path: no\n\
5047 double-decode-query: no\n\
5048 request-body-limit: 0\n\
5049 response-body-limit: 0\n\
5062 memset(&ssn, 0,
sizeof(ssn));
5064 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5067 f->
proto = IPPROTO_TCP;
5072 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
5076 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
5097 static int HTPParserTest14(
void)
5108 double-decode-path: no\n\
5109 double-decode-query: no\n\
5110 request-body-limit: 0\n\
5111 response-body-limit: 0\n\
5116 memset(&ssn, 0,
sizeof(ssn));
5126 memset(httpbuf, 0x00,
len);
5129 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5130 "Host: myhost.lan\r\n"
5131 "Connection: keep-alive\r\n"
5133 "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"
5134 "Referer: http://blah.lan/\r\n"
5135 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5137 size_t o = strlen(httpbuf);
5138 for ( ; o <
len - 4; o++) {
5141 httpbuf[
len - 4] =
'\r';
5142 httpbuf[
len - 3] =
'\n';
5143 httpbuf[
len - 2] =
'\r';
5144 httpbuf[
len - 1] =
'\n';
5150 f->
proto = IPPROTO_TCP;
5155 for (u = 0; u <
len; u++) {
5158 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5159 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5160 else flags = STREAM_TOSERVER;
5168 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5193 static int HTPParserTest15(
void)
5196 char *httpbuf = NULL;
5207 double-decode-path: no\n\
5208 double-decode-query: no\n\
5209 request-body-limit: 0\n\
5210 response-body-limit: 0\n\
5211 meta-field-limit: 20000\n\
5215 memset(&ssn, 0,
sizeof(ssn));
5226 memset(httpbuf, 0x00,
len);
5229 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5230 "Host: myhost.lan\r\n"
5231 "Connection: keep-alive\r\n"
5233 "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"
5234 "Referer: http://blah.lan/\r\n"
5235 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5237 size_t o = strlen(httpbuf);
5238 for ( ; o <
len - 4; o++) {
5241 httpbuf[
len - 4] =
'\r';
5242 httpbuf[
len - 3] =
'\n';
5243 httpbuf[
len - 2] =
'\r';
5244 httpbuf[
len - 1] =
'\n';
5246 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5249 f->
proto = IPPROTO_TCP;
5255 for (u = 0; u <
len; u++) {
5258 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5259 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5260 else flags = STREAM_TOSERVER;
5269 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5291 static int HTPParserTest16(
void)
5298 memset(&ssn, 0,
sizeof(ssn));
5300 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5301 "Host: myhost.lan\r\n"
5302 "Connection: keep-alive\r\n"
5304 "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"
5305 "Referer: http://blah.lan/\r\n"
5306 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5307 "Cookie: blah\r\n\r\n";
5308 size_t len =
sizeof(httpbuf) - 1;
5310 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5313 f->
proto = IPPROTO_TCP;
5318 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5326 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5331 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5351 static int HTPParserTest20(
void)
5354 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5355 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5356 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5357 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5358 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
5359 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5360 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5361 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5367 memset(&ssn, 0,
sizeof(ssn));
5369 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5372 f->
proto = IPPROTO_TCP;
5391 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5410 static int HTPParserTest21(
void)
5413 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5414 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5415 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5416 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5417 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
5418 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5419 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5420 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5426 memset(&ssn, 0,
sizeof(ssn));
5428 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5431 f->
proto = IPPROTO_TCP;
5450 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5469 static int HTPParserTest22(
void)
5472 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5473 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5474 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5475 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5476 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
5477 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5478 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5484 memset(&ssn, 0,
sizeof(ssn));
5486 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5489 f->
proto = IPPROTO_TCP;
5504 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5523 static int HTPParserTest23(
void)
5526 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5527 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5528 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5529 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5530 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
5531 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5532 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5538 memset(&ssn, 0,
sizeof(ssn));
5540 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5543 f->
proto = IPPROTO_TCP;
5558 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5577 static int HTPParserTest24(
void)
5580 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5581 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5582 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5583 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5584 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
5585 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5586 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5592 memset(&ssn, 0,
sizeof(ssn));
5594 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5597 f->
proto = IPPROTO_TCP;
5612 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5630 static int HTPParserTest25(
void)
5637 memset(&ssn, 0,
sizeof(ssn));
5642 f->
proto = IPPROTO_TCP;
5645 const char *
str =
"GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
5647 (uint8_t *)
str, strlen(
str));
5671 str =
"HTTP 1.1 200 OK\r\nServer: Suricata/1.0\r\nContent-Length: 8\r\n\r\nSuricata";
5673 (uint8_t *)
str, strlen(
str));
5707 (uint8_t *)
str, strlen(
str));
5718 (uint8_t *)
str, strlen(
str));
5738 static int HTPParserTest26(
void)
5747 request-body-limit: 1\n\
5748 response-body-limit: 1\n\
5762 uint8_t httpbuf1[] =
"GET /alice.txt HTTP/1.1\r\n\r\n";
5763 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5764 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\n"
5765 "Content-Type: text/plain\r\n"
5766 "Content-Length: 228\r\n\r\n"
5767 "Alice was beginning to get very tired of sitting by her sister on the bank."
5768 "Alice was beginning to get very tired of sitting by her sister on the bank.";
5769 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5770 uint8_t httpbuf3[] =
"Alice was beginning to get very tired of sitting by her sister on the bank.\r\n\r\n";
5771 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5777 memset(&th_v, 0,
sizeof(th_v));
5778 memset(&f, 0,
sizeof(f));
5779 memset(&ssn, 0,
sizeof(ssn));
5786 f.
proto = IPPROTO_TCP;
5807 "(filestore; sid:1; rev:1;)");
5852 AppLayerGetFileState files = HTPGetTxFiles(tx_ptr, STREAM_TOCLIENT);
5874 static int HTPParserTest27(
void)
5877 memset(&cfg, 0,
sizeof(cfg));
5881 uint32_t
len = 1000;
5906 static void HTPParserRegisterTests(
void)
5928 UtRegisterTest(
"HTPParserDecodingTest01", HTPParserDecodingTest01);
5929 UtRegisterTest(
"HTPParserDecodingTest01a", HTPParserDecodingTest01a);
5930 UtRegisterTest(
"HTPParserDecodingTest02", HTPParserDecodingTest02);
5931 UtRegisterTest(
"HTPParserDecodingTest03", HTPParserDecodingTest03);
5932 UtRegisterTest(
"HTPParserDecodingTest04", HTPParserDecodingTest04);
5933 UtRegisterTest(
"HTPParserDecodingTest05", HTPParserDecodingTest05);
5934 UtRegisterTest(
"HTPParserDecodingTest06", HTPParserDecodingTest06);
5935 UtRegisterTest(
"HTPParserDecodingTest07", HTPParserDecodingTest07);
5936 UtRegisterTest(
"HTPParserDecodingTest08", HTPParserDecodingTest08);
5937 UtRegisterTest(
"HTPParserDecodingTest09", HTPParserDecodingTest09);
5939 UtRegisterTest(
"HTPBodyReassemblyTest01", HTPBodyReassemblyTest01);